По сути, вы должны установить соответствующий слушатель на комбо и явно открыть всплывающее окно.Первым кандидатом на "подходящее" является AncestorListener, который вызывает отображение всплывающего окна в своем методе ancestorAdded.
К сожалению, это не вся история: работает, если свойство surrenderFocus таблицы имеет значение false.Если это правда, работает только для нередактируемых комбо.После некоторого копания причиной неработающей части оказывается внутренний перенос (из комбинированного списка в текстовое поле) после того, как всплывающее окно открывается ancestorListener.В этом случае нам нужен второй слушатель, который открывает всплывающее окно, как только редактор editComponent постоянно получает фокус.
Несколько слушателей обычно наступают друг другу на ноги, поэтому лучше не устанавливать их постоянно, а делать это при каждом вызове getEditorComp, и позволить им удалить себя, как только они отобразят всплывающее окно.Ниже приведен рабочий пример того, как это сделать, просто остерегайтесь: он не был официально протестирован!
public static class DefaultCellEditorX extends DefaultCellEditor {
private AncestorListener ancestorListener;
private PropertyChangeListener focusPropertyListener;
public DefaultCellEditorX(JComboBox comboBox) {
super(comboBox);
}
/**
* Overridden to install an appriate listener which opens the
* popup when actually starting an edit.
*
* @inherited <p>
*/
@Override
public Component getTableCellEditorComponent(JTable table,
Object value, boolean isSelected, int row, int column) {
super.getTableCellEditorComponent(table, value, isSelected, row, column);
installListener(table);
return getComponent();
}
/**
* Shows popup.
*/
protected void showPopup() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
getComponent().setPopupVisible(true);
}
});
}
/**
* Dynamically install self-uninstalling listener, depending on JComboBox
* and JTable state.
* @param table
*/
private void installListener(JTable table) {
if (getComponent().isEditable() && table.getSurrendersFocusOnKeystroke()) {
installKeyboardFocusListener();
} else {
installAncestorListener();
}
}
private void installAncestorListener() {
if (ancestorListener == null) {
ancestorListener = new AncestorListener() {
@Override
public void ancestorAdded(AncestorEvent event) {
getComponent().removeAncestorListener(ancestorListener);
showPopup();
}
@Override
public void ancestorRemoved(AncestorEvent event) {
}
@Override
public void ancestorMoved(AncestorEvent event) {
}
};
}
getComponent().addAncestorListener(ancestorListener);
}
private void installKeyboardFocusListener() {
if (focusPropertyListener == null) {
focusPropertyListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
LOG.info("property: " + evt.getPropertyName());
if (focusManager().getPermanentFocusOwner() !=
getComponent().getEditor().getEditorComponent()) return;
focusManager()
.removePropertyChangeListener("permanentFocusOwner", focusPropertyListener);
showPopup();
}
};
}
focusManager().addPropertyChangeListener("permanentFocusOwner", focusPropertyListener);
}
/**
* Convience for less typing.
* @return
*/
protected KeyboardFocusManager focusManager() {
return KeyboardFocusManager.getCurrentKeyboardFocusManager();
}
/**
* Convenience for type cast.
* @inherited <p>
*/
@Override
public JComboBox getComponent() {
return (JComboBox) super.getComponent();
}
}