0

I am trying to change JCombobox items list (towns) depending on the value of the other JCombobox (city). When I change the value in the city list, it changes the items in the towns list. But there are 2 issues.

  1. The updated list (towns) shows double of the items but when click on it then it shows the correct number of items as shown in the first screenshot.
  2. The updated list doesn't allow me to choose one of the item, it only select the first item

a

here is my code:

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

import javax.swing.*;   
public class Testing extends JFrame implements ActionListener {
    
    public static void main(String[] args )
    {
    new Testing();
    }
    JComboBox cb,cb1,cb2;
    JFrame f; 
    JLabel label1,label2;
    JButton b1;
    JTextField name,ID,birth;
    
    
 Testing(){    
        f=new JFrame("Information Example");  
        label1 = new JLabel("Please input your information below");
        label1.setBounds(10, 20, 260, 30);
      f.add(label1);
        String question[]={"Calculate my Age","When do I drive","When do I vote"};
        String city[]={"Asimah","Ahmadi","Hawalli"};
       
               
         name= new JTextField("NAME");
        name.setBounds(10,50,264,25);
        f.add(name);
         ID= new JTextField("CIVIL ID");
        ID.setBounds(10,80,264,25);
        f.add(ID);
         birth= new JTextField("DATE OF BIRTH");
        birth.setBounds(10,110,264,25);
        f.add(birth);
        cb=new JComboBox(question);    
        cb.setBounds(50, 150,180,20);    
        f.add(cb);
        b1= new JButton("Get");
        b1.setBounds(100,250,60,20);
        f.add(b1);
        cb1=new JComboBox(city);    
        cb1.setBounds(10, 200,120,20);    
        f.add(cb1);
        cb2=new JComboBox();    
        cb2.setBounds(150, 200,120,20);    
        f.add(cb2);
     
        f.setLayout(null);    
        f.setSize(300,400);    
        f.setVisible(true);
        cb.addActionListener(this);
        cb1.addActionListener(this);
        cb2.addActionListener(this);
}
 @Override
 public void actionPerformed(ActionEvent event)
 {
     if(cb1.getSelectedIndex() == 0)
     {
         cb2.removeAllItems();
        
         cb2.addItem("Rawdhah");
         cb2.addItem("Abdahll");
     }
     else if(cb1.getSelectedIndex() == 1)
     {
        
         cb2.removeAllItems();
         cb2.addItem("Siddiq");
         cb2.addItem("Aljabryha");
     }
     else
     {
         cb2.removeAllItems();
         cb2.addItem("Fintas");
         cb2.addItem("Abdahll");
     }
     
 }
}
TT.
  • 15,774
  • 6
  • 47
  • 88
Saleh Refaai
  • 689
  • 3
  • 14
  • 25
  • Your `ActionListener` is been triggered twice, once for `cb1` and once for `cb2. `cb2` is trigger a `ActionEvent` because the `addItem` is changing the selected item, so, you `addItem`s, event is triggered and you add two new items, and then you add two more items. It's not getting into a infinite loop, because the second item you add doesn't change the selected item - because the first item is now selected – MadProgrammer Sep 14 '20 at 22:47
  • Here is an approach that changes the model: https://stackoverflow.com/questions/4982260/binding-comboboxes-in-swing/4982576#4982576. It will also support changing the model for unlimited number of cities without using nested if/else statements. – camickr Sep 14 '20 at 22:53
  • 2
    Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). – Andrew Thompson Sep 14 '20 at 23:27

1 Answers1

1

So, basically, the combination of removeAllItems and addItem is causing the JComboBox to generate a ActionEvent, but only for the first new item added.

You should isolate your functionality to only perform certain actions based on the source of the event, for example...

@Override
public void actionPerformed(ActionEvent event) {
    if (event.getSource() == cb1) {
        if (cb1.getSelectedIndex() == 0) {
            cb2.removeAllItems();

            System.out.println(cb2.getItemCount());

            cb2.addItem("Rawdhah");
            cb2.addItem("Abdahll");
        } else if (cb1.getSelectedIndex() == 1) {

            cb2.removeAllItems();
            cb2.addItem("Siddiq");
            cb2.addItem("Aljabryha");
        } else {
            cb2.removeAllItems();
            cb2.addItem("Fintas");
            cb2.addItem("Abdahll");
        }
    }
}

You could also make use of the actionCommand property, but the above is the simpler, immediate solution

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366