如何禁用JComboBox中的某些项目

时间:2014-05-18 13:58:05

标签: java swing netbeans jcombobox

我有一个ComboBox,其中我有8个项目,除了在某个条件下,我想要显示所有项目,用户应该只能选择前两个,所以我编程了如果条件为真并且用户选择任何其他选项,则它会显示一个显示"You cannot choose this"的消息框,然后自动选择默认值。到目前为止一切都很好。

但现在问题是,用户无法通过查看JComboBox的选项来判断哪些可以选择,所以我想要做的是如果条件为真,则除了以外的所有选项前两个应该被禁用(或灰色或其他东西),以便用户可以知道你不能选择它,如果他们仍然这样做,那么我的消息框应该出现。

我尝试了什么:我尝试查找this,但我无法弄清楚问题所做的事情(答案对我没有用)我也试过了其他选择,但没有成功。

注意:我正在使用Netbeans GUI创建所有内容,而我正在编写的代码在JComboBoxActionPerformed上,我是新手,所以我无法弄清楚自己,道歉该

2 个答案:

答案 0 :(得分:9)

首先......

这需要一些手动编码。 GUI Builder不会帮助你。

至于渲染......

您可以实现自己的BasicComboBoxRenderer,并在其中传递ListSelectionModel。根据您传递给它的模型,只有选定的间隔将使用标准渲染器进行渲染。其余索引将以禁用方式呈现,方法是更改​​前景色及其选择背景。

注意:这只会影响项目的呈现,而不会影响实际的选择事件

import java.awt.Color;
import java.awt.Component;
import javax.swing.JList;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicComboBoxRenderer;

public class EnabledComboBoxRenderer extends BasicComboBoxRenderer {

    private ListSelectionModel enabledItems;

    private Color disabledColor = Color.lightGray;

    public EnabledComboBoxRenderer() {}

    public EnabledComboBoxRenderer(ListSelectionModel enabled) {
        super();
        this.enabledItems = enabled;
    }

    public void setEnabledItems(ListSelectionModel enabled) {
        this.enabledItems = enabled;
    }

    public void setDisabledColor(Color disabledColor) {
        this.disabledColor = disabledColor;
    }

    @Override
    public Component getListCellRendererComponent(JList list, Object value,
            int index, boolean isSelected, boolean cellHasFocus) {

        Component c = super.getListCellRendererComponent(list, value, index,
                isSelected, cellHasFocus);

        if (!enabledItems.isSelectedIndex(index)) {// not enabled
            if (isSelected) {
                c.setBackground(UIManager.getColor("ComboBox.background"));
            } else {
                c.setBackground(super.getBackground());
            }

            c.setForeground(disabledColor);

        } else {
            c.setBackground(super.getBackground());
            c.setForeground(super.getForeground());
        }
        return c;
    }
}

enter image description here

至于选择项目......

您可以使用两个单独的侦听器。一个用于启用项目,一个用于禁用项目。启用项目后,您可以 1。更改选择模型 2. 添加已启用的侦听器 3. 删除已禁用的侦听器

private class EnabledListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println(((JComboBox) e.getSource()).getSelectedItem());
    }
}

private class DisabledListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        if (((JComboBox) e.getSource()).getSelectedIndex() != SELECTION_INTERVAL[0]
                && ((JComboBox) e.getSource()).getSelectedIndex() != SELECTION_INTERVAL[1]) {
            JOptionPane.showMessageDialog(null,
                    "You can't Select that Item", "ERROR",
                    JOptionPane.ERROR_MESSAGE);
        } else {
            System.out.println(((JComboBox) e.getSource())
                    .getSelectedItem());
        }
    }
}

protected void enableItemsInComboBox() {
    comboBox.removeActionListener(disabledListener);
    comboBox.addActionListener(enabledListener);
    model.setSelectionInterval(SELECTION_INTERVAL[0], comboBox.getModel()
        .getSize() - 1);
}

反之亦然

protected void disableItemsInComboBox() {
    comboBox.removeActionListener(enabledListener);
    comboBox.addActionListener(disabledListener);
    model.setSelectionInterval(SELECTION_INTERVAL[0], SELECTION_INTERVAL[1]);
}

enter image description here

这是一个完整的运行示例,使用上面的EnabledComboBoxRenderer

import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.DefaultListSelectionModel;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

public class ComboBoxDisabledItemsDemo {
    private static final int[] SELECTION_INTERVAL = { 0, 1 };

