两个 JComboBoxes 用户不能选择相同的值

Two JComboBoxes user can't choose same value

我有两个 JComboBox。第一个模型具有元素 "one"、"two"、"three",第二个模型具有元素 "three"、"four"。而当用户在第一个JComboBox中选择元素"three"时,他不能在第二个JComboBox中选择元素"three"。相反 - 当用户在第二个 JComboBox 中选择元素 "three" 时,他不能在第一个 CB 中选择相同的元素。我如何在 Java 中执行此操作?

感谢您的解答。 还有一个问题。当我动态创建 ComboBoxes(当有人单击按钮时 - 在按钮 actionListener 中),并且每个新的 ComboBox 都有相同的模型 - 相同的元素列表。我怎样才能检查这个案例?和 Blip 说的一样?

我认为您可以将 ItemListener 添加到 2 JComboBox。如果用户 select 在任何 JComboBox 中使用对象 "three",则可以从另一个 JComboBox 的模型中删除对象 "three"。如果用户在一个 JComboBox 中删除 select 对象 "three",那么对象 "three" 可以添加到另一个 JComboBox 的模型中。

您可以通过以下方式实现:

  1. 让两个 JComboBox 存储在变量 box1box2 中,可以实现为:

    JComboBox<String> box1 = new JComboBox<>(new String[]{"one", "two", "three"});
    JComboBox<String> box2 = new JComboBox<>(new String[]{"three", "four"});
    
  2. 现在将 itemListener 添加到这两个 JComboBox 并将其传递给方法 boxItemSelected:

    box1.addItemListener(new ItemListener(){
    
        itemStateChanged(ItemEvent e){
            boxItemSelected(e);
        }
    });
    box2.addItemListener(new ItemListener(){
    
        itemStateChanged(ItemEvent e){
            boxItemSelected(e);
        }
    });
    
  3. 现在实施boxItemSelected(e)

    void boxItemSelected(ItemEvent e){
    
        //Check the item selected/deselected is "three" else do nothing.
        if (e.getItem().equals("three")){ 
    
        //Find the box on which this action was not performed to change its model.
            JComboBox<String> oppositeBox;
            if(e.getSource().equals(box1)){
                oppositeBox = box2;
            }else{
                oppositeBox = box1;
            }
    
        //Check the item is selected or deselected to remove or add "three" to item list.
            if(e.getStateChange() == ItemEvent.SELECTED){
                oppositeBox.removeItem("three");
            }else{
                oppositeBox.addItem("three");
            }
        }
    }
    

附加信息

在这里,如果您有超过 1 个重叠的项目并且只能 selected 一个 JComboBox,可以对方法 boxItemSelected 稍作修改您的问题如下图所示:

将上面代码中的行更改为:

if (e.getItem().equals("three"))

if (e.getItem().equals("three") || e.getItem().equals("<new item>") || ....)

并改变

oppositeBox.removeItem("three");
oppositeBox.addItem("three");

oppositeBox.removeItem(e.getItem());
oppositeBox.addItem(e.getItem());

在任何情况下,用户都不能 select 两个 JComboBox 中的相同项目。所有这些都发生在幕后,用户使用用户界面并不知情。

When i dynamically create ComboBoxes (when someone clicked the button - in button actionListener), and every new ComboBox has same model - same list of elements. How can i check this case ? Same like Blip said ?

