国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

通過 JAVA SWING 看透 MVC 設計模式

2019-11-18 12:44:09
字體:
來源:轉載
供稿:網友

  一個好的用戶界面(GUI)的設計通常可以在現實世界找到相應的表現。例如,假如在您的面前擺放著一個類似于電腦鍵盤按鍵的一個簡單的按鈕,然而就是這么簡單的一個按鈕,我們就可以看出一個GUI設計的規則,它由兩個主要的部分構成,一部分使得它具有了按鈕應該具有的動作特性,例如可以被按下。另外一部分則負責它的表現,例如這個按鈕是代表了A還是B。
  
  看清楚這兩點你就發現了一個很強大的設計方法,這種方法鼓勵重用reuse,而不是重新設計redesign。你發現按鈕都有相同的機理,你只要在按鈕的頂上噴上不同的字母便能制造出“不同”的按鈕,而不用為了每個按鈕而重新設計一份圖紙。這大大減輕了設計工作的時間和難度。
  
  假如您把上述設計思想應用到軟件開發領域,那么取得相似的效果一點都不讓人驚異。一個在軟件開發領域應用的非常廣泛的技術Model/View/Controller(MVC)便是這種思想的一個實現。
  
  這當然很不錯,但是或許您又開始迷惑這和java基礎類JFC(Java Foundation Class)中的用戶界面設計部分(Swing)又有什么關系呢?好的,我來告訴你。
  
  盡管MVC設計模式通常是用來設計整個用戶界面(GUI)的,JFC的設計者們卻獨創性的把這種設計模式用來設計Swing中的單個的組件(Component),例如表格Jtable,樹Jtree,組合下拉列表框JcomboBox等等等等。這些組件都有一個Model,一個View,一個Controller,而且,這些model,view,controller可以獨立的改變,就是當組件正在被使用的時候也是如此。這種特性使得開發GUI界面的工具包顯得非常的靈活。
  
  MVC設計模式
  就象我剛才指出的一樣,MVC設計模式把一個軟件組件區分為三個不同的部分,model,view,controller。
  
 通過 JAVA SWING 看透 MVC 設計模式(圖一)

  Model是代表組件狀態和低級行為的部分,它治理著自己的狀態并且處理所有對狀態的操作,model自己本身并不知道使用自己的view和controller是誰,系統維護著它和view之間的關系,當model發生了改變系統還負責通知相應的view。
  
  View代表了治理model所含有的數據的一個視覺上的呈現。一個Model可以有一個以上的View,但是Swing中卻很少有這樣的情況。
  
  Controller治理著model和用戶之間的交互的控制。它提供了一些方法去處理當model的狀態發生了變化時的情況。
  
  使用鍵盤上的按鈕的例子來說明一下:Model就是按鈕的整個機械裝置,View/Controller就是按鈕的表面部分。
  
  下面的圖解釋了如何把一個JFC開發的用戶界面分為model,view,controller,注重,view/Controller被合并到了一起,這是MVC設計模式通常的用法,它們提供了組件的用戶界面(UI)。
  
通過 JAVA SWING 看透 MVC 設計模式(圖二)

  用Button的例子具體說明
  
  為了更好的理解MVC設計模式和Swing用戶界面組件之間的關系,讓我們更加深入的進行分析。我將采用最常見的組件button來說明。
  
  我們從model來開始。
  
  Model
  一個按鈕的model所應該具備的行為由一個接口ButtonModel來完成。一個按鈕model實例封裝了其內部的狀態,并且定義了按鈕的行為。它的所有方法可以分為四類:
  
  查詢內部狀態
  
  操作內部狀態
  
  添加和刪除事件監聽器
  
  發生事件
  
  其他的用戶界面組件有它們各自的與組件相關的Model,但是所有的組件Model都提供這四類方法。
  
  View & Controller
  上面的圖中講述一個按鈕的view/controller由一個接口ButtonUI完成。假如一個類實現了這個接口,那么它將會負責創建一個用戶界面,處理用戶的操作。它的所有方法可以被分為三大類:
  
  繪制Paint
  
  返回幾何類型的信息
  
  處理AWT事件
  
  其他用戶界面組件有他們自己的組件相關的View/Controller,但是他們都提供上述三類方法。
  
  程序員通常并不會直接和model以及view/controller打交道,他們通常隱藏于那些繼續自java.awt.Component的組件里面了,這些組件就像膠水一樣把MVC三者合三為一。也正是由于這些繼續的組件對象,一個程序員可以很方便的混合使用Swing組件和AWT組件,然后,我們知道,Swing組件有很多都是直接繼續自相應的AWT組件,它能提供比AWT組件更加方便易用的功能,所以通常情況下,我們沒有必要混合使用兩者。
  
  一個實例
  現在我們已經明白了Java類與MVC各個部分的對應關系,我們可以更加深入一點去分析問題了。下面我們將要講述一個小型的使用MVC模式開發的例子。因為JFC十分的復雜,我只能把我的例子局限于一個用戶界面組件里面(假如你猜是一個按鈕的例子,那么你對了!)
  
  讓我們來看看這個例子的所有部分吧。
  
  Button類
  最顯而易見的開始的地方就是代表了按鈕組件本省的代碼,因為這個類是大部分程序員會接觸的。
  
  就像我前面提到的,按鈕用戶界面組件類實際上就是model和view/controller的之間的黏合劑。每個按鈕組件都和一個model以及一個controller關聯,model定義了按鈕的行為,而view/controller定義了按鈕的表現。而應用程序可以在任何事件改變這些關聯。讓我們看看得以實現此功能的代碼。
  
    public void setModel(ButtonModel buttonmodel)
  {
   if (this.buttonmodel != null)
   {
     this.buttonmodel.removeChangeListener(buttonchangelistener);
     this.buttonmodel.removeActionListener(buttonactionlistener);
  
     buttonchangelistener = null;
     buttonactionlistener = null;
   }
  
   this.buttonmodel = buttonmodel;
  
   if (this.buttonmodel != null)
   {
     buttonchangelistener = new ButtonChangeListener();
     buttonactionlistener = new ButtonActionListener();
  
     this.buttonmodel.addChangeListener(buttonchangelistener);
     this.buttonmodel.addActionListener(buttonactionlistener);
   }
  
   updateButton();
  }
  
  public void setUI(ButtonUI buttonui)
  {
   if (this.buttonui != null)
   {
     this.buttonui.uninstallUI(this);
   }
  
   this.buttonui = buttonui;
  
   if (this.buttonui != null)
   {
     this.buttonui.installUI(this);
   }
  
   updateButton();
  }
  
  public void updateButton()
  {
   invalidate();
  }
  
  在進入下一節之前,你應該多花一些時間來仔細閱讀一下Button類的源代碼。
  
  ButtonModel類
  ButtonModel維護著三種類型的狀態信息:是否被按下(PRessed),是否“武裝上了”(armed),是否被選擇(selected)。它們都是boolean類型的值。
  
  一個按鈕被按下(pressed)是指當鼠標在按鈕上面的時候,按下鼠標但是還沒有松開鼠標按鈕的狀態,及時用戶此時把鼠標拖拽到按鈕的外面也沒有改變這種狀態。
  
  一個按鈕是否“武裝了”(armed)是指按鈕被按下,并且鼠標還在按鈕的上面。
  
  一些按鈕還可能被選擇(selected),這種狀態通過重復的點擊按鈕取得true或者false的值。
  
  下面的代碼是狀態pressed的一個缺省的實現。狀態armed以及selected實現的代碼與之類似。ButtonModel類應該被繼續,這樣可以覆蓋缺省的狀態定義,實現有個性的按鈕。
  
    private boolean boolPressed = false;
  
  public boolean isPressed()
  {
   return boolPressed;
  }
  
  public void setPressed(boolean boolPressed)
  {
   this.boolPressed = boolPressed;
  
   fireChangeEvent(new ChangeEvent(button));
  }   
  
  按鈕的模型button model還負責通知其他對象(事件監聽器)它們所感愛好的事件。從下面的代買中我們可以看出當按鈕的轉臺發生改變的時候就會發出一個ChangeEvent。下面就是代碼:
  
  private Vector vectorChangeListeners = new Vector();
  
  public void addChangeListener(ChangeListener changelistener)
  {
   vectorChangeListeners.addElement(changelistener);
  }
  
  public void removeChangeListener(ChangeListener changelistener)
  {
   vectorChangeListeners.removeElement(changelistener);
  }
  
  protected void fireChangeEvent(ChangeEvent changeevent)
  {
   Enumeration enumeration = vectorChangeListeners.elements();
  
   while (enumeration.hasMoreElements())
   {
     ChangeListener changelistener =
      (ChangeListener)enumeration.nextElement();
  
     changelistener.stateChanged(changeevent);
   }
  }

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 留坝县| 上饶县| 邛崃市| 江都市| 织金县| 芷江| 兰溪市| 凤凰县| 兴安盟| 岚皋县| 望江县| 双牌县| 武安市| 绍兴县| 朝阳市| 平原县| 泸州市| 夏河县| 海南省| 杭州市| 皋兰县| 龙里县| 松桃| 婺源县| 宾阳县| 砚山县| 涟源市| 腾冲县| 元氏县| 蓝田县| 阳西县| 迁安市| 双鸭山市| 获嘉县| 海宁市| 洛阳市| 乡城县| 乐东| 墨竹工卡县| 紫云| 廉江市|