1

例如,假设我有一个JComboBox元素 {"example 1", "example 2", "example 3"} (请注意 example 和相应数字之间的空格)。

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

这可以分为两个问题:

  1. 我已经做了一个摇摆事件,到目前为止它可以识别空格键,并且我已经禁用了JComboBox. 我该如何做到这一点,以便按下空格键实际上会使其在搜索中添加“”?
  2. 如果 #1 不可能或未知,还有什么其他方法可以做到这一点?

任何能正确回答这个问题的人都肯定会得到支持。

4

2 回答 2

4

您可以使用:

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

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

编辑:

如果这是针对单个组合框,则需要更多的工作。您需要调用comboBox.selectWithKeyChar()方法。使用自定义操作很容易做到这一点。不幸的是,这仍然不起作用,因为此代码最终调用了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();
            }
        });
    }
}
于 2013-02-14T23:19:16.650 回答
0

您可以捕获 keypressed 事件并简单地将“”附加到所需的字符串。

于 2013-02-13T23:23:23.153 回答