分享
 
 
 

Understanding Swing’s Model

王朝java/jsp·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

Understanding Swing’s Model

经常用Swing 开发Java GUI 程序的人一定听过这样的说法,Swing 控件是按MVC结构设计的。更准确地说,Swing是Model-driven的结构。但不同Swing控件的Model,其作用是否相同呢?比如当你在使用JButton时,你很少需要关心ButtonModel的存在,但在JTable使用时,你却总是需要用到 TableModel。更进一步,当你频繁的使用JTable时,你会发现你可能不仅用到了TableModel,还用到TableColumnModel, ListSelectionModel。这使我们意识到,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 JSlider。

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 Object 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也有内部容量的概念,但它提供了随机存取的功能 (random 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 :

http://java.sun.com/products/jfc/tsc/articles/jtree/

[2] A Swing Architecture Overview :http://java.sun.com/products/jfc/tsc/articles/architecture/index.html

[3] JGuru Faq:

http://www.jguru.com/faq/

[4] « Swing » by Matthew Robinson & Pavel Vorobiev

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有