1

たとえば、JComboBox{"example 1", "example 2", "example 3"} という要素を持つ a があるとします (example と対応する番号の間のスペースに注意してください)。

コンボボックスが選択されている状態で入力して「例 2」を検索しようとすると、スペースバーがコンポーネントのポップアップを切り替えるため、コンボボックスが閉じます。

これは、次の 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);

このソリューションの問題点は、アプリケーション内のすべてのコンボ ボックスのポップアップ機能が削除されることです。これは、必要な場合とそうでない場合があります。

編集:

これが 1 つのコンボ ボックスの場合は、より多くの作業が必要になります。omboBox.selectWithKeyChar()メソッドを呼び出す必要があります。これは、カスタム アクションを使用すると簡単に実行できます。残念ながら、このコードは BasicComboBoxUI クラスに含まれるいくつかのクラス変数に依存するDefaultKeySelectionManagerを呼び出すことになるため、これはまだ機能しません。したがって、これらすべての変数をローカルに保持する独自のフロー 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

キーが押されたイベントをキャッチし、目的の文字列に「」を追加するだけです。

于 2013-02-13T23:23:23.153 に答える