最初の質問...
http://www.orbital-computer.de/JComboBox/のチュートリアルを読み、それに基づいて、検索可能にするために既存の JComboBox を渡すクラスを作成するように変更しました。
JComboBox で結果を変更することができましたが、壊れたキャレットで何かが起こっているようです。
具体的には、JComboBox をこのクラスに渡して、.indexOf ステートメントに対して true を返すリスト内の既存の項目を自動選択する必要があります。
コード:
public class SearchableJComboBox extends PlainDocument {
JComboBox comboBox;
ComboBoxModel model;
JTextComponent editor;
// flag to indicate if setSelectedItem has been called
// subsequent calls to remove/insertString should be ignored
boolean selecting=false;
boolean hidePopupOnFocusLoss;
boolean hitBackspace=false;
boolean hitBackspaceOnSelection;
public SearchableJComboBox(final JComboBox comboBox) {
this.comboBox = comboBox;
model = comboBox.getModel();
editor = (JTextComponent) comboBox.getEditor().getEditorComponent();
editor.setDocument(this);
comboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
editor.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (comboBox.isDisplayable()) comboBox.setPopupVisible(true);
hitBackspace=false;
}
});
// Bug 5100422 on Java 1.5: Editable JComboBox won't hide popup when tabbing out
hidePopupOnFocusLoss=System.getProperty("java.version").startsWith("1.5");
// Highlight whole text when gaining focus
editor.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
// Workaround for Bug 5100422 - Hide Popup on focus loss
if (hidePopupOnFocusLoss) comboBox.setPopupVisible(false);
}
});
// Handle initially selected object
Object selected = comboBox.getSelectedItem();
if (selected!=null) setText(selected.toString());
}
void setPrototypeValue(Object value, JList list) {
comboBox.setPrototypeDisplayValue(value);
list.setPrototypeCellValue(value);
}
JList getListBox() {
JList listBox;
try {
Field field = JComponent.class.getDeclaredField("ui");
field.setAccessible(true);
BasicComboBoxUI ui = (BasicComboBoxUI) field.get(comboBox);
field = BasicComboBoxUI.class.getDeclaredField("listBox");
field.setAccessible(true);
listBox = (JList) field.get(ui);
} catch (NoSuchFieldException nsfe) {
throw new RuntimeException(nsfe);
} catch (IllegalAccessException iae) {
throw new RuntimeException(iae);
}
return listBox;
}
public void remove(int offs, int len) throws BadLocationException {
// return immediately when selecting an item
if (selecting) return;
if (hitBackspace) {
// user hit backspace => move the selection backwards
// old item keeps being selected
if (offs>0) {
if (hitBackspaceOnSelection) offs--;
} else {
// User hit backspace with the cursor positioned on the start => beep
comboBox.getToolkit().beep(); // when available use: UIManager.getLookAndFeel().provideErrorFeedback(comboBox);
}
} else {
super.remove(offs, len);
}
}
private void setText(String text) {
try {
super.remove(0, getLength());
super.insertString(0, text, null);
} catch (BadLocationException e) {
throw new RuntimeException(e.toString());
}
}
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
// return immediately when selecting an item
if (selecting) return;
// insert the string into the document
super.insertString(offs, str, a);
// lookup and select a matching item
Object item = lookupItem(getText(0, getLength()));
if (item != null)
setSelectedItem(item);
}
private void setSelectedItem(Object item) {
selecting = true;
model.setSelectedItem(item);
selecting = false;
}
private Object findStringWithin(String pattern) {
for(int i=0; i<model.getSize();i++)
{
if(model.getElementAt(i).toString().toLowerCase().indexOf(pattern.toLowerCase())!=-1)
return model.getElementAt(i);
}
return null;
}
private Object lookupItem(String pattern) {
return this.findStringWithin(pattern);
}
}