首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JComboBox搜索列表

JComboBox搜索列表
EN

Stack Overflow用户
提问于 2015-01-03 09:24:38
回答 2查看 5.8K关注 0票数 2

我想制作一个内容可以搜索的JComboBox。我尝试了AutoCompleteDecorator, GlazedLists, SwingLabs, JIDE, Laf-Widget,但所有的搜索都不能通过第二个关键字进行。例如,在这段代码中,可以用第一个字母进行搜索,而这个内容只包含一个单词。

代码语言:javascript
运行
复制
this.comboBox = new JComboBox(new Object[] { "Ester", "Jordi", "Jordina", "Jorge", "Sergi" });
AutoCompleteDecorator.decorate(this.comboBox);

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-02-17 06:16:19

我重构了给定的代码。它可以通过碎片识别。因此,“美式英语”和“英语”在你把“英语”放在一起时就被认可了。

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

代码语言:javascript
运行
复制
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是如何在演示程序中工作的。

代码语言:javascript
运行
复制
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();
    }
}

另一种方法,我们把现有的组合框变成过滤的组合框。这有点“装饰”。

“装饰品”课。

代码语言:javascript
运行
复制
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();
        }
    }

}

示范课。

代码语言:javascript
运行
复制
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();
    }
}
票数 4
EN

Stack Overflow用户

发布于 2021-06-12 15:28:27

在尝试执行时,我遇到了两个问题:

  • 在键盘上按(上、下、输入)按钮时。我通过阻止他们使用return语句来解决这个问题。

  • 每次在textfield中写入时都会触发popupMenuWillBecomeInvisble()。我通过添加getKeyStat()来解决这个问题,在popupMenuWillBecomeInvisible内部的主框架中添加这段代码

希望这能有所帮助!

代码语言:javascript
运行
复制
   private voidjCombobox1popupMenuWillBecomeInvisble(javax.swing.event.PopupMenuEvent evt){
         if(JComboBoxDecorator.getKeyStat().equals("enter")){
           //write yor code here
        }
        }

代码语言:javascript
运行
复制
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();
        }
    }

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27753375

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档