views:

1689

answers:

1

I'm having issues with the following code, where I use a JComboBox to change a String value in a table cell. The JComboBox works fine, but if I click in the box and then click away without selecting anything the JComboBox's dropdown remains visible, even if I delete the row. Clicking on another Swing component like a JButton often causes it to go away, but not always.


    TableColumn col = myTable.getColumnModel().getColumn(0);
    JComboBox eq = new JComboBox();
    eq.addItem("==");
    eq.addItem("!=");
    DefaultCellEditor editor = new DefaultCellEditor(eq);
    col.setCellEditor(editor);

Edit: I had neglected to mention that earlier I set:


    myTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

If I comment this line out or set it false, then clicking on other Swing components does NOT cause the box to vanish. With it in, clicking on anything that takes focus causes the box to go away, making the problem less annoying but possibly masking the cause of the behavior.

Am I doing something wrong here, or forgetting a step? Alternately, is there a way to force it to close itself?

Thanks!

+4  A: 

To understand this you'll need to understand what goes on with an editable table. A short bit of theory:

Every cell has a potential renderer and editor. The renderer just tells the cell how to draw and does not interact with events. The editor however is a component that can interact with events. When an event happens that triggers an edit, the editor component is added on top of the table. When the edit finishes, the component is removed.

In order to get the component to go away, you'll have to make sure the cell is not still in the "editing" state. This is why terminateEditOnFocusLast causes the JComboBox to vanish. If you want other things to get the box to go, you'll need to probably call removeEditor() in response to certain events, possibly focus, or cell selection.

To really get a handle on what happens I'd recommend having a quick look at the source code to removeEditor(), editCellAt() etc., and maybe step through once in a debugger. It's possible you've overridden some of the event handling code, or are calling it when you shouldn't. The editor/event handling code in JTable is fairly fragile, and it's quite easy by accident to get calls to happen in the wrong order with funny side effects.

Also, Java very subtly changed the event and focus behaviour of JTable between versions once, I think it was between 1.4 and 1.5, when the focus handling for swing changed. So the first thing I'd recommend trying is your code with a different Java version. The bug may have been caused by Sun (some of our complicated editor code had to be changed) and if it differs between releases it is easier to report to Sun.

Nick Fortescue
Thanks for the background and the thorough answer. I've taken a look at those methods but haven't turned up anything yet. I think you've basically got the right answer, though -- I just need to figure out where it's happening. Thanks!
JMurphy
Nice thorough answer!
shuby_rocks