    private JComboBox comboBox;
    private JCheckBox disableCheckBox;
    private DefaultListSelectionModel model = new DefaultListSelectionModel();
    private EnabledComboBoxRenderer enableRenderer = new EnabledComboBoxRenderer();

    private EnabledListener enabledListener = new EnabledListener();
    private DisabledListener disabledListener = new DisabledListener();

    public ComboBoxDisabledItemsDemo() {
        comboBox = createComboBox();

        disableCheckBox = createCheckBox();
        disableCheckBox.setSelected(true); // this adds the action listener to
                                            // the
                                            // to the combo box

        JFrame frame = new JFrame("Disabled Combo Box Items");
        frame.setLayout(new GridBagLayout());
        frame.add(comboBox);
        frame.add(disableCheckBox);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 300);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private JComboBox createComboBox() {
        String[] list = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5",
                "Item 6", "Item 7" };
        JComboBox cbox = new JComboBox(list);
        model.addSelectionInterval(SELECTION_INTERVAL[0], SELECTION_INTERVAL[1]);
        enableRenderer.setEnabledItems(model);
        cbox.setRenderer(enableRenderer);
        return cbox;
    }

    private class EnabledListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println(((JComboBox) e.getSource()).getSelectedItem());
        }
    }

    private class DisabledListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            if (((JComboBox) e.getSource()).getSelectedIndex() != SELECTION_INTERVAL[0]
                    && ((JComboBox) e.getSource()).getSelectedIndex() != SELECTION_INTERVAL[1]) {
                JOptionPane.showMessageDialog(null,
                        "You can't Select that Item", "ERROR",
                        JOptionPane.ERROR_MESSAGE);
            } else {
                System.out.println(((JComboBox) e.getSource())
                        .getSelectedItem());
            }
        }
    }

    protected void disableItemsInComboBox() {
        comboBox.removeActionListener(enabledListener);
        comboBox.addActionListener(disabledListener);
        model.setSelectionInterval(SELECTION_INTERVAL[0], SELECTION_INTERVAL[1]);
    }

    protected void enableItemsInComboBox() {
        comboBox.removeActionListener(disabledListener);
        comboBox.addActionListener(enabledListener);
        model.setSelectionInterval(SELECTION_INTERVAL[0], comboBox.getModel()
                .getSize() - 1);
    }

    private JCheckBox createCheckBox() {
        JCheckBox checkBox = new JCheckBox("diabled");
        checkBox.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    disableItemsInComboBox();
                } else if (e.getStateChange() == ItemEvent.DESELECTED) {
                    enableItemsInComboBox();
                }
            }
        });
        return checkBox;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new ComboBoxDisabledItemsDemo();
            }
        });
    }
}

答案 1 :(得分:0)

解决@Samsotha的代码"问题"在残疾人物品仍然可以选择的地方,我发现并改编了一个适用于此目的的代码。下面是一个工作示例,说明如何调用它并以类似于JComboBox的方式使用它:

import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicComboBoxRenderer;

/**
 * Creates a util class to generate a JComboBox with enabled/disabled items.
 * Strongly adapted from original post of Joris Van den Bogaert at http://esus.com/disabling-some-of-the-elements-in-a-jcombobox/
 */

