开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