Order of listeners in Java
I wrote my own table cell editor that extends an AbstractCellEditor
and implements a TableCellEditor
, an ItemListener
, and a MouseListener
. Is there a way I can have the mouseClicked
method be executed first before the itemStateChanged
method? I'm trying to do the following:
private int rowClicked;
private JTable table;
public void itemStateChanged(ItemEvent e) {
if (rowClicked == 5) {
// Do something to row 5.
}
}
public void mouse开发者_开发百科Clicked(MouseEvent e) {
Point p = e.getPoint();
rowClicked = table.rowAtPoint(p);
}
Here is a nice article explaining the absence of listener notification order in swing: Swing in a better world
I encountered a similar problem and just wrote this class. It is a composite action listener where action listeners have priorities. Higher priorities get called first. It is not generic and only applies to action listeners.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
public class CompositeActionListenerWithPriorities implements ActionListener {
private Map<Integer, ArrayList<ActionListener>> listeners =
new TreeMap<Integer,ArrayList<ActionListener>>();
@Override
public void actionPerformed(ActionEvent e) {
TreeSet<Integer> t = new TreeSet<Integer>();
t.addAll(listeners.keySet());
Iterator<Integer> it = t.descendingIterator();
while(it.hasNext()){
int x = it.next();
ArrayList<ActionListener> l = listeners.get(x);
for(ActionListener a : l){
a.actionPerformed(e);
}
}
}
public boolean deleteActionListener(ActionListener a){
for(Integer x : listeners.keySet()){
for(int i=0;i<listeners.get(x).size();i++){
if(listeners.get(x).get(i) == a){
listeners.get(x).remove(i);
return true;
}
}
}
return false;
}
public void addActionListener(ActionListener a, int priority){
deleteActionListener(a);
if(!listeners.containsKey(priority)){
listeners.put(priority,new ArrayList<ActionListener>());
}
listeners.get(priority).add(a);
}
}
Ideally you should not try to get the row number being edited inside the editor. Once user is done editing in the editor and moves to another cell, JTable will get the current value in the editor using the getCellEditorValue() method and then call setValueAt(Object aValue, int rowIndex, int columnIndex) on the table model. So it may be better to handle anything specific to the row in the setValueAt() method.
You cannot depend on event firing order, but you can forward events as needed. In this case, don't try to determine the row in the ItemListener
. Instead, let the CellEditor
conclude, and use the new value to update the model, as suggested here.
精彩评论