使用多字元素搜索JComboBoxes [英] Searching JComboBoxes with multi-word elements

查看:154
本文介绍了使用多字元素搜索JComboBoxes的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

比如说,我有一个 JComboBox ,其元素为{示例1,示例2,示例3}(请注意示例和相应数字之间的空格)。



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



这可以分为两个问题:


  1. 我做了一个swing事件,到目前为止,它识别空格键,并且我已禁用 JComboBox 的默认空格键操作。我如何制作它以便按空格键实际上会使它添加到搜索?

  2. 如果#1不可能或未知,还有什么方法可以这样做?

任何能够正确回答这个问题的人都绝对会收到一个upvote。

  KeyStroke space = KeyStroke.getKeyStroke( 压制太空); 
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。*;

公共类ComboBoxKeySelection扩展JPanel
{
JComboBox< String>组合框;

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

动作搜索= 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));
}


静态类MyKeySelectionManager实现JComboBox.KeySelectionManager
{
private JComboBox comboBox;
private JList listBox;
private boolean useComboBoxModel;

private long timeFactor;
private long lastTime;
私人长时间;

private String prefix =;
private String typedString =;

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

Long l =(长)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)))
{
//后续相同的密钥press将键盘焦点移动到以相同字母开头的下一个
//对象。
startIndex ++;
}
else
{
prefix = typedString;
}
}
其他
{
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。向前);
}

返回索引;
}
}


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


Let's say, for example, that I have a JComboBox with the elements {"example 1", "example 2", "example 3"} (please note the spaces between example and the corresponding number).

When you try to search "example 2" by typing while the combobox is selected, it closes because the space bar toggles the popup of the component.

This could be split up into two questions:

  1. I have made a swing event and so far it recognizes the space key and I have disabled the default space bar action of the JComboBox. How do I make it so that pressing the space bar will actually make it add " " to the search?
  2. If #1 isn't possible or is unknown, what other way is there to do this?

Anyone who can answer this question properly will most definitely recieve an upvote.

解决方案

You can use:

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

The problem with this solution is that it removes the popup functionality for all combo boxes in your application, which may or may not be what you want.

Edit:

If this is for a single combo box the more work required. You need to invoke the comboBox.selectWithKeyChar() method. This is easy enough to do with a custom Action. Unfortunately this still doesn't work because this code ends up invoking the DefaultKeySelectionManager which depends on some class variables contained in the BasicComboBoxUI class. Therefore I ended up writing my own ow KeySelectionManager which keeps all these variable local. This is what I came up with:

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

这篇关于使用多字元素搜索JComboBoxes的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