Understanding Swing’s Model (轉)
Understanding ’s Model
:namespace prefix = o ns = "urn:schemas--com::office" />
經常用Swing 開發 GUI 的人一定聽過這樣的說法,Swing 是按MVC結構設計的。更準確地說,Swing是Model-driven的結構。但不同Swing控制元件的Model,其作用是否相同呢?比如當你在使用JButton時,你很少需要關心ButtonModel的存在,但在JTable使用時,你卻總是需要用到 TableModel。更進一步,當你頻繁的使用JTable時,你會發現你可能不僅用到了TableModel,還用到TableColumnModel, ListionModel。這使我們意識到,Model存在不同的種類,不同型別的Model實現不同的功能。
GUI-State Model
首先,我們討論第一種Model, GUI–State Model。GUI-State Model的作用在於標識控制元件的視覺狀態 (visual status)。例如按鈕是否被點選,列表中的Item是否被選中。Swing的控制元件會對GUI-State Model的操作,通常我們不要直接操作GUI–State Model。
ButtonModel
最常見的GUI-State Model是ButtonModel,屬於這個範疇的控制元件有JButton ,JToggleButton ,JCheckBox, JRadioButton, JMenu, JMenuItem, JCheckBoxMenuItem, JRadioButtonMenuItem。(所有AbstractButton的子類)
ButtonModel需要標識的狀態有:
- PRESSED: Button是否被點選了
- ENABLED: Button能否被點選(是否顯示呈灰色)
- ROLLOVER: 滑鼠是否從Button上劃過。Button透過判斷這個屬性判斷是否要顯示RolloverIcon,當然前提是Button透過setRolloverIcon,設定了RolloverIcon
- SELECTED: 只對RadioButton or Checkbox 有用
- ARMED: 滑鼠點選Button後,是否在Button該釋放
顯而易見,這些屬性都只和顯示有關。對於GUI-State Model,只有以下兩種情況我們需要關心它的處在 :(1)我們想改變控制元件預設的視覺行為(假定這種情況很少發生) (2)出於某種顯示目的共用Model,操作一個控制元件會改變另外一個控制元件的狀態(下面會討論到這種情況),其他情況下我們可以忽視它。當然還有一種情況我們需要注意,這就是在使用JRadioButton時。因為使用JRadioButton時,一組JRadioButton同時只能有一個被選中(SELECTED),這當然只有透過操作ButtonModel的SELECTED屬性來實現。不過,Swing針對這個問題引入了ButtonGroup類,透過ButtonGroup.add()方法設定同一個 button group,因此我們同樣不需要直接操作ButtonModel。
BoundedRangeModel
另一個常見的GUI-State Model是BoundedRangeModel,屬於這個範疇的控制元件有JProgressBar JScrollBar JSlr。
BoundedRangeModel標識的主要狀態有:min,max,value(int),同樣的,我們很少直接操作BoundedRangeModel。使用JProgressBar 最常見的方式是在構造裡指定min,max或是透過get/set讀寫min,max,value。而控制元件再把這些請求轉發給BoundedRangeModel。
前面提到出於某種顯示目的,我們有可能需要直接操作GUI-State Model。以下是一種可能的情況(scenario):當我們把一幅面積較大的影像放在JScrollPane,同時希望透過移動滑桿(JSlider)來控制顯示影像顯示在JScrollPane的部分。常見的做法是BoundedRangeModel的ChangeEvent事件(addChangeListener(ChangeListener l)),當JSlider改變了Model的值時在ChangeListener對顯示作相應的調整。
TableColumnModel
TableColumnModel是JTable特有的GUI-State Model。TableColumnModel用於管理TableColumn。而TableColumn代表了JTable中的每一列資料的視覺屬性,比如該列對應的data-model index(這決定了要顯示的內容,參見後面敘述),該列的寬度是否可變,列的最大、最小、首選寬度;該列的繪製器TableCellRenderer和編輯器TableCellEditor(JTable是面向列的,它基於每一列進行繪製和編輯)
Selection Model
考慮這樣一個問題,當使用JTable時,如何設定從X行到Y行處於選擇狀態呢?
我們可以透過調要JTable.setRowSelectionInterval(int index0, int index1)來實現。再進一步,如果想實現反轉選擇(Toggle Selection),即單擊齊數次處於選擇狀態,偶數次則處於非選擇狀態,JTable沒有提供直接的方法來實現。因為JTable將選擇的工作交由Selection Model來實現。察看setRowSelectionInterval的實現
public void setRowSelectionInterval(int index0, int index1) {
selectionModel.setSelectionInterval(boundRow(index0), boundRow(index1));
}
要實現Toggle Selection就只有直接對Selection Model進行。
Selection Model也屬於GUI- State Model的範疇,因為它標識也是一種視覺的狀態,選中的Item會加亮(high light)。和其他GUI- State Model一樣,通常我們不需要直接操作Selection Model。
Selection Model標識的狀態有:
- SINGLE_SELECTION
- SINGLE_INTERVAL_SELECTION
- MULTIPLE_INTERVAL_SELECTION
我們分析一下其他需要判斷選擇幾種控制元件
- JList, 和 JTable一樣用的是ListSelectionModel
- JTree, JTree需要的Selection Model最複雜,因此它有專門Selection Model: TreeSelectionModel。
- JComboBox只能是單選,因此不需要有專門Selection Model
- JFileChooser,透過設定 FILES_ONLY ,DIRECTORIES_ONLY FILES_AND_DIRECTORIES (int) 來設定使用者是否可選擇,目錄,或兩者都可以。透過設定multiSelectionEnabled屬性來決定是否單選或多選,透過File陣列 selectedFiles記錄當前的選擇
- JTabbedPane, JTabbedPane的情況有些特殊,雖然JTabbedPane也只能單選,但它能有專門的Selection Model: SingleSelectionModel
對待Selection Model的方式和其他GUI-State Model一樣,相應Jcomponent都提供專門的函式遮蔽我們對它的直接操作。
Application-data model
這類的Model決定了顯示在控制元件中的內容,因此往往需要我們直接的操作。他們分別是:
- JList: ListModel
- JTable: TableModel
- JComboBox: ComboBoxModel
- JTree: TreeModel
- 各類Text控制元件:Document
ListModel
Swing首先定義了介面ListModel
然後定義了抽象類AbstractListModel實現這個介面。在抽象類裡沒有定義實際資料的方式。因此要實現AbstractListModel,使用者還需要定義這兩個函式
- public int getSize();
- public getElementAt(int index);
因為沒有定義實際資料的儲存方式,當然沒有辦法提供這兩個函式的實現。
最後Swing提供預設類DefaultListModel實現抽象類,預設類以Vector作為儲存資料的方式。
構造一個JList的例項有四種方式:
JList()
JList(final Object[] listData)
JList(final Vector listData)
JList(ListModel dataModel)
前三種建構函式里會分別生成相應的ListModel。還可以在構造完後JList還可以用以下的函式來制定ListModel
void setListData(final Object[] listData)
void setListData(final Vector listData)
void setModel(ListModel model)
JList沒有提供編輯其Item的方法,使用者是無法直接編輯其Item的(這點和JComboBox不同,JComboBox提供了直接編輯其Item的方法),要改變Item的內容需要直接操作ListModel(用陣列和Vector生成JList不適合用來顯示可變內容的資料)。
要顯示可變內容的JList,最方便的方法是用DefaultListModel,但由於它用Vcetor作為其內部的儲存資料的方式,決定他們在處理大資料量的顯示時是不適宜的。首先Vector有內部容量的概念,當容量不足以容納更多的資料時,它需要重新分配一塊,複製原記憶體的東西,並把原來的記憶體丟棄,這是非常耗時的動作;其次,Vector是執行緒的容器(thread-safe collection),所有對容器的操作都需要同步(synchronized),對於包含大資料量的collection這也是非常耗時的。
因此對於大資料量的Application-data,使用者如果想用collection,應該在ArrayList和LinkedList(thread-unsafe collection)之間選擇:
- ArrayList也有內部容量的概念,但它提供了隨機存取的功能 (ran access), 使用它時可以預先申請一塊較大的記憶體,以免以後重新分配記憶體。
- LinkedList沒有內部容量的概念,因此不會重新分配記憶體,但它不提供隨機存取的功能。
TableModel
Swing對TableModel的處理和ListModel類似:
首先定義了介面TableModel,
然後定義了抽象類實現這個介面AbstractTableModel。在抽象類裡沒有定義實際資料的儲存方式。
要實現AbstractTableModel,使用者還需要定義這三個函式
- public getColumnCount()
- public Object getValueAt(int rowIndex, int columnIndex)
- public int getRowCount()
public String getColumnName(int column) 往往也需要定義,不然在表頭將顯示為A,B,C,D …
最後Swing提供預設類DefaultTableModel實現抽象類,預設類以Vector作為儲存資料的方式。因此對大資料量的操作(比如用JTable顯示查詢的結果)同樣不適合用DefaultTableModel。當用JTable顯示資料庫查詢的結果,最好是擴充套件
AbstractTableModel,並讓資料庫每次只返回批次的資料。
JTable的建構函式比起JList要複雜一些, 因為它還需要指定TableColumnModel。但對於Application-data model 的處理和JList是一樣的。
ComboBoxModel
JComboBox和JList很相似,都是用來顯示一個列表項,並可以接受使用者的選擇 (JRadioButton也實現這個功能)。但他們也有本質的不同,JComboBox可以接受使用者的輸入,並可以編輯已有的選項。通常在使用JComboBox是把它分成兩類:可編輯的和不可編輯的。預設狀態是不可編輯的,透過JComboBox.setEditable(true)可將JComboBox設定成可編輯。對應這兩種狀態JComboBox定義了兩類data-model介面,ComboBoxModel和MutableComboBoxModel。
ComboBoxModel的定義如下:
public interface ComboBoxModel extends ListModel {
void setSelectedItem(Object anItem);
Object getSelectedItem();
}
它擴充套件ListModel並只是定義了用於獲取和設定當前選項的辦法,這是因為JComboBox沒有Selection Model。
MutableComboBoxModel,顧名思義,當然是定義修改data-model的方法,它的定義如下:
public interface MutableComboBoxModel extends ComboBoxModel {
public void addElement( Object obj );
public void removeElement( Object obj );
public void insertElementAt( Object obj, int index );
public void removeElementAt( int index );
}
Swing提供對MutableComboBoxModel的實現DefaultComboBoxModel,其內部Vector來儲存資料,當我們想提供自己的現實時,最方便的方法是可以擴充套件AbstractListModel, 並選擇是實現ComboBoxModel還是MutableComboBoxModel。
構造一個JComboBox例項有四種方法:
public JComboBox()
public JComboBox(final Object items[])
public JComboBox(Vector items)
public JComboBox(ComboBoxModel aModel)
前三種建構函式里會分別生成相應的DefaultComboBoxModel。(個人覺得這樣構造JComboBox並不好,由於沒有透過建構函式建立不變性 (invariants) ,即該JComboBox是否可編輯的,當需要修改data-model時,JComboBox都需要首先判斷data-model是否可編輯,對於不可編輯的JComboBox呼叫編輯函式會丟出RuntimeException ())
TreeModel
TreeModel時最複雜的一種data-model,參考文獻一有詳細說明
各類Text控制元件
各類Text控制元件是比較獨立的主題,這裡不再詳述。
參考文獻
[1] Understanding the TreeModel :
[2] A Swing Architecture Overview :
[3] JGuru Faq:
[4] « Swing » by Matthew Robinson & Pavel Vorobiev
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-993469/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Swing入門基礎 (轉)
- java swing的drag and drop源程式 (轉)Java
- Understanding Service Types
- swing
- 愚人節特斯拉釋出Model 3:Model S可能要賣不動了
- insightface之mxnet model轉caffemodel
- Eclipse中EventModel轉Model的錯誤Eclipse
- 特斯拉Model S悄然漲價 上調2.27萬
- 特斯拉 Model S 首次中國亮相 新店建在太古裡?
- javafx 和swing_整合JavaFX和SwingJava
- 1、Swing簡介:Swing是什麼?
- Understanding JSON SchemaJSON
- Understanding Delegated JavaScript EventsJavaScript
- Understanding Parallel Execution PlanParallel
- [翻譯] Understanding deletedelete
- Understanding RabbitMQ Exchange & QueueMQ
- Understanding Initialization Parameters (85)
- javax.swing.undo類 使用例項 - 轉載Java
- Java SwingJava
- 《消費者報告》:Model 3和Model S被評選為美國最佳豪華汽車
- getPageIterator's result is null, check your ModelListAction subclassNull
- ModelMaker 新手起步(一) (轉)
- 建立SWING風格的按鈕控制元件 (轉)控制元件
- 製作圓形Swing按鈕(中文版) (轉)
- Understanding Linux CPU statsLinux
- Understanding React `setState` 翻譯React
- Understanding the CREATE DATABASE Statement (69)Database
- Understanding Buffer Overflow Bugs
- swing with transformjsORMJS
- SWing事件呼叫事件
- Swing結構
- Laravel 使用多資料庫和 Model 表名去 sLaravel資料庫
- 【轉載】Kano Model — Ways to use it and NOT use it
- 打造強大的BaseModel(2):讓Model實現自動對映,將字典轉化成Model
- Understanding HBase and BigTable 譯文
- 【譯】Understanding NodeJS Event LoopNodeJSOOP
- SAP S/4HANA New Simplified Data Model (NSDM) 模型介紹模型
- What are HANA's models of cloud computing, and which should I choose?Cloud