使用checkBox在combox中自动选择/突出显示项目

时间:2015-05-26 10:55:18

标签: java swing jcombobox

我使用示例代码创建了带复选框项的Combobox。 Java - Check Boxes in a 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(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);
}
}

但我无法在按键上选择组合项目。 例如如果组合文本是第一,第二等。     用户按“S”键,     应突出显示/选择第二个。就像在普通的JComboBox中一样。     有没有办法做到这一点,因为在我的一个应用程序中我们需要它。

2 个答案:

答案 0 :(得分:1)

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

您可以创建自定义JCheckBox组件并覆盖toString()方法以返回getText()方法。

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

查看Combo Box With Custom Renderer作为渲染器和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;
    }
}

您可以通过在代码中添加以下内容来使用它:

new CheckBoxKeySelectionRenderer(combo);

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

答案 1 :(得分:0)

这不是正常的jComboBox如何工作,按下&#34; S&#34; key突出显示以&#34; S&#34;开头的第一个条目,而不是第二个条目。

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

要为您提供所需的行为,请在应用程序中添加一个键侦听器,并根据按下的键选择相关条目。虽然我没有内置的方式,但我知道这样做。