针对上述问题,我正在考虑所有 JComboBox 中的所有项目都相同并存储在 List 变量中,如果 1 项被 selected JComboBox 中的任何一项,则无法在 JComboBox 的其余部分中 select 编辑该项目。如果我的假设是正确的,那么我建议您执行以下操作:

  1. 创建一个List<JComboBox<?>> say boxes并初始化如下:

    List<JComboBox<?>> boxes = new ArrayList<>();
    
  2. 在你的 JButton(动态 JComboBox 的按钮)变量的 ActionListener 实现中创建一个变量说 items 作为 List 存储 JComboBox 的项目并添加项目

    List<String> items = new Vector<>();
    items.add("One");
    items.add("Two");
    ......
    
  3. 现在从 items 变量中删除在其他 JComboBox 中 select 动态生成的项目:

       Iterator<JComboBox<?>> iterator = boxes.iterator();
       while(iterator.hasNext()){
           JComboBox<?> existing = iterator.next();
           items.remove(existing.getSelectedItem());
       }
    
  4. 现在在 JComboBox 实例初始化后说 boxbox 的模型设置为先前初始化和修剪的 List 变量 items

    box.setModel(new DefaultComboBoxModel(items));
    
  5. 现在将JComboBox变量box添加到List变量boxes:

    boxes.add(box);
    
  6. 也在上面提到的 ActionListener 实现中添加 ItemListenerboxJComboBox 的新实例化变量并将其传递给方法 boxItemSelected:

    box.addItemListener(new ItemListener(){
    
        itemStateChanged(ItemEvent e){
            boxItemSelected(e);
        }
    });
    
  7. 现在必须更改 boxItemSelected 的实施以适应更改:

    void boxItemSelected(ItemEvent e){
    
        //Create an iterator to iterate over the boxes 
        Iterator<JComboBox<?>> iterator = boxes.iterator();
    
        while(iterator.hasNext()){
    
            //Get the current instance of comboBox from the list
            JComboBox<?> current = iterator.next();
    
            //If the box in which the select or de-select 
            //event has occurred is the current comboBox then do nothing.
            if(e.getSource().equals(current)(
                continue;
            }
    
            //If the event is select then remove the Item from the 
            //current comboBox else add the Item to the current comboBox.
            if(e.getStateChange() == ItemEvent.SELECTED){
                current.removeItem(e.getItem());
            }else{
                current.addItem(e.getItem());
            }
        }
    }
    

您可以使用组合框的模型,但更简单的方法是在用户要求程序接受值时检查所选值,可能是在 JButton 的 ActionListener 中,然后如果两个相同的值已被选中,取消选中它们并使用 JOptionPane 警告用户。或者,您可以将侦听器(Actionlistener 或 ItemListener)中的代码添加到两个 JComboBox,以检查另一个组合框的选定值以确保它们不相同,如果是,则警告用户并取消选择错误的选择。

所以这绝对是可能的。我认为最好的方法是检查两个框的选定索引,然后根据该索引值的结果执行您的逻辑。在下面的示例中,您可以看到该演示。发生的事情是 ComboBox1 和 2 上有一个 ActionListener。如果值匹配,我使用索引,但您也可以获取字符串值以确保它们不匹配。

public class SOF extends JFrame {
private JPanel mainPanel, comboPanel;
private JComboBox jcb1, jcb2;

public SOF()
{
    super("Combo Box Example");
    mainPanel = new JPanel();
    mainPanel.add(configureCombo());
    add(mainPanel);
    setSize(200,200);
    setLocationRelativeTo(null);
    setVisible(true);


    jcb1.addActionListener(new ActionListener() {
       @Override
       public void actionPerformed(ActionEvent e)
       {
           //You can replace this with, jcb2.getSelectedItem if you don't know the indexes or if they will be random. 
           if((jcb1.getSelectedIndex() == 2) && (jcb2.getSelectedIndex() == 0))
           {
               JOptionPane.showMessageDialog(null, "Cannot select 3 in both field.");
               jcb1.setSelectedIndex(-1);
               jcb2.setSelectedIndex(-1);
           }
            //ANOTHER OPTION
           If((jcb1.getSelectedValue().equals("three") && (jcb2.getSelectedValue().equals("three")
           {
            LOGIC
           }
       }
    });

    jcb2.addActionListener(new ActionListener() {
       @Override
       public void actionPerformed(ActionEvent e)
       {
           //You can replace this with, jcb2.getSelectedItem if you don't know the indexes or if they will be random. 
           if((jcb2.getSelectedIndex() == 0) && (jcb1.getSelectedIndex() == 2))
           {
               JOptionPane.showMessageDialog(null, "Cannot select 3 in both field.");
               jcb1.setSelectedIndex(-1);
               jcb2.setSelectedIndex(-1);
           }
       }
    });


}

private JPanel configureCombo()
{
    String[] cb1List = {"one", "two", "three"};
    String[] cb2List = {"three", "four"};
    comboPanel = new JPanel(new GridLayout(1,2));
    jcb1 = new JComboBox(cb1List);
    jcb2 = new JComboBox(cb2List);
    comboPanel.add(jcb1);
    comboPanel.add(jcb2);
    return comboPanel;
}
/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    SOF s = new SOF();
}

}

如果选择了匹配框,则在任一组合框上都会弹出错误消息并取消选择两个组合框。