简体   繁体   English

Java Swing如何处理侦听器?

[英]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 ), SingletonFactoryObserver等。

Many JComponents such as JTable , JList or JComboBox are implementing MVC pattern. 许多JComponents例如JTableJListJComboBox正在实现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. 查看JTableAbstractTableModel的源代码以了解触发和侦听TableModelEvent的机制是有益的。

[UPDATE] [更新]

There is not a magic way, just method calls. 没有魔术的方法,只有方法调用。 In the AbstractTableModel there is a List<TableModelListener> called listenerList . AbstractTableModel有一个名为listenerListList<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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM