つまり、JComboBox (またはその他の JComboBox ベースのセル エディター) エディターが関連付けられているセルにユーザーが入力するたびに、JTable がコンボ ボックスをドロップダウンするようにします。
1488 次
2 に答える
1
基本的に、コンボに適切なリスナーをインストールし、ポップアップを明示的に開く必要があります。「適切」の最初の候補は、AncestorListener です。これは、ancestorAdded メソッドでポップアップを表示することを呼び出します。
残念ながら、それがすべてではないようです。テーブルの surrenderFocus プロパティが false の場合に機能します。true の場合、編集不可のコンボに対してのみ機能します。掘り下げた後、動作しない部分の理由は、ポップアップが祖先リスナーによって開かれた後の内部フォーカス転送 (コンボからテキストフィールドへ) であることが判明しました。その場合、エディターの editComponent が永続的にフォーカスを取得すると、ポップアップを開く 2 番目のリスナーが必要です。
複数のリスナーが日常的にお互いの足を踏み入れるので、両方を永続的にインストールするのではなく、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();
}
}
于 2011-10-24T10:24:45.570 に答える