5

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 mouseClicked(MouseEvent e) {
  Point p = e.getPoint();
  rowClicked = table.rowAtPoint(p);
}
Hamed
  • 1,382
  • 11
  • 20
BJ Dela Cruz
  • 5,194
  • 13
  • 51
  • 84
  • 3
    Why not do everything in the ItemListener? Then the order will be determined by the order of methods called inside of itemStateChanged. – Hovercraft Full Of Eels Sep 30 '11 at 16:56
  • This is probably dependent on which listener is thrown when, on what thread, and what else is happening at the time....short answer, probably not. – BenCole Sep 30 '11 at 17:01
  • @Hovercraft Full Of Eels: Maybe because you can't find out the row number there. Or maybe you can get it using`ItemEvent.getItem()`, no idea what `Object` it returns. – maaartinus Sep 30 '11 at 17:16
  • 2
    Maybe you should explain your requirement and not your solution. I'm sure there are better approaches. I'm not even sure how an ItemEvent gets generated when you click on a row. Post your SSCCE. – camickr Sep 30 '11 at 17:55
  • 1
    dont make your editor do _anything_ outside itself. It's designed to focus on, well, editing the one value it is given and report back when it is ready. Nothing else. – kleopatra Oct 01 '11 at 08:22
  • I changed my entire approach and used an `ActionListener` instead to do what I needed to do. Thanks for your comments, guys! – BJ Dela Cruz Oct 07 '11 at 17:19

4 Answers4

8

Here is a nice article explaining the absence of listener notification order in swing: Swing in a better world

K.C.
  • 2,084
  • 2
  • 25
  • 38
Fredrik LS
  • 1,480
  • 9
  • 15
5

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

}
2

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.

Ashwinee K Jha
  • 9,187
  • 2
  • 25
  • 19
2

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.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045