修改Swing中的ComboBox显示

时间:2011-10-11 20:51:37

标签: java swing jcombobox

我想以这样的方式修改(不可编辑的)JComboBox的显示,使得当前所选条目在编辑字段中有一些额外的文本(下拉列表,但是)。

这样的事情:

Mockup

我的第一个猜测是覆盖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); }
}

实际上,只要修改显示器就行了。不幸的是,当前条目不再标记为活动:

Wrong display

(注意缺少的复选标记......或者操作系统会显示选择。)

进一步检查显示,每次用户在框中选择新项目时,都会使用索引getElementAt调用模型的-1方法。这是使用修改后的选定项目时的情况。当模型的getSelectedItem方法返回没有包装器的普通对象时,所选项目在下拉框中被标记为已选中,而getElementAt 被调用,参数为{ {1}}。

显然,ComboBox依次将每个项目与当前活动的项目进行比较,但是,尽管我覆盖了-1方法,但它找不到匹配项。 我该如何解决这个问题?

(针对此问题的完整且可编译的代码at gist.github.com

2 个答案:

答案 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)

创建JTextFieldJButton IconJButton实现ButtonModel,覆盖其方法isRollover(), isPressed(), isArmed()

不从Icon中提取JComboBox,绘制自己的三角形,然后JButton IconLook and FeelNative OS抵抗,对于更好的输出实现JButton#setRolloverIcon()

创建JPopupJWindow,放在此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活动中的JPopupJWindow