如何在Java中向JComboBox添加分隔符?
我有一个JComboBox,希望在元素列表中有一个分隔符。如何在Java中实现这一点 在一个示例场景中,当为字体系列选择创建一个组合框时,这将派上用场;类似于Word和Excel中的字体族选择控件。在本例中,我想在顶部显示最常用的字体,然后是分隔符,最后是按字母顺序显示分隔符下面的所有字体系列如何在Java中向JComboBox添加分隔符?,java,swing,jcombobox,jseparator,Java,Swing,Jcombobox,Jseparator,我有一个JComboBox,希望在元素列表中有一个分隔符。如何在Java中实现这一点 在一个示例场景中,当为字体系列选择创建一个组合框时,这将派上用场;类似于Word和Excel中的字体族选择控件。在本例中,我想在顶部显示最常用的字体,然后是分隔符,最后是按字母顺序显示分隔符下面的所有字体系列 有人能帮我做这件事吗?这在Java中是不可能的吗?您可以使用自定义的ListCellRenderer,它将以不同的方式绘制分隔符项。请参阅和一个小教程。有一个非常简短的教程,其中有一个示例,演示如何在ja
有人能帮我做这件事吗?这在Java中是不可能的吗?您可以使用自定义的
ListCellRenderer
,它将以不同的方式绘制分隔符项。请参阅和一个小教程。有一个非常简短的教程,其中有一个示例,演示如何在java2s上使用自定义ListCellRenderer
基本上,它包括在列表模型中插入一个已知的占位符,当您在ListCellRenderer中检测到占位符时,您将返回一个“new JSepator(JSepator.HORIZONTAL)”的实例。在我编写和测试下面的代码时,您可能得到了很多更好的答案……
我不介意,因为我喜欢这个实验/学习(秋千的正面还是有点绿) [编辑]三年后,我的环保意识有所下降,我考虑到了Bobndew的合理评论。我对刚刚工作的键导航没有问题(可能是JVM版本问题?)。不过,我改进了渲染器以显示高光。我使用了更好的演示代码。被接受的答案可能更好(更标准),如果你想要自定义分隔符,我的答案可能更灵活 基本思想是对组合框的项目使用渲染器。对于大多数项目,它是一个带有项目文本的简单JLabel。对于最近/最常用的项目,我用自定义边框在其底部绘制一条线来装饰JLabel
import java.awt.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class TwoPartsComboBox extends JComboBox
{
private int m_lastFirstPartIndex;
public TwoPartsComboBox(String[] itemsFirstPart, String[] itemsSecondPart)
{
super(itemsFirstPart);
m_lastFirstPartIndex = itemsFirstPart.length - 1;
for (int i = 0; i < itemsSecondPart.length; i++)
{
insertItemAt(itemsSecondPart[i], i);
}
setRenderer(new JLRenderer());
}
protected class JLRenderer extends JLabel implements ListCellRenderer
{
private JLabel m_lastFirstPart;
public JLRenderer()
{
m_lastFirstPart = new JLabel();
m_lastFirstPart.setBorder(new BottomLineBorder());
// m_lastFirstPart.setBorder(new BottomLineBorder(10, Color.BLUE));
}
@Override
public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus)
{
if (value == null)
{
value = "Select an option";
}
JLabel label = this;
if (index == m_lastFirstPartIndex)
{
label = m_lastFirstPart;
}
label.setText(value.toString());
label.setBackground(isSelected ? list.getSelectionBackground() : list.getBackground());
label.setForeground(isSelected ? list.getSelectionForeground() : list.getForeground());
label.setOpaque(true);
return label;
}
}
}
测试等级:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class TwoPartsComboBoxDemo extends JFrame
{
private TwoPartsComboBox m_combo;
public TwoPartsComboBoxDemo()
{
Container cont = getContentPane();
cont.setLayout(new FlowLayout());
cont.add(new JLabel("Data: ")) ;
String[] itemsRecent = new String[] { "ichi", "ni", "san" };
String[] itemsOther = new String[] { "one", "two", "three" };
m_combo = new TwoPartsComboBox(itemsRecent, itemsOther);
m_combo.setSelectedIndex(-1);
cont.add(m_combo);
m_combo.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
String si = (String) m_combo.getSelectedItem();
System.out.println(si == null ? "No item selected" : si.toString());
}
});
// Reference, to check we have similar behavior to standard combo
JComboBox combo = new JComboBox(itemsRecent);
cont.add(combo);
}
/**
* Start the demo.
*
* @param args the command line arguments
*/
public static void main(String[] args)
{
// turn bold fonts off in metal
UIManager.put("swing.boldMetal", Boolean.FALSE);
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
JFrame demoFrame = new TwoPartsComboBoxDemo();
demoFrame.setTitle("Test GUI");
demoFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
demoFrame.setSize(400, 100);
demoFrame.setVisible(true);
}
});
}
}
在这里,变量命名并不是最糟糕的事情:您正在破坏整个组合框项选择:选择不再被绘制,并且第一个字母键跳转被破坏。您应该在尽可能小的范围内(在
publicttestgui()
中)定义m_组合
和m_呈现程序
)。并且不应该对渲染器和“TestGui”类(应该是单独的主类,而不是“JFrame”子类)使用gloobalm_lastRecentIndex
)。但是我喜欢牙套的样式@波德鲁:嘿!正如我写的,我当时是个新手(已经3年了!)。在你们没有指出的错误中,我可能使用了我发现的一些Swing测试模板,更糟糕的是,我没有使用SwingUtilities.invokeLater!我目前的代码至少使用了它(但它仍然是一个JFrame子类…)。而且m_lastRecentIndex更本地化。。。但是您的大多数批评都是关于一个快速生成的测试类,它不是真正的生产代码。今天,我更加关注这些代码,因为新手可以从中获得灵感…:-)另外,关于突出显示悬停元素和选定内容,您是正确的。TODONote:我编辑了上面的代码以获得更现代/正确的版本。我的方法的一个优点是,它比JSepator更灵活(至少在外观上),而且不占用任何时间。示例BlockComboBoxExample
打破了光标键和第一个字母键的导航。桑托什·库马尔的似乎效果更好。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class TwoPartsComboBoxDemo extends JFrame
{
private TwoPartsComboBox m_combo;
public TwoPartsComboBoxDemo()
{
Container cont = getContentPane();
cont.setLayout(new FlowLayout());
cont.add(new JLabel("Data: ")) ;
String[] itemsRecent = new String[] { "ichi", "ni", "san" };
String[] itemsOther = new String[] { "one", "two", "three" };
m_combo = new TwoPartsComboBox(itemsRecent, itemsOther);
m_combo.setSelectedIndex(-1);
cont.add(m_combo);
m_combo.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
String si = (String) m_combo.getSelectedItem();
System.out.println(si == null ? "No item selected" : si.toString());
}
});
// Reference, to check we have similar behavior to standard combo
JComboBox combo = new JComboBox(itemsRecent);
cont.add(combo);
}
/**
* Start the demo.
*
* @param args the command line arguments
*/
public static void main(String[] args)
{
// turn bold fonts off in metal
UIManager.put("swing.boldMetal", Boolean.FALSE);
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
JFrame demoFrame = new TwoPartsComboBoxDemo();
demoFrame.setTitle("Test GUI");
demoFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
demoFrame.setSize(400, 100);
demoFrame.setVisible(true);
}
});
}
}