@SuppressWarnings({ "unchecked" })
public class MyComboBox extends JComboBox<Object> {

private static final long serialVersionUID = 6975854742812751380L;

/**************************************************
 * FOR TESTING:
 */

public static void main(String[] args) throws Exception {

     // Way 1: load an array
     ConditionalItem[] arr = new ConditionalItem[] {
         new ConditionalItem("Item 0", false),
         new ConditionalItem("Item 1", false),
         new ConditionalItem("Item 2"),
         new ConditionalItem("Item 3", false),
         new ConditionalItem("Item 4", true)
     };
     MyComboBox combo = new MyComboBox(arr);

//      // Way 2: load oned by one (allows run-time modification)
//      MyComboBox combo = new MyComboBox();
//      combo.addItem("sss", false);
//      combo.addItem("ddd", true);
//      combo.addItem("eeee");

    // Way 3: initial load and oned by one on run-time
    combo.addItem("Item 5");
    combo.addItem("Item 6", false);
    combo.addItem("Item 7", true);

    JPanel panel = new JPanel(new FlowLayout());
    panel.add(new JLabel("Test:"));
    panel.add(combo);

    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setContentPane(panel);
    frame.pack();
    frame.setVisible(true);

    Thread.sleep(2*1000);
    combo.setItem("Item 2", false);

    Thread.sleep(2*1000);
    combo.setItem("Item 8", false);
}

/**************************************************
 * CONSTRUCTORS:
 */

ActionListener listener;

public MyComboBox() {
    this.setRenderer(new ConditionalComboBoxRenderer());
}

public MyComboBox(ConditionalItem[] arr) {
    for(ConditionalItem ci : arr) {
        this.addItem(ci);
    }
    this.setRenderer(new ConditionalComboBoxRenderer());
    listener = new ConditionalComboBoxListener(this);
    this.addActionListener(listener);
}

public void addItem(String str) {
    addItem(new ConditionalItem(str, true));
}

public void addItem(String str, boolean bool) {
    addItem(new ConditionalItem(str, bool));
}

public void addItem(Component ci) {
    this.add(ci);
    this.setRenderer(new ConditionalComboBoxRenderer());
    this.addActionListener(new ConditionalComboBoxListener(this));
}

/** if combobox contains "str", sets its state to "bool"; 
 *  if it's not yet an item, ignores it; 
 *  the method also re-sets the selected item to the first one 
 *  shown in the list as "true", and disables the listeners in this 
 *  process to avoid firing an action when reorganizing the list. 
 */
public void setItem(String str, boolean bool) {
    int n = this.getItemCount();
    for (int i=0; i<n; i++) {
        if(this.getItemAt(i).toString().equals(str)) {

            this.removeActionListener(listener);
            this.removeItemAt(i);
            this.insertItemAt(new ConditionalItem(str, bool), i);
            int k = this.firstTrueItem();
            if(k<0) k=0; // default index 0 if no true item is shown as true
            this.setSelectedIndex(k);
            this.addActionListener(listener);

            return;
        }
    }
    System.err.println("Warning: item "+ str +" is not a member of this combobox: ignoring it...");
}

public Object[] getItems() {
    int n = this.getItemCount();
    Object[] obj = new Object[n];
    for (int i=0; i<n; i++) {
        obj[i] = this.getItemAt(i);
    }
    return obj;
}

/** @return -1 if no item is true */
int firstTrueItem() {
    int i = 0;
    for(Object obj : this.getItems()) {
        if(((ConditionalItem) obj).isEnabled()) return i;
        i++;
    }
    return -1;
}
}

@SuppressWarnings("rawtypes")
class ConditionalComboBoxRenderer extends BasicComboBoxRenderer implements ListCellRenderer {

private static final long serialVersionUID = 8538079002036282063L;

@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
        boolean cellHasFocus) {
    if (isSelected) {
        setBackground(list.getSelectionBackground());
        setForeground(list.getSelectionForeground());

    } else {
        setBackground(list.getBackground());
        setForeground(list.getForeground());
    }

try {
    if (value != null && !((ConditionalItem) value).isEnabled()) {
        setBackground(list.getBackground());
        setForeground(UIManager.getColor("Label.disabledForeground"));
    }
} catch(Exception e) {
     e.printStackTrace();
}  finally {
    setFont(list.getFont());
    setText((value == null) ? "" : value.toString());
}
return this;
}
}

class ConditionalComboBoxListener implements ActionListener {

MyComboBox combobox;
Object oldItem;

ConditionalComboBoxListener(MyComboBox combobox) {
    this.combobox = combobox;
    combobox.setSelectedIndex(combobox.firstTrueItem());
    oldItem = combobox.getSelectedItem();
}

public void actionPerformed(ActionEvent e) {

    Object selectedItem = combobox.getSelectedItem();
    if (!((ConditionalItem) selectedItem).isEnabled()) {
        combobox.setSelectedItem(oldItem);
        System.err.println(selectedItem.toString());
    } else {
        oldItem = selectedItem;
        System.out.println(oldItem.toString());
    }
}
}

class ConditionalItem {

Object object;
boolean isEnabled;

ConditionalItem(Object object, boolean isEnabled) {
    this.object = object;
    this.isEnabled = isEnabled;
}

ConditionalItem(Object object) {
    this(object, true);
}

public boolean isEnabled() {
    return isEnabled;
}

public void setEnabled(boolean isEnabled) {
    this.isEnabled = isEnabled;
}

@Override
public String toString() {
    return object.toString();
}
}