我使用示例代码创建了带复选框项的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中一样。 有没有办法做到这一点,因为在我的一个应用程序中我们需要它。
答案 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;开头的第一个条目,而不是第二个条目。
您可以使用向上/向下箭头键在任何组合框中选择。
要为您提供所需的行为,请在应用程序中添加一个键侦听器,并根据按下的键选择相关条目。虽然我没有内置的方式,但我知道这样做。