当前位置: 首页 > 知识库问答 >
问题:

如何禁用 JComboBox 中的某些项目

锺英卫
2023-03-14

我有一个组合框,其中有8个项目,我想显示其中的所有项目,但在特定条件下,用户只能选择前两个项目,因此我编写了html" target="_blank">程序,如果条件为真,用户选择任何其他选项,则会显示一个消息框,显示“您无法选择此”然后自动选择默认值。到现在为止,一直都还不错。

但现在的问题是,用户无法通过查看JComboBox的选项来判断他可以选择哪些选项,因此我想做的是,如果条件为真,那么除前两个选项之外的所有选项都应该被禁用(或灰显或其他),这样用户就可以判断出您无法选择它,如果他们仍然选择,那么我的消息框就会出现。

我尝试了什么:我试着查找这个,但是我不知道问题中做了什么(它的答案对我没有用),我也尝试了其他选择,但是没有成功。

注意:我使用Netbeans GUI来创建一切,我正在编写的代码在< code > jcomboboxationperformed 上,我是一个新手,所以我不能理解我自己,对此表示歉意

共有2个答案

白云
2023-03-14

为了解决@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();
}
}
慕容俭
2023-03-14

这将需要一些手工编码。GUI生成器在这里帮不了你。

您可以实现您自己的BasicComboBoxRenler,在其中您将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;
    }
}

您可以使用两个独立的侦听器。一个用于项目启用时,一个用于项目禁用时。启用这些项目后,您可以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]);
}

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

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();
            }
        });
    }
}
 类似资料:
  • 这是一个相当普遍的问题,我用过的解决方案和我后来搜索发现的差不多。其中一个实现了带有< code>JLabel的< code>ListCellRenderer,它根据当前选择的索引启用或禁用自身: 问题是,尽管列表项在视觉上显示为禁用,但尽管调用了< code>setFocusable,它仍然可以被选中。我该如何禁用它?

  • 问题内容: 如何禁用Android虚拟键盘中的某些键(例如数字/符号键)? 具体来说,当用户将焦点放在标准android EditText小部件上时,当虚拟键盘显示时,我希望用户不能输入双引号(“)字符。 问题答案: 如何禁用Android虚拟键盘中的某些键(例如数字/符号键)? 你不能,对不起。毕竟,输入法编辑器可能首先没有“键”。 具体来说,当用户将焦点放在标准android EditText

  • 1.我创建了一个JComboBox和Jtable。当用户从JComboBox中选择项目时,它们被添加到Jtable中 2.我不想让用户选择他以前在JComboBox中选择的项目 3.因此必须禁用选定的选项(不可选择)。我该怎么做?4.下面的代码在添加到JTable中后从JComboBox中删除该选定项,但我有兴趣禁用它

  • 我想禁用一个场景的当前日期和其他场景的未来日期时,是否可以禁用日期。我应该如何禁用日期?

  • 在我们的组织中,我们有几个微服务和许多库。 有些库定义的“public”类不用于公共用途-仅在多个包中的库内部(因此不能是包私有的) 我想添加一些类似于Kotlin的“内部”修饰符的东西——一个检查风格规则/注释处理器/测试组件,用于验证消费者应用程序没有导入这些类。 例如,我将它们标记为@ForInternalUsageOnly或放入包com中。奥罗格。迈里布。内部使用 什么是非复制粘贴的(例如

  • 问题内容: 我使用PHP库生成一些图像。 有时浏览器不会加载新生成的文件。 如何仅为我动态创建的图像禁用缓存? 注意:随着时间的推移,我必须对创建的图像使用相同的名称。 问题答案: 对于这个问题,一种常见而简单的解决方案是给每个对动态图像的请求添加一个随机生成的查询字符串,这种解决方案看起来很像黑客,但移植性很强。 因此,例如- 会成为 要么 从Web服务器的角度来看,可以访问同一文件,但是从浏览