我想以这样的方式修改(不可编辑的)JComboBox
的显示,使得当前所选条目在编辑字段中有一些额外的文本(不下拉列表,但是)。
这样的事情:
我的第一个猜测是覆盖ComboBox的模型,以便getSelectedItem
返回修改显示的包装器对象:
petList.setModel(new ComboBoxModel() {
private Object selected;
public void setSelectedItem(Object anItem) {
selected = anItem;
}
public Object getSelectedItem() {
return new ActiveComboItem(selected);
}
// … The rest of the methods are straightforward.
});
ActiveComboItem
如下所示:
static class ActiveComboItem {
private final Object item;
public ActiveComboItem(Object item) { this.item = item; }
@Override
public boolean equals(Object other) {
return item == null ? other == null : item.equals(other);
}
@Override
public String toString() { return String.format("Animal: %s", item); }
}
实际上,只要修改显示器就行了。不幸的是,当前条目不再标记为活动:
(注意缺少的复选标记......或者操作系统会显示选择。)
进一步检查显示,每次用户在框中选择新项目时,都会使用索引getElementAt
调用模型的-1
方法。这是仅使用修改后的选定项目时的情况。当模型的getSelectedItem
方法返回没有包装器的普通对象时,所选项目在下拉框中被标记为已选中,而getElementAt
未被调用,参数为{ {1}}。
显然,ComboBox依次将每个项目与当前活动的项目进行比较,但是,尽管我覆盖了-1
方法,但它找不到匹配项。 我该如何解决这个问题?
(针对此问题的完整且可编译的代码at gist.github.com)
答案 0 :(得分:7)
您需要提供自定义ListCellRenderer。以下作品:
final JComboBox animalCombo = new JComboBox(animals);
animalCombo.setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(final JList list, Object value, final int index, final boolean isSelected,
final boolean cellHasFocus) {
if (index == -1) {
value = "Animal: " + value;
}
return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
}
});
index为-1时,其绘制的值是不在下拉列表中的值。
为了将来参考,当您只想更改Swing中显示内容的方式时,您永远不想修改背景模型。每个组件都有一个渲染器,通常你只需稍微修改一个默认的渲染器。
答案 1 :(得分:-1)
创建JTextField
和JButton
Icon
,JButton
实现ButtonModel
,覆盖其方法isRollover(), isPressed(), isArmed()
不从Icon
中提取JComboBox
,绘制自己的三角形,然后JButton
Icon
将Look and Feel
和Native OS
抵抗,对于更好的输出实现JButton#setRolloverIcon()
创建JPopup
或JWindow
,放在此JScrollPane
,从model.isPressed()
或isArmed
现在你有两个选择
1)创建包含JList
的{{1}}(从JCheckBox中删除矩形)
JCheckBox
2)或实现ListSelectionModel并在MouseClick
上添加/删除import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
public class CheckList {
public static void main(String args[]) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create a list containing CheckListItem's
JList list = new JList(new CheckListItem[]{
new CheckListItem("apple"),
new CheckListItem("orange"),
new CheckListItem("mango"),
new CheckListItem("paw paw"),
new CheckListItem("banana")});
// Use a CheckListRenderer (see below) to renderer list cells
list.setCellRenderer(new CheckListRenderer());
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.addMouseListener(new MouseAdapter() {// Add a mouse listener to handle changing selection
@Override
public void mouseClicked(MouseEvent event) {
JList list = (JList) event.getSource();
int index = list.locationToIndex(event.getPoint());// Get index of item clicked
CheckListItem item = (CheckListItem) list.getModel().getElementAt(index);
item.setSelected(!item.isSelected()); // Toggle selected state
list.repaint(list.getCellBounds(index, index));// Repaint cell
}
});
frame.getContentPane().add(new JScrollPane(list));
frame.pack();
frame.setVisible(true);
}
}
// Represents items in the list that can be selected
class CheckListItem {
private String label;
private boolean isSelected = false;
public CheckListItem(String label) {
this.label = label;
}
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean isSelected) {
this.isSelected = isSelected;
}
@Override
public String toString() {
return label;
}
}
// Handles rendering cells in the list using a check box
class CheckListRenderer extends JCheckBox implements ListCellRenderer {
private static final long serialVersionUID = 1L;
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean hasFocus) {
setEnabled(list.isEnabled());
setSelected(((CheckListItem) value).isSelected());
setFont(list.getFont());
setBackground(list.getBackground());
setForeground(list.getForeground());
setText(value.toString());
return this;
}
}
隐藏Icon
活动中的JPopup
或JWindow