问题是swing如何处理听众。在这个例子中,焦点是TableModelListener
。
表格模型(我们称之为TableModelImpl
)我从AbstractTableModel
扩展而来。在此表格模型和JTable
之间,我有一个名为TableSorter
的类,它类似于TableModelImpl
的装饰器(而TableSorter
也扩展了AbstractTableModel
)。 TableSorter
通过关联链接到TableModelImpl
,所以我的意思是TableSorter
包含对TableModelImpl
的引用。此外,TableSorter
具有类型为TableModelListener
的成员,它会侦听我的TableModelImpl
对象。 JTable
会依次收听TableSorter
。
一般来说,可以说JTable
对象会侦听TableSorter
,它会监听我的TableModelImpl
。所以问题是:这是如何工作的?例如,假设我想在TableModelStructureChanged()
对象上调用TableModelImpl
,此事件是否会通过JTable
转发到TableSorter
?
所以,一些缩短的例子:
public class TableModelImpl extends AbstractTableModel {
private boolean enabled;
public TableModelImpl(//non relevant parameter, linked to data) {
//Irrelevant code binds model to the data
this.enabled = false;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
fireTableStructureChanged();
}
// More irrelevant code
}
public class TableSorter extends AbstractTableModel {
private TableModel tableModel;
private MouseListener mouseListener;
private TableModelListener tableModelListener;
public TableSorter() {
this.mouseListener = new MouseHandler();
this.tableModelListener = new TableModelHandler();
}
public TableSorter(TableModel tableModel) {
this();
setTableModel(tableModel); //Adds this.tableModelListener to tableModels listenerList
}
}
所以,如果我这样做:
TableModelImpl tm = new TableModelImpl();
TableSorter sorter = new TableSorter(tm);
JTable table = new JTable(sorter);
tm.setEnabled(true);
是否会通知JTable?
答案 0 :(得分:2)
Swing是java中大多数知名设计模式的一个很好的实现,例如Model-View-Controller
(大多数时候被称为 MVC ),Singleton
,{{1 },Factory
等等。
许多Observer
,例如JComponents
,JTable
或JList
正在实施 MVC 模式。
在更改模型的许多情况下,会调用类似JComboBox
的方法,该方法负责迭代添加到模型的侦听器列表并调用其fireTableDataChanged()
方法。因此,由于模型的更改,将通知任何其他组件(例如视图)更新其状态。
调用tableChanged(TableModelEvent tme)
时也适用。由于fireTableStructureChanged()
正在实施JTable
界面,并将自己注册为TableModelListener
的监听者,因此当您致电TableModel
时会自动通知。
有必要查看fireTableStructureChanged()
和JTable
的源代码,以了解触发和聆听AbstractTableModel
的机制。
<强> [UPDATE] 强>
没有神奇的方法,只是方法调用。在TableModelEvent
中有AbstractTableModel
名为List<TableModelListener>
。另一方面,listenerList
正在实现JTable
接口。在TableModelListener
类的构造函数中,JTable
将自身添加到模型中的侦听器列表中。因此,当JTable
发生任何事情并且其TableModel
方法被调用时,唯一的魔法是迭代fireXXX()
并调用'tableChanged'方法。由于listenerList
位于列表中,因此调用了JTable
的“tableChanged”。
希望这会有所帮助。