JComboBox search list

你。 提交于 2019-12-10 10:29:53

问题


I w'd like make a JComboBox that contents could be searchable. I tried AutoCompleteDecorator, GlazedLists, SwingLabs, JIDE, Laf-Widget, but all of the cannot search by second keyword. For example, in this code possible search by 1st letter and this content includes just one word.

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

If JComboBox content consists 2 or 3 words, for example: "Ester Jordi" or "Jorge Sergi", in this case if I enter "Sergi", JComboBoxdon't show nothing, because it can recognize by 1st word. I w'd like to ask is there have any way to solve this problem?


回答1:


I refactored the given code. It can recognize by the fragment. So "American English" and "English" are recognized when you put "English".

You could use the FilterComboBox class in your program.

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();
        }
    }
}

See how FilterComboBox works in Demo program.

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();
    }
}

Another approach, where we make existing comboboxes to filtered comboboxes. It is somewhat "decoration".

"Decorator" class.

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();
        }
    }

}

Demonstration class.

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();
    }
}


来源:https://stackoverflow.com/questions/27753375/jcombobox-search-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!