Java中的侦听器顺序

时间:2011-09-30 16:53:13

标签: java swing listeners

我编写了自己的表格单元格编辑器,扩展了AbstractCellEditor并实现了TableCellEditorItemListenerMouseListener。有没有办法在mouseClicked方法之前先执行itemStateChanged方法?我正在尝试执行以下操作:

private int rowClicked;
private JTable table;

public void itemStateChanged(ItemEvent e) {
  if (rowClicked == 5) {
    // Do something to row 5.
  }
}

public void mouseClicked(MouseEvent e) {
  Point p = e.getPoint();
  rowClicked = table.rowAtPoint(p);
}

4 个答案:

答案 0 :(得分:9)

这是一篇很好的文章,解释了摇摆中没有听众通知顺序: Swing in a better world

答案 1 :(得分:3)

我遇到了类似的问题,只是编写了这个类。它是一个复合动作侦听器,其中动作侦听器具有优先级。首先调用更高优先级。它不是通用的,仅适用于动作侦听器。

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);
  }

}

答案 2 :(得分:2)

理想情况下,您不应尝试在编辑器中编辑行号。一旦用户在编辑器中完成编辑并移动到另一个单元格,JTable将使用 getCellEditorValue()方法在编辑器中获取当前值,然后调用 setValueAt(Object aValue,int rowIndex, int columnIndex)  在桌子上的模型。因此,最好在 setValueAt()方法中处理特定于行的任何内容。

答案 3 :(得分:2)

无法依赖event firing order,但您可以根据需要转发事件。在这种情况下,请勿尝试确定ItemListener中的行。相反,让CellEditor结束,并使用新值来更新模型,如建议here