[英]How are listeners handled in Java Swing?
The question is how swing handles listeners. 问题是秋千如何处理听众。 In this example it is the TableModelListener
which is in focus. 在此示例中,重点是TableModelListener
。
The table model (let us call it TableModelImpl
) I have is extended from AbstractTableModel
. 我拥有的表模型(我们称之为TableModelImpl
)是从AbstractTableModel
扩展的。 Between this table model and the JTable
I have class called TableSorter
, which is like a decorator to TableModelImpl
(and the TableSorter
also extends AbstractTableModel
). 在此表模型和JTable
我有一个名为TableSorter
类,它类似于TableModelImpl
的装饰器(并且TableSorter
还扩展了AbstractTableModel
)。 The TableSorter
is linked to TableModelImpl
via association, so what I mean is that TableSorter
holds a reference to the TableModelImpl
. TableSorter
通过关联链接到TableModelImpl
,所以我的意思是TableSorter
拥有对TableModelImpl
的引用。 Further, the TableSorter
have member of type TableModelListener
, which listen to my TableModelImpl
object. 此外, TableSorter
具有TableModelListener
类型的成员,该成员侦听我的TableModelImpl
对象。 The JTable
does in turn listen to a TableSorter
. JTable
依次侦听TableSorter
。
So in general it can be said that the JTable
object listens to TableSorter
, which listens to my TableModelImpl
. 因此,通常可以说JTable
对象侦听TableSorter
,后者侦听我的TableModelImpl
。 So the question is: How does this work? 所以问题是:这如何工作? Assume for example that I want to call TableModelStructureChanged()
on my TableModelImpl
object, will this Event be forwarded to the JTable
via the TableSorter
then? 例如,假设我要在TableModelImpl
对象上调用TableModelStructureChanged()
,那么此事件是否将通过TableSorter
转发到JTable
?
So, some shortened example: 因此,一些简短的示例:
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
}
}
So if I do following: 因此,如果我执行以下操作:
TableModelImpl tm = new TableModelImpl();
TableSorter sorter = new TableSorter(tm);
JTable table = new JTable(sorter);
tm.setEnabled(true);
Will the JTable be notified? 会通知JTable吗?
Swing is a great implementation of most well-known design patterns in java such as Model-View-Controller
(most of times referred to as MVC ), Singleton
, Factory
, Observer
and etc. Swing是Java中最著名的设计模式的绝佳实现,例如Model-View-Controller
(通常称为MVC ), Singleton
, Factory
, Observer
等。
Many JComponents
such as JTable
, JList
or JComboBox
are implementing MVC pattern. 许多JComponents
例如JTable
, JList
或JComboBox
正在实现MVC模式。
In many situations when the model is changed, a method like fireTableDataChanged()
is getting called, which is responsible for iterating over the list of listeners added to the model and call their tableChanged(TableModelEvent tme)
method. 在许多情况下,当模型发生更改时,将调用诸如fireTableDataChanged()
类的方法,该方法负责遍历添加到模型中的侦听器列表,并调用其tableChanged(TableModelEvent tme)
方法。 So any other component such as the view will be notified to update it's state due to the changes of the model. 因此,由于模型的更改,将通知其他任何组件(例如视图)以更新其状态。
The same is applied when fireTableStructureChanged()
is called. 调用fireTableStructureChanged()
时,将应用相同的内容。 Since JTable
is implementing the TableModelListener
interface and register itself as a listener to it's TableModel
, it will be notified automatically when you call fireTableStructureChanged()
. 由于JTable
实现了TableModelListener
接口并将其自身注册为它的TableModel
的侦听器,因此当您调用fireTableStructureChanged()
时,它将自动得到通知。
It's beneficial to see the source code of the JTable
and AbstractTableModel
to understand the mechanism of firing and listening to the TableModelEvent
s. 查看JTable
和AbstractTableModel
的源代码以了解触发和侦听TableModelEvent
的机制是有益的。
[UPDATE] [更新]
There is not a magic way, just method calls. 没有魔术的方法,只有方法调用。 In the AbstractTableModel
there is a List<TableModelListener>
called listenerList
. 在AbstractTableModel
有一个名为listenerList
的List<TableModelListener>
。 On the other hand, JTable
is implementing TableModelListener
interface. 另一方面, JTable
正在实现TableModelListener
接口。 In the constructor of JTable
class, JTable
adds itself to the list of listeners in the model. 在JTable
类的构造函数中, JTable
将自身添加到模型中的侦听器列表中。 So when anything happens to TableModel
and its fireXXX()
methods are getting called, the only magic is iterating over listenerList
and calling 'tableChanged' method. 因此,当TableModel
发生任何事情并且调用它的fireXXX()
方法时,唯一的魔术就是遍历listenerList
并调用'tableChanged'方法。 Since JTable
is in the list, then 'tableChanged' of JTable
is called. 由于JTable
在列表中,因此将调用JTable
“ tableChanged”。
Hope this would be helpful. 希望这会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.