使用多字元素搜索JComboBoxes

时间:2013-02-13 23:09:57

标签: java swing jcombobox

例如,假设我有JComboBox元素{“示例1”,“示例2”,“示例3”}(请注意示例与相应数字之间的空格)。

当您在选择组合框时尝试通过键入搜索“示例2”时,它会关闭,因为空格键会切换组件的弹出窗口。

这可以分为两个问题:

  1. 我做了一个swing事件,到目前为止它识别出空格键,并且我已经禁用了JComboBox的默认空格键操作。如何制作它以便按空格键实际上会使其添加到搜索?
  2. 如果#1不可能或未知,还有其他方法吗?
  3. 任何能够正确回答这个问题的人都绝对会收到一个upvote。

2 个答案:

答案 0 :(得分:3)

您可以使用:

KeyStroke space = KeyStroke.getKeyStroke("pressed SPACE");
InputMap im = comboBox.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
im.getParent().remove(space);

此解决方案的问题在于它会删除应用程序中所有组合框的弹出功能,这可能是您想要的也可能不是。

编辑:

如果是单个组合框,则需要更多工作。您需要调用 comboBox.selectWithKeyChar()方法。这很容易与自定义Action一起使用。不幸的是,这仍然不起作用,因为此代码最终调用 DefaultKeySelectionManager ,这依赖于BasicComboBoxUI类中包含的一些类变量。因此,我最终编写了自己的ow KeySelectionManager,它将所有这些变量保持为本地。这就是我想出的:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.basic.*;
import javax.swing.text.*;

public class ComboBoxKeySelection extends JPanel
{
    JComboBox<String> comboBox;

    public ComboBoxKeySelection()
    {
        String[] data =
        {
            " 1", " 2",  " 3", " 4",
            "a", "ab", "abc", "abcd",
            "b1", "b2", "b3", "b4", "be",
            "c", "d", "e", "f"
        };

        comboBox = new JComboBox<String>( data );
        add( comboBox );

        Action search = new AbstractAction()
        {
            public void actionPerformed(ActionEvent e)
            {
                comboBox.selectWithKeyChar( " ".charAt(0) );
            }
        };

        KeyStroke space = KeyStroke.getKeyStroke("typed SPACE");
        comboBox.getActionMap().put("spacePopup", search);

        comboBox.setKeySelectionManager( new MyKeySelectionManager(comboBox) );
    }


    static class MyKeySelectionManager implements JComboBox.KeySelectionManager
    {
        private JComboBox comboBox;
        private JList listBox;
        private boolean useComboBoxModel;

        private long timeFactor;
        private long lastTime;
        private long time;

        private String prefix = "";
        private String typedString = "";

        public MyKeySelectionManager(JComboBox comboBox)
        {
            this.comboBox = comboBox;

            Long l = (Long)UIManager.get("ComboBox.timeFactor");
            timeFactor = l == null ? 1000L : l.longValue();

            Object child = comboBox.getAccessibleContext().getAccessibleChild(0);

            if (child instanceof BasicComboPopup)
            {
                BasicComboPopup popup = (BasicComboPopup)child;
                listBox = popup.getList();
                useComboBoxModel = false;
            }
            else
            {
                listBox = new JList();
                useComboBoxModel = true;
            }
        }

        public int selectionForKey(char aKey, ComboBoxModel aModel)
        {
            if (useComboBoxModel)
            {
                listBox.setModel( aModel );
            }

            time = System.currentTimeMillis();
            boolean startingFromSelection = true;
            int startIndex = comboBox.getSelectedIndex();

            if (time - lastTime < timeFactor)
            {
                typedString += aKey;

                if((prefix.length() == 1) && (aKey == prefix.charAt(0)))
                {
                    // Subsequent same key presses move the keyboard focus to the next
                    // object that starts with the same letter.
                    startIndex++;
                }
                else
                {
                    prefix = typedString;
                }
            }
            else
            {
                startIndex++;
                typedString = "" + aKey;
                prefix = typedString;
            }

            lastTime = time;

            if (startIndex < 0 || startIndex >= aModel.getSize())
            {
                startingFromSelection = false;
                startIndex = 0;
            }

            int index = listBox.getNextMatch(prefix, startIndex, Position.Bias.Forward);

            if (index < 0 && startingFromSelection)
            {
                // wrap
                index = listBox.getNextMatch(prefix, 0, Position.Bias.Forward);
            }

            return index;
        }
    }


    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("ComboBoxKeySelection");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new ComboBoxKeySelection() );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

答案 1 :(得分:0)

你可以捕获keypressed事件,只需在所需的字符串中附加“”即可。