JComboBox搜索列表

我想制作一个可以搜索内容的JComboBox 。 我尝试过AutoCompleteDecorator, GlazedLists, SwingLabs, JIDE, Laf-Widget ,但是所有的都无法通过第二个关键字进行搜索。 例如,在此代码中,可能按第一个字母搜索,此内容仅包含一个单词。

 this.comboBox = new JComboBox(new Object[] { "Ester", "Jordi", "Jordina", "Jorge", "Sergi" }); AutoCompleteDecorator.decorate(this.comboBox); 

如果JComboBox内容包含2或3个单词,例如:“Ester Jordi”或“Jorge Sergi”,在这种情况下,如果我输入“Sergi”, JComboBox不会显示任何内容,因为它可以通过第一个单词识别。 我想问一下有没有办法解决这个问题?

我重构了给定的代码。 它可以通过片段识别。 因此,当您放入“英语”时,“美国英语”和“英语”就会得到认可。

您可以在程序中使用FilterComboBox类。

 import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.List; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.UIManager; /** * A class for filtered combo box. */ public class FilterComboBox extends JComboBox { /** * Entries to the combobox list. */ private List entries; public List getEntries() { return entries; } public FilterComboBox(List entries) { super(entries.toArray()); this.entries = entries ; this.setEditable(true); final JTextField textfield = (JTextField) this.getEditor().getEditorComponent(); /** * Listen for key presses. */ textfield.addKeyListener(new KeyAdapter() { public void keyReleased(KeyEvent ke) { SwingUtilities.invokeLater(new Runnable() { public void run() { /** * On key press filter the list. * If there is "text" entered in text field of this combo use that "text" for filtering. */ comboFilter(textfield.getText()); } }); } }); } /** * Build a list of entries that match the given filter. */ public void comboFilter(String enteredText) { List entriesFiltered = new ArrayList(); for (String entry : getEntries()) { if (entry.toLowerCase().contains(enteredText.toLowerCase())) { entriesFiltered.add(entry); } } if (entriesFiltered.size() > 0) { this.setModel( new DefaultComboBoxModel( entriesFiltered.toArray())); this.setSelectedItem(enteredText); this.showPopup(); } else { this.hidePopup(); } } } 

了解FilterComboBox在Demo程序中的工作原理。

 import javax.swing.JFrame; import java.util.Arrays; public class Demo { public static void makeUI() { JFrame frame = new JFrame("Your frame"); /** * Put data to your filtered combobox. */ FilterComboBox fcb = new FilterComboBox( Arrays.asList( "", "English", "French", "Spanish", "Japanese", "Chinese", "American English", "Canada French" )); /** * Set up the frame. */ frame.getContentPane().add(fcb); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } public static void main(String[] args) throws Exception { makeUI(); } } 

另一种方法,我们将现有的combobox用于过滤combobox。 它有点“装饰”。

“装饰者”课。

 import java.util.List; import java.util.ArrayList; import javax.swing.JComboBox; import javax.swing.JTextField; import javax.swing.DefaultComboBoxModel; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.swing.SwingUtilities; import javax.swing.UIManager; /** * Makes given combobox editable and filterable. */ public class JComboBoxDecorator { public static void decorate(final JComboBox jcb, boolean editable) { List entries = new ArrayList<>(); for (int i = 0; i < jcb.getItemCount(); i++) { entries.add((String)jcb.getItemAt(i)); } decorate(jcb, editable, entries); } public static void decorate(final JComboBox jcb, boolean editable, final List entries) { jcb.setEditable(editable); jcb.setModel( new DefaultComboBoxModel( entries.toArray())); final JTextField textField = (JTextField) jcb.getEditor().getEditorComponent(); textField.addKeyListener( new KeyAdapter() { public void keyReleased(KeyEvent e) { SwingUtilities.invokeLater( new Runnable() { public void run() { comboFilter(textField.getText(), jcb, entries); } } ); } } ); } /** * Build a list of entries that match the given filter. */ private static void comboFilter(String enteredText, JComboBox jcb, List entries) { List entriesFiltered = new ArrayList(); for (String entry : entries) { if (entry.toLowerCase().contains(enteredText.toLowerCase())) { entriesFiltered.add(entry); } } if (entriesFiltered.size() > 0) { jcb.setModel( new DefaultComboBoxModel( entriesFiltered.toArray())); jcb.setSelectedItem(enteredText); jcb.showPopup(); } else { jcb.hidePopup(); } } } 

示范课。

 import javax.swing.JFrame; import java.util.Arrays; import java.util.List; import java.util.ArrayList; import javax.swing.JComboBox; import javax.swing.JPanel; public class Demo { public static void makeUI() { JFrame frame = new JFrame("Demonstration"); /** * List of values for comboboxes. */ List list = Arrays.asList( "", "English", "French", "Spanish", "Japanese", "Chinese", "American English", "Canada French" ); List list2 = Arrays.asList( "", "Anglais", "Francais", "Espagnol", "Japonais", "Chinois", "Anglais americain", "Canada francais" ); /** * Set up the frame. */ JPanel panel = new JPanel(); frame.add(panel); /** * Create ordinary comboboxes. * These comboboxes represent premade combobox'es. Later in the run-time we make some of them filtered. */ JComboBox jcb1 = new JComboBox<>(list.toArray(new String[0])); panel.add(jcb1); JComboBox jcb2 = new JComboBox<>(); panel.add(jcb2); JComboBox jcb3 = new JComboBox<>(list2.toArray(new String[0])); panel.add(jcb3); /** * On the run-time we convert second and third combobox'es to filtered combobox'es. * The jcb1 combobox is left as it was. * For the first decorated combobox supply our entries. * For the other put entries from list2. */ JComboBoxDecorator.decorate(jcb2, true, list); JComboBoxDecorator.decorate(jcb3, true); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } public static void main(String[] args) throws Exception { makeUI(); } }