0

I've got 6 comboboxes using the same DefaultListModel with 6 elements. I use an ActionListener so that when one of the comboboxes selects an element from the list that another combobox has selected they swap the who has selected the elements. AKA, combobox 1, which had element 1 selected, selects element 2, which combobox 3 had selected, and after the listener runs combobox 3 will have element 1 selected.

ActionListener abilCBListener = new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent evt){
        JComboBox cb = (JComboBox)evt.getSource();
        int ind = abilCBArray.indexOf(cb);
        int num = 15;
        int dup = 7;

        if(abilCBArray.size() == 6 && abilCBBoo == true){
            abilCBBoo = false;// prevents another combobox's listener from firing
            for(int i = 0; i < abilCBArray.size();i++){
                //System.out.println("i = " + i + " index = "+abilCBArray.get(i).getSelectedIndex());
                if(i != ind){
                    num -= abilCBArray.get(i).getSelectedIndex();
                    System.out.println("i = "+ i+" num = "+ num+ " Index = "+abilCBArray.get(i).getSelectedIndex() );
                    if(abilCBArray.get(i).getSelectedIndex() == cb.getSelectedIndex()){
                        dup = i;
                    } 
                }
            }
            if(num < abilCBArray.size() && dup != 7){
                abilCBArray.get(dup).setSelectedIndex(num);
            }
        }else{
            System.out.println("Tried to run abilCBArrayChange without full array");            
        }          
        abilCBBoo = true;
    }
};

The problem is the user can put a random set of numbers into the DefaultListModel and if any of the numbers are the same, the comboboxes will select the index of the first instance of the number which messes up my ActionListener. Everything I read seems to indicate that you have to make each item in the list unique to get around the combobox selection problem and I still won't be able to use getSelectIndex() because if I do that as it will still return the first instance of the number.

Richard
  • 1
  • 1

3 Answers3

3

@camickr

import java.awt.event.ActionEvent;
import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Vector;

public class TestDuplicatesItems {

    private Vector<String> vec = new Vector<String>();
    private String[] degrees = {"AAS1", "AAS2", "AAS1", "AAS1"};
    private JComboBox combo = new JComboBox(vec);
    private JComboBox combo1 = new JComboBox(degrees);
    private JTextField txt = new JTextField(10);
    private JFrame frame = new JFrame("JComboBox with Duplicates Items");
    private JPanel panel = new JPanel();

    public TestDuplicatesItems() {
        vec.add("AAS1");
        vec.add("AAS1");
        vec.add("AAS1");
        vec.add("AAS1");
        //combo.setEditable(true);
        //combo.setBackground(Color.gray);
        //combo.setForeground(Color.red);        
        //combo.setEditable(true);
        //combo1.setBackground(Color.gray);
        //combo1.setForeground(Color.red);        
        txt.setText("1");
        combo.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println(combo.getSelectedIndex());
                System.out.println(combo.getSelectedItem().toString());
                txt.setText(String.valueOf(combo.getSelectedIndex()));
            }
        });
        combo1.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(ItemEvent e) {
                if ((e.getStateChange() == ItemEvent.SELECTED)) {
                    System.out.println(combo1.getSelectedIndex());
                    System.out.println(combo1.getSelectedItem().toString());
                    txt.setText(String.valueOf(combo1.getSelectedIndex()));
                }
            }
        });
        panel.add(combo);
        panel.add(combo1);
        panel.add(txt);
        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                TestDuplicatesItems tdi = new TestDuplicatesItems();
            }
        });
    }
}

and based on primitive array

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicComboBoxRenderer;

public class SelectedComboBoxID {

    private JComboBox combo = new JComboBox();
    private JFrame frame = new JFrame("MyComboEg");
    private JTextField txt = new JTextField(10);
    private JPanel panel = new JPanel();

    public SelectedComboBoxID() {
        combo.addItem(new Item(1, "-"));
        combo.addItem(new Item(2, "Snowboarding"));
        combo.addItem(new Item(3, "Rowing"));
        combo.addItem(new Item(4, "Knitting"));
        combo.addItem(new Item(5, "Speed reading"));
        combo.addItem(new Item(6, "Pool"));
        combo.addItem(new Item(7, "None of the above"));
        //comboBox.setMaximumRowCount(3);
        combo.setPrototypeDisplayValue(" None of the above ");
        combo.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                JComboBox comboBox = (JComboBox) e.getSource();
                Item item = (Item) comboBox.getSelectedItem();
                System.out.println(item.getId() + " : " + item.getDescription());
                txt.setText(String.valueOf(combo.getSelectedIndex()));
            }
        });
        //comboBox.setRenderer(new ItemRenderer());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        panel.add(combo);
        panel.add(txt);
        frame.add(panel);
        frame.pack();
        //frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private class ItemRenderer extends BasicComboBoxRenderer {

        private static final long serialVersionUID = 1L;

        @Override
        public Component getListCellRendererComponent(JList list, Object value,
                int index, boolean isSelected, boolean cellHasFocus) {
            super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            if (value != null) {
                Item item = (Item) value;
                setText(item.getDescription().toUpperCase());
            }
            if (index == -1) {
                Item item = (Item) value;
                setText("" + item.getId());
            }
            return this;
        }
    }

    private class Item {

        private int id;
        private String description;

        public Item(int id, String description) {
            this.id = id;
            this.description = description;
        }

        public int getId() {
            return id;
        }

        public String getDescription() {
            return description;
        }

        @Override
        public String toString() {
            return description;
        }
    }

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

            @Override
            public void run() {
                SelectedComboBoxID selectedComboBoxID = new SelectedComboBoxID();
            }
        });
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
1

You can call the Method getSelectedItem(). It will return the selected value.

JComboBox has an underlying ComboBoxModel. You can set the type of it at its declaration.

 JComboBox<String> j = new JComboBox();

So this comboBox uses Strings as its model. When you want to get the selected Item you can call:

 j.getSelectedItem()

and you will get the selected String from it. If you call

 j.getSelectedIndex()

you will get the index of the selected String in the model and you have to map it back, to get the selected value. Hence getSelectedItem() is the right way to proceed.

Stimpson Cat
  • 1,444
  • 19
  • 44
1

I've got 6 comboboxes using the same DefaultListModel with 6 elements.

If a combo box shares the same model, then when you make a selection in one combo box, all combo boxes will be updated with the same selection.

You need to create 6 different DefaultListModels with each model containing the same data.

, the comboboxes will select the index of the first instance of the number

The problem is that the "select item" is stored in the combo box model, not the index of the selected item.

When you invoke the `getSelectedIndex() method, it iterates through all the items in the model until it finds an object that equals the selected object.

If the object added to the model implements the equals method, this will always be the first object found.

So the solution is to create a custom object to be stored in the model.

See the answer provided by @mKorbel.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • AFAIK it must be based on primitive array, otherwise never works correctly, bug or feature from Java6, – mKorbel May 16 '17 at 17:35
  • please to see my code explanation posted here as an answer – mKorbel May 16 '17 at 17:53
  • Here's how I got around the comboboxes selecting the same item with just 1 set of data [link](http://stackoverflow.com/questions/18171992/populate-multiple-combobox-with-same-model-but-select-diff) – Richard May 17 '17 at 01:55
  • @Richard, Yes, 1 set of data and 6 models is fine, but that is not what your original question stated. That is why I made the comment that you need 6 different models. – camickr May 17 '17 at 02:11