我想制作一个内容可以搜索的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
不会显示任何内容,因为它可以通过第一个单词识别。我想问一下,有没有办法解决这个问题?
发布于 2015-02-17 06:16:19
我重构了给定的代码。它可以通过碎片识别。因此,“美式英语”和“英语”在你把“英语”放在一起时就被认可了。
您可以在程序中使用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<String> entries;
public List<String> getEntries()
{
return entries;
}
public FilterComboBox(List<String> 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<String> entriesFiltered = new ArrayList<String>();
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是如何在演示程序中工作的。
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();
}
}
另一种方法,我们把现有的组合框变成过滤的组合框。这有点“装饰”。
“装饰品”课。
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<String> 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<String> 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<String> entries)
{
List<String> entriesFiltered = new ArrayList<String>();
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<String> list = Arrays.asList(
"",
"English",
"French",
"Spanish",
"Japanese",
"Chinese",
"American English",
"Canada French"
);
List<String> 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<String> jcb1 = new JComboBox<>(list.toArray(new String[0]));
panel.add(jcb1);
JComboBox<String> jcb2 = new JComboBox<>();
panel.add(jcb2);
JComboBox<String> 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();
}
}
发布于 2021-06-12 15:28:27
在尝试执行时,我遇到了两个问题:
return
语句来解决这个问题。getKeyStat()
来解决这个问题,在popupMenuWillBecomeInvisible
内部的主框架中添加这段代码希望这能有所帮助!
private voidjCombobox1popupMenuWillBecomeInvisble(javax.swing.event.PopupMenuEvent evt){
if(JComboBoxDecorator.getKeyStat().equals("enter")){
//write yor code here
}
}
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;
/**
* Makes given combo box editable and filterable.
*/
public class JComboBoxDecorator {
static String checkenter="";
public static String getKeyStat(){
return checkenter;
}
public static void decorate(final JComboBox jcb, boolean editable) {
List<String> 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<String> entries) {
jcb.setEditable(editable);
jcb.setModel(new DefaultComboBoxModel(entries.toArray()));
final JTextField textField = (JTextField) jcb.getEditor().getEditorComponent();
textField.addKeyListener(
new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER){
checkenter = "enter";
}
}
@Override
public void keyReleased(KeyEvent e) {
SwingUtilities.invokeLater(() -> {
if(e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode()==KeyEvent.VK_ENTER){
// e.consume();
return ;
}
else{
comboFilter(textField.getText(), jcb, entries);
}
});
checkenter = "type";
}
}
);
}
/**
* Build a list of entries that match the given filter.
*/
private static void comboFilter(String enteredText, JComboBox jcb, List<String> entries) {
List<String> 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();
}
}
}
https://stackoverflow.com/questions/27753375
复制相似问题