I am using a custom JComboBox as a cell editor in a JTable. When the users gets to the cell using keyboard controls it tries to open the popup. This causes the following e
Popups like the pulldown in a JComboBox tend to have edge cases for event handling order because they are not geometrically nested inside their ancestors in the component hierarchy. In your case, you are causing the box's focus handler to show the pulldown. To do this it needs the box to be already located on the screen, but it's not.
The solution is almost certainly to defer showing the pulldown until all the events that will make the box visible have been processed. I had a similar (though not exactly the same) problem and was able to resolve it in this manner. Happily there is a Swing utility function that does the trick. Try wrapping the body of the focus gained handler in invokeLater
and a Runnable
:
void focusGained() {
SwingUtilities.invokeLater(new Runnable() {
... focus gained body including show of pulldown menu here ...
});
}
The invokeLater
puts a new message containing the Runnable
at the end of the queue, i.e. after all the existing ones. That Runnable
is executed only when the message makes it to the head, after all those other messages have been processed. This is exactly what you want.
I second (third? fourth?) everyone asking for a pared-down example of a table using your custom combobox any maybe a bit of the code from the combobox itself, but just to take a stab at it anyway...have you tried making a customized version of EditorDelegate to go with your other custom code and moving the code for showing the popup from focusGained()
into your delegate's startCellEditing()
method?
First, let me explain what comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
does. Normally, hoovering the mouse over an item or pressing the arrow keys on the keyboard will cause the selection of items on the JComboBox
immediately. Since selection events from the JComboBox
will cause the cell edit process to stop, this behavior is not suitable for table cells. So when setting this special client property items will be shown selected inside the popup list but not set on the JComboBox
yet. Only committed items (via click or Enter key) will change the selected item on the JComboBox
causing the end of the edit then. At least, this holds for BasicLookAndFeel
and its derivatives.
The problem you have is completely different. As the exception message and the stack trace clearly say, the look and feel tries to open the JPopupMenu
associated with the JComboBox
(as you requested) but it can’t determine the on-screen location for the popup menu because your JComboBox
is not shot showing on the screen. The reason why it wants the location of the JComboBox
is that it opens the new window relative to the JComboBox
.
The remaining question is why you received a focusGained
from a JComboBox
that is not showing on the screen (or why you thought you did).
If you embed your instruction inside a try .. catch instruction , your program will run without problems:
SwingUtilities.invokeLater(new Runnable(){
public void run()
{
try {
tInput.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
tInput.showPopup();
}
catch (IllegalComponentStateException e) {
return;
}
}
});