`

Understanding Swing’s Model

阅读更多

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需要标识的状态有:

  1. PRESSED: Button是否被点击了
  2. ENABLED: Button能否被点击(是否显示呈灰色)
  3. ROLLOVER: 鼠标是否从 Button上划过。 Button通过判断这个属性判断是否要显示 RolloverIcon,当然前提是 Button通过 setRolloverIcon,设置了 RolloverIcon
  4. SELECTED: 只对 RadioButton or Checkbox 有用
  5. 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标识的状态有:

  1. SINGLE_SELECTION
  2. SINGLE_INTERVAL_SELECTION
  3. MULTIPLE_INTERVAL_SELECTION

 

我们分析一下其他需要判断用户选择几种控件

  1. JList, 和 JTable一样用的是 ListSelectionModel
  2. JTree, JTree需要的 Selection Model最复杂,因此它有专门 Selection Model: TreeSelectionModel
  3. JComboBox只能是单选,因此不需要有专门 Selection Model
  4. JFileChooser,通过设置 FILES_ONLY DIRECTORIES_ONLY FILES_AND_DIRECTORIES (int) 来设定用户是否可选择文件,目录,或两者都可以。通过设定 multiSelectionEnabled属性来决定是否单选或多选,通过 File数组 selectedFiles记录当前的选择
  5. JTabbedPane, JTabbedPane的情况有些特殊,虽然 JTabbedPane也只能单选,但它能有专门的 Selection Model: SingleSelectionModel

对待 Selection Model的方式和其他 GUI-State Model一样,相应 Jcomponent都提供专门的函数屏蔽我们对它的直接操作。

 

Application-data model

 

这类的 Model决定了显示在控件中的内容,因此往往需要我们直接的操作。他们分别是:

  1. JList: ListModel
  2. JTable: TableModel
  3. JComboBox: ComboBoxModel
  4. JTree: TreeModel
  5. 各类 Text控件 :Document

 

ListModel

 

Swing首先定义了接口 ListModel

然后定义了抽象类 AbstractListModel实现这个接口。在抽象类里没有定义实际数据的存储方式。因此要实现 AbstractListModel,用户还需要定义这两个函数

  1. public int getSize();
  2. 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)之间选择:

  1. ArrayList也有内部容量的概念,但它提供了随机存取的功能 (random access), 使用它时可以预先申请一块较大的内存,以免以后重新分配内存。
  2. LinkedList没有内部容量的概念,因此不会重新分配内存,但它不提供随机存取的功能。

 

TableModel

 

Swing TableModel的处理和 ListModel类似:

首先定义了接口 TableModel

然后定义了抽象类实现这个接口 AbstractTableModel。在抽象类里没有定义实际数据的存储方式。

要实现 AbstractTableModel,用户还需要定义这三个函数

  1. public getColumnCount()
  2. public Object getValueAt(int rowIndex, int columnIndex)
  3. 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

分享到:
评论

相关推荐

    Understanding Ruby's Object Model

    **Ruby对象模型详解** Ruby是一种面向对象的编程语言,其对象模型是其核心特性之一,它使得Ruby在处理...阅读`Understanding_Ruby_s_Object_Model.ppt`,你将获得更详细的解释和示例,进一步提升你的Ruby编程技能。

    understanding-security-osi-model_377

    understanding-security-osi-model_377

    Matlab 科技专讲:Understanding Model Predictive Control

    Matlab 科技专讲之《Understanding Model Predictive Control》,该视频专讲包括7个视频,以及对应的英文字幕。(1)Why use MPC;(2)What is MPC;(3)MPC Design Parameters;(4)Adaptive, Gain-Scheduled ...

    Understanding JavaServer Pages Model 2 architecture.doc

    Model 2架构也可以视为流行的Model-View-Controller(MVC)设计模式的服务器端实现。在继续阅读之前,需要读者对JSP和Servlet编程的基本概念有所了解,本文不会涉及语法问题。 首先,有人可能会问,为什么要在JSP中...

    [Manning]Swing_2rd.zip

    it with an intermediate understanding of Swing. For this reason we do not recommend this book to Swing beginners. For beginners we suggest Manning’s own Up to Speed with Swing by Steven Gutz.

    Understanding LSTM Networks -- colah's blog.pdf

    As you read this essay, you understand each word based on your understanding of previous words. You don’t throw everything away and start thinking from scratch again. Your thoughts have persistence....

    Java™ Swing, 2nd Edition

    It goes into detail about the model-delegate architecture behind the components and discusses all of the data models. Understanding the models is essential when you're working on an application that ...

    PMI's Organizational Project Management Maturity Model (OPM3™)

    PMI's Organizational Project Management Maturity Model (OPM3™) provides a foundation of knowledge about organizational project management and organizational project management maturity. It assists ...

    Understanding Understanding

    根据提供的文件信息,可以得知“Understanding Understanding”是由Heinz von Foerster所著的一本书籍,该书以“Essays on Cybernetics and Cognition”为副标题,涉及的领域是认知理论与人工智能。书名中的...

    Understanding and Using C Pointers 原版pdf by Reese

    Numerous books have been written about C. They usually offer a broad ...That higher level of understanding for C can only be achieved with a solid understanding of pointers and the management of memory.

    Inside the C++ object model 高清英文版

    Inside the C++ Object Model focuses on the underlying mechanisms that support object-oriented programming within C++: constructor semantics, temporary generation, support for encapsulation, ...

    Inside the C++ Object Model

    Inside the C++ Object Model focuses on the underlying mechanisms that support object-oriented programming within C++: constructor semantics, temporary generation, support for encapsulation, ...

    Newcoder's brief understanding of C‘s "branch" and "circle"

    Newcoder's brief understanding of C‘s "branch" and "circle

    Understanding zigbee rf4ce

    Understanding zigbee rf4ce

    Ken Bradley’s Understanding PRINCE 2

    Ken Bradley’s Understanding PRINCE 2

    Understanding stacks and registers in the Sparc architecture.pdf

    Peter Magnusson的文章《Understanding stacks and registers in the Sparc architecture.pdf》中可能详细解释了Sparc架构的栈和寄存器的工作原理、它们在程序执行中的角色以及如何通过编译器和汇编器进行管理和优化...

    Model Driven Architecture.pdf

    ### Model Driven Architecture (MDA) - Key Concepts and Overview #### Introduction to Model Driven Architecture (MDA) Model Driven Architecture, or MDA, is an approach to software design that ...

    Understanding User’s Query Intent with Wikipedia

    ### 知识点一:查询意图的理解及其重要性 在搜索引擎技术中,理解用户的查询意图是提高搜索结果质量的关键步骤之一。用户输入的查询词往往包含丰富的语义信息,但这些信息并不总是显而易见的。...

    AngularJs Understanding the Model Component

    在angular文档讨论的上下文中,术语“model”可以适用于单一对象代表一个实体(例如,一个叫” phones”的model,它的值是一个电话数组。)或者作为应用的全部数据Model(所有实体)。  在angular中,model可以是...

Global site tag (gtag.js) - Google Analytics