Java 使用复选框自动选择/突出显示combox中的项目

Java 使用复选框自动选择/突出显示combox中的项目,java,swing,jcombobox,Java,Swing,Jcombobox,我使用示例代码创建带有复选框项的组合框。 我使用JComboCheckBox的示例程序 import javax.swing.JCheckBox; import javax.swing.JFrame; public class ComboBoxMainClass { public static void main(String[] args) { // Frame for our test JComboCheckBox combo = new JComboCheckBox(

我使用示例代码创建带有复选框项的组合框。

我使用JComboCheckBox的示例程序

import javax.swing.JCheckBox;
import javax.swing.JFrame;

public class ComboBoxMainClass {
public static void main(String[] args) {
    // Frame for our test

    JComboCheckBox combo = new JComboCheckBox(new JCheckBox[] {
            new JCheckBox(""), new JCheckBox("First"),
            new JCheckBox("Second") });

    JFrame f = new JFrame("Frame Form Example");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.getContentPane().add(combo);
    // Show the frame
    f.pack();
    f.setVisible(true);
}
}
但我不能在按键时选择组合项目。 e、 g.如果组合文本为第一个,则为第二个等。。 用户按“S”键, 应突出显示/选择第二个。就像在普通的JComboBox中一样。
在我的一个应用程序中,我们需要它。这不是普通jComboBox的工作方式,按“S”键会突出显示以“S”开头的第一个条目,而不是第二个条目

您可以使用上/下箭头键在任何组合框中进行选择


要给出行为,您需要在应用程序中添加一个键侦听器,并根据按下的键选择相关条目。不过,我知道没有内置的方法来执行此操作。

组合框项目选择由
按键选择管理器完成。默认实现使用从添加到ComboBoxModel的对象的
toString()
方法返回的值来确定要选择的项

您可以创建一个自定义的
JCheckBox
组件,并重写
toString()
方法以返回
getText()
方法

或者,另一种方法是创建要与自定义渲染器一起使用的自定义KeySelectionManager。这种方法更复杂

检查作为渲染器和
KeySelectionManager
的类。但是,此类旨在显示业务对象的属性,而不是Swing组件,因此需要进一步自定义

以下是显示JCheckBox的自定义版本:

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

/*
 *  This class can be used as the renderer and KeySelectionManager for an
 *    Object added to the ComboBoxModel.
 *
 *  The class must be extended and the getDisplayValue() method must be
 *  implemented. This method will return a String to be rendered in the
 *  JComboBox. The same String will be used to do key selection of an
 *  item in the ComboBoxModel.
 */
public class CheckBoxKeySelectionRenderer extends BasicComboBoxRenderer
    implements JComboBox.KeySelectionManager
{
    //  Used by the KeySelectionManager implementation to determine when to
    //  start a new search or append typed character to the existing search.

    private long timeFactor;
    private long lastTime;
    private long time;
    private String prefix = "";

    public CheckBoxKeySelectionRenderer(JComboBox comboBox)
    {
        comboBox.setRenderer( this );
        comboBox.setKeySelectionManager( this );

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

    /**
     *  This method must be implemented in the extended class.
     *
     *  @param item an item from the ComboBoxModel
     *  @returns a String containing the text to be rendered for this item.
    */
    public String getDisplayValue(Object item)
    {
        if (item instanceof JCheckBox)
        {
            JCheckBox checkBox = (JCheckBox)item;
            return checkBox.getText();
        }
        else
            return item.toString();
    }

    //  Implement the renderer

    @Override
    public Component getListCellRendererComponent(
        JList list, Object item, int index, boolean isSelected, boolean hasFocus)
    {
        super.getListCellRendererComponent(list, item, index, isSelected, hasFocus);

        if (item instanceof JCheckBox)
        {
            Component c = (Component)item;

            if (isSelected)
            {
                c.setBackground(list.getSelectionBackground());
                c.setForeground(list.getSelectionForeground());
            }
            else
            {
                c.setBackground(list.getBackground());
                c.setForeground(list.getForeground());
            }

            return c;
        }

        return this;
    }

    //  Implement the KeySelectionManager

    @Override
    public int selectionForKey(char aKey, ComboBoxModel model)
    {
        time = System.currentTimeMillis();

        //  Get the index of the currently selected item

        int size = model.getSize();
        int startIndex = -1;
        Object selectedItem = model.getSelectedItem();

        if (selectedItem != null)
        {
            for (int i = 0; i < size; i++)
            {
                if ( selectedItem == model.getElementAt(i) )
                {
                    startIndex  =  i;
                    break;
                }
            }
        }

        //  Determine the "prefix" to be used when searching the model. The
        //  prefix can be a single letter or multiple letters depending on how
        //  fast the user has been typing and on which letter has been typed.

        if (time - lastTime < timeFactor)
        {
            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 += aKey;
            }
        }
        else
        {
            startIndex++;
            prefix = "" + aKey;
        }

        lastTime = time;

        //  Search from the current selection and wrap when no match is found

        if (startIndex < 0 || startIndex >= size)
        {
            startIndex = 0;
        }

        int index = getNextMatch(prefix, startIndex, size, model);

        if (index < 0)
        {
            // wrap
            index = getNextMatch(prefix, 0, startIndex, model);
        }

        return index;
    }

    /*
    **  Find the index of the item in the model that starts with the prefix.
    */
    private int getNextMatch(String prefix, int start, int end, ComboBoxModel model)
    {
        for (int i = start; i < end; i++ )
        {
            Object item = model.getElementAt(i);

            if (item != null)
            {
                String displayValue = getDisplayValue( item ).toLowerCase();

                if (displayValue.startsWith(prefix))
                {
                    return i;
                }
            }
        }

        return -1;
    }
}

这将替换当前渲染器。但是,您仍然无法切换当前选定项目的选择状态。这是因为组合框不会选择同一项两次。这是一个组合框问题,而不是渲染器问题。我不知道如何解决这个问题。

thnx获取您的答案。它适用于示例程序。但不知何故,在我的应用程序中,KeySelectionManager.selectionForKey无法调用,java.awt.Component.processKeyEvent(KeyEvent)正在被调用,其中侦听器obejct也将提交null,而对于普通JComboBox,此侦听器对象不为null。尽管我们没有为这两个版本调整任何自定义侦听器的大小。我不知道为什么会绕过KeySelectionManager。我和@hitesh saxena有同样的问题。未调用此代码,processKeyEvent为。
new CheckBoxKeySelectionRenderer(combo);