How to load values into JComboBox,depending on selection from another JComboBox? - java

Here is my code:
JComboBox unity=new JComboBox();
unity.setBounds(430,280,140,25);
unity.addItem("Pakistan");
unity.addItem("China");
unity.addItem("America");
unity.addItem("Japan");
unity.addItem("Bangladesh");
unity.addItem("Srilanka");
unity.addItem("India");
unity.addItem("Turkey");
unity.addItem("UK");
unity.addItem("Afghanistan");
unity.addItem("Iran");
unity.addItem("Iraq");
unity.setEditable(true);
uy.add(unity);
JLabel city=new JLabel("City:");
city.setBounds(350,320,100,25);
city.setForeground(Color.BLACK);
uy.add(city);
JComboBox cety=new JComboBox();
cety.setBounds(430,320,140,25);
cety.addItem("");
uy.add(cety);
unity.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent olala){
if(unity.getSelectedItem().equals("Pakistan")){
cety.addItem("Lahore");
cety.addItem("Islamabad");
cety.addItem("Karachi");
cety.addItem("Rawalpindi");
cety.addItem("Faisalabad");
cety.addItem("Gujjranwala");
}
}
});
But when i run the program,the block of if statement did not do anything.
What should I do,if I want to Load Values into JComboBox, depending on selection from another JComboBox?

Actually, if you choose "China" first, then "Pakistan" again, and click on the down arrow of the cety combobox, you'll see the items.
You can easily debug and see when the method is called by adding a println like so,
...
unity.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent olala) {
// DEBUG
System.out.println("itemStateChanged(): item = " + olala.getItem());
...
You'll notice that itemStateChanged is called when you select a different item. If you start the program and see the comboboxes for the first time, they haven't changed state yet, the method hasn't been called, and cety is empty. You could make unity change state, by adding
unity.setSelectedIndex(1);
unity.setSelectedIndex(0);
at the end of your code. Alternatively, you could just move all the unity.addItem lines to after the addItemListener so adding the first item to the list will trigger the event.
You'll need to clear the items before adding new ones, or selecting a couple of items in unity will result in a long list in cety. If you need an empty string in the list, you need to move that statement here as well,
...
public void itemStateChanged(ItemEvent olala){
cety.removeAllItems();
cety.addItem("");
if (unity.getSelectedItem().equals("Pakistan")) {
cety.addItem("Lahore");
...
You could then use a switch instead of a ton of if statements, get the item from the event instead of unity, and get rid of the raw types:
JComboBox<String> unity = new JComboBox<>();
unity.setBounds(430, 280, 140, 25);
unity.setEditable(true);
uy.add(unity);
JLabel city = new JLabel("City:");
city.setBounds(350, 320, 100, 25);
city.setForeground(Color.BLACK);
uy.add(city);
JComboBox<String> cety = new JComboBox<>();
cety.setBounds(430, 320, 140, 25);
uy.add(cety);
unity.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent event) {
cety.removeAllItems();
cety.addItem("");
switch (event.getItem().toString()) {
case "Pakistan":
cety.addItem("Lahore");
cety.addItem("Islamabad");
cety.addItem("Karachi");
cety.addItem("Rawalpindi");
cety.addItem("Faisalabad");
cety.addItem("Gujjranwala");
break;
case "China":
cety.addItem("Beijing");
break;
// ...
}
}
});
unity.addItem("Pakistan");
unity.addItem("China");
unity.addItem("America");
unity.addItem("Japan");
unity.addItem("Bangladesh");
unity.addItem("Srilanka");
unity.addItem("India");
unity.addItem("Turkey");
unity.addItem("UK");
unity.addItem("Afghanistan");
unity.addItem("Iran");
unity.addItem("Iraq");
// This would be a workaround if you don't want to move the addItems:
// unity.setSelectedIndex(1);
// unity.setSelectedIndex(0);

Related

JComboBox returning double value

I started making a small application where the user is required to select their province from a combobox, I added an action listener to the combobox. I wanted to test the ActionListener so I just made it print what was selected to the console. For some reason it seems as though I am getting the value of the combobox returned twice. For example, I select "Alberta" on the combobox, "Alberta Alberta" is printed to the console. Anyone have any idea why this might be?
JComboBox comboProv = new JComboBox(provinces);
comboProv.setBounds(40, 79, 137, 24);
contentPane.add(comboProv);
comboProv.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
String selectedProv = (String)comboProv.getSelectedItem();
System.out.print(selectedProv);
}
});
You didn't add an ActionListener, you add a ItemListener, a ItemListener will be notified twice when the value changes, once for the ItemEvent.DESELECTED event and once for the ItemEvent.SELECTED.
If you're not interested in the change of selection simply use a ActionListener
comboProv.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String selectedProv = (String)comboProv.getSelectedItem();
System.out.print(selectedProv);
}
});
Which will only be notified once
Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
put this inside the listener.. It printed twice because it is called for selected and deselected.. so add this to filter
if (e.getStateChange() == ItemEvent.SELECTED) {
String selectedProv = (String)comboProv.getSelectedItem();
System.out.print(selectedProv);.
} else if(e.getStateChange() == ItemEvent.DESELECTED){
//Do any operations you need to do when an item is de-selected.
}

JTextField Update based on JComboBox Selection

I'm trying to build a form where one can fill in own's own values into a JTextField or rely a preset option which is depending on a selection from a JComboBox.
This is the JCombobox
String[] areas = new String [] {"Own Specifications", "SurveySample", "UK", "London", "Surrey"};
#SuppressWarnings({ "unchecked", "rawtypes" })
final JComboBox<String> selectedArea = new JComboBox(areas);
//selectedArea = new JComboBox<String>();
selectedArea.setModel(new DefaultComboBoxModel<String>(areas));
selectedArea.setBounds(282, 52, 164, 27);
contentPane.add(selectedArea);
And this is the JTextField
tenurePrivateRenters = new JTextField();
tenurePrivateRenters.setHorizontalAlignment(SwingConstants.CENTER);
tenurePrivateRenters.setText("Private Renters");
tenurePrivateRenters.setBounds(58, 213, 134, 28);
contentPane.add(tenurePrivateRenters);
Depending on the JComboBox Selection of the user, in a JTextField, the value is supposed to change, e.g. if Survey Sample is selected the JTextField should chance its value to 10.
I've tried the two following option:
selectedArea.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
// TODO Auto-generated method stub
Object selectedValue = selectedArea.getSelectedItem();
if(selectedValue.equals("Own Specifications")){
tenurePrivateRenters.setText("10");
System.out.println("Good choice!");
}
}
});
and
selectedArea.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent e){
#SuppressWarnings("unchecked")
JComboBox<String> selectedArea = (JComboBox<String>) e.getSource();
String selectedItem = (String) selectedArea.getSelectedItem();
if(selectedItem.equals("Own Specifications")){
tenurePrivateRenters.setText("10");
System.out.println("Good choice!");
}
}
}
);
}
But for both options nothing happens and the value of the JTextField remains on "Private Renters". Any idea's on where I'm going wrong?
In your itemStateChanged method, you have the following:
Object selectedValue = selectedArea.getSelectedItem();
The getSelectedItem method returns an Object. Then, you call that Object's equals method:
if(selectedValue.equals("Own Specifications")){
This will certainly always return false because the Object equals method is comparing an object of type String to an object of type Object.
Instead, if you want to compare selectedValue to a String:
String selectedValue = (String)selectedArea.getSelectedItem();
Then, the if statement should work as expected.
I have tried your code and it worked perfectly. Are you sure you are properly attaching those listeners to combobox BEFORE you try to change its value? Try to attach them right in the constructor to be sure.

Java - Adding tab to JTabbedPane causing StackOverflowError (Disabling a firing ChangeEvent?)

Hey StackOverflow community, I'm having a StackOverflow problem.
I'm having difficulty adding a new tab to my GUI's JTabbedPane container, when the [+] tab is selected. So far, whenever I click the [+] tab, new tabs are appended until a StackOverflowError occurs.
A new tab is added to the JTabbedPane when the following condition is true.
if(songPanel.getSelectedIndex()==songPanel.getTabCount()-1){
...
}
I've tried to revert back to the previously selected tab to avoid tabs being added repeatedly to the JTabbedPane, to no avail. When the ChangeEvent actuator is fired, does it stay on indefinitely? I haven't come across anything useful in the SE7 API.
Relevant code (non-compilable, excerpt from larger program. May be missing brackets, only because I copy-pasted excerpts of the code, and liable to make mistakes)
#Override
public void init(){
setLayout(new GridLayout(MAIN_LAYOUT_ROWS, MAIN_LAYOUT_COLUMNS));
add(renderPanel = new JScrollPane());
add(controlPanel = new JPanel());
add(colourPanel = new JPanel());
add(songPanel = new JTabbedPane());
//songPanel options
songPanel = new JTabbedPane();
songPanel.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
songPanel.addTab("#1", new JTextArea());
songPanel.addTab("+", null, new JLabel(), "+");
Container cp = getContentPane();
cp.add(BorderLayout.SOUTH, songPanel);
//integrate songPanel changeListener
songPanel.addChangeListener(new ChangeListener(){
#Override //Method called when selected tab changes
public void stateChanged(ChangeEvent e){
try {
if(songPanel.getSelectedIndex()==songPanel.getTabCount()-1){
addTab("songPanel");
}
} catch (StackOverflowError soe){soe.printStackTrace();}
}
});
//*************************************************************************
#Override
public void start(){
}
//*************************************************************************
private void addTab(String panelName){
System.out.println("ADDING TAB");
if(panelName.equals("songPanel")){
String tabName = ("#" + Integer.toString(songPanel.getTabCount()-1));
songPanel.insertTab(tabName, null, new JTextField(), tabName, songPanel.getTabCount()-2);
}
}
}
//**************************************************************************
}
I've tried:
Setting a revert index in the addTab() method, so the newest tab is selected (still results in StackOverflowError)
Note this line:
songPanel.getSelectedIndex()==songPanel.getTabCount()-1)
Both "songPanel.getSelectedIndex()" and "songPanel.getTabCount()-1)" are always equal, so condition is always true (causing the StackOverflowError)
Error message:
java.lang.StackOverflowError
at javax.swing.text.StyleContext$SmallAttributeSet.getAttributeNames(StyleContext.java:947)
at javax.swing.text.StyleContext$SmallAttributeSet.containsAttributes(StyleContext.java:973)
at javax.swing.text.StyleContext$SmallAttributeSet.equals(StyleContext.java:852)
at java.util.WeakHashMap.eq(WeakHashMap.java:282)
at java.util.WeakHashMap.get(WeakHashMap.java:379)
at java.util.Collections$SynchronizedMap.get(Collections.java:2031)
at javax.swing.text.StyleContext.getImmutableUniqueSet(StyleContext.java:520)
at javax.swing.text.StyleContext.addAttributes(StyleContext.java:340)
at javax.swing.text.AbstractDocument$AbstractElement.addAttributes(AbstractDocument.java:1985)
at javax.swing.text.AbstractDocument$AbstractElement.<init>(AbstractDocument.java:1777)
at javax.swing.text.AbstractDocument$LeafElement.<init>(AbstractDocument.java:2502)
at javax.swing.text.AbstractDocument$BidiElement.<init>(AbstractDocument.java:2674)
at javax.swing.text.AbstractDocument.<init>(AbstractDocument.java:149)
at javax.swing.text.AbstractDocument.<init>(AbstractDocument.java:109)
at javax.swing.text.PlainDocument.<init>(PlainDocument.java:90)
at javax.swing.text.PlainDocument.<init>(PlainDocument.java:80)
at javax.swing.text.DefaultEditorKit.createDefaultDocument(DefaultEditorKit.java:130)
at javax.swing.plaf.basic.BasicTextUI.installUI(BasicTextUI.java:799)
at javax.swing.JComponent.setUI(JComponent.java:655)
at javax.swing.text.JTextComponent.setUI(JTextComponent.java:338)
at javax.swing.text.JTextComponent.updateUI(JTextComponent.java:348)
at javax.swing.text.JTextComponent.<init>(JTextComponent.java:322)
at javax.swing.JTextField.<init>(JTextField.java:231)
at javax.swing.JTextField.<init>(JTextField.java:172)
at application.Analyzer.addTab(Analyzer.java:133)
at application.Analyzer.access$100(Analyzer.java:24)
at application.Analyzer$1.stateChanged(Analyzer.java:101)
at javax.swing.JTabbedPane.fireStateChanged(JTabbedPane.java:416)
at javax.swing.JTabbedPane$ModelListener.stateChanged(JTabbedPane.java:270)
at javax.swing.DefaultSingleSelectionModel.fireStateChanged(DefaultSingleSelectionModel.java:132)
at javax.swing.DefaultSingleSelectionModel.setSelectedIndex(DefaultSingleSelectionModel.java:67)
at javax.swing.JTabbedPane.setSelectedIndexImpl(JTabbedPane.java:616)
at javax.swing.JTabbedPane.insertTab(JTabbedPane.java:735)
at application.Analyzer.addTab(Analyzer.java:133)
at application.Analyzer.access$100(Analyzer.java:24)
.
.
.
Do you have any suggestions? I know it's kind of vague, but I'm really not sure what is going wrong.
Any suggestions?
Thanks.
Tyler
StackOverflow identifies an infinite recursion. So first thing is to find that recursion. In your case these are the lines of the stacktrace that identifies that recursion:
at application.Analyzer.addTab(Analyzer.java:133) at
application.Analyzer.access$100(Analyzer.java:24) at
application.Analyzer$1.stateChanged(Analyzer.java:101) at
javax.swing.JTabbedPane.fireStateChanged(JTabbedPane.java:416) at
javax.swing.JTabbedPane$ModelListener.stateChanged(JTabbedPane.java:270)
at
javax.swing.DefaultSingleSelectionModel.fireStateChanged(DefaultSingleSelectionModel.java:132)
at
javax.swing.DefaultSingleSelectionModel.setSelectedIndex(DefaultSingleSelectionModel.java:67)
at javax.swing.JTabbedPane.setSelectedIndexImpl(JTabbedPane.java:616)
at javax.swing.JTabbedPane.insertTab(JTabbedPane.java:735) at
application.Analyzer.addTab(Analyzer.java:133)
So when you insert a tab, it automatically triggers a change of selected tab which in turns calls your ChangeEventListener which will trigger the insertion of a tab etc...
So you have two simple solutions:
Use a flag (a boolean) that is set to true before you add the new tab and that you set back to false when you are done. In your condition to test if you need to add a tab, you also check that this flag is not true.
You remove your change listener from the JTabbedPane before you insert the tab and you put it back afterwards.
In both case, use a try/finally block to make sure to return to a consistent state.
UPDATED SOLUTION
Sorry, the previous solution is not working as expected. Here my updated one:
public class TabbedPaneTest {
private final static JButton ADD_NEW_TAB_BUTTON = new JButton();
private JFrame mainFrame;
private JTabbedPane tabbedPane;
public void run() {
mainFrame = new JFrame("Test JTabbedPane");
mainFrame.setSize(300, 400);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tabbedPane = new JTabbedPane();
tabbedPane.addTab("default new tab", new JLabel("this is a default tab"));
addNewTabButton();
tabbedPane.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
if (tabbedPane.getSelectedComponent() == ADD_NEW_TAB_BUTTON) {
tabbedPane.addTab("new tab", new JLabel("new tab label"));
addNewTabButton();
}
}
});
mainFrame.getContentPane().add(tabbedPane);
mainFrame.setVisible(true);
}
private void addNewTabButton() {
tabbedPane.remove(ADD_NEW_TAB_BUTTON);
tabbedPane.addTab("[+]", ADD_NEW_TAB_BUTTON);
}
public static void main(String[] params) {
TabbedPaneTest test = new TabbedPaneTest();
test.run();
}
}
The problem is that the changeListener is called after the adding once again with the + tab as the selected tab, causing the creation of a new tab, and so on.
a pretty simple solution could be just to add a bool flag as Guillaume Polet stated :
songPanel.addChangeListener(new ChangeListener(){
#Override //Method called when selected tab changes
public void stateChanged(ChangeEvent e){
try {
if(songPanel.getSelectedIndex()==songPanel.getTabCount()-1 && !adding){
adding = true;
addTab("songPanel");
adding = false;
}
} catch (StackOverflowError soe){soe.printStackTrace();}
}
});
The adding flag is a class field initialized to false, and indicates whether or not you are in progress of adding a tab.
Minor changes to the addTab to get everything to work:
private void addTab(String panelName){
System.out.println("ADDING TAB");
if(panelName.equals("songPanel")){
String tabName = ("#" + Integer.toString(songPanel.getTabCount()));
int index = songPanel.getTabCount()-1;
songPanel.insertTab(tabName, null, new JTextField(), tabName, index);
songPanel.setSelectedIndex(index);
}
}
I made a little change in code, making the active tab the newly created one, and the indexes where a bit off.
Hope this helps :)

JComboBox Selection Change Listener?

I'm trying to get an event to fire whenever a choice is made from a JComboBox.
The problem I'm having is that there is no obvious addSelectionListener() method.
I've tried to use actionPerformed(), but it never fires.
Short of overriding the model for the JComboBox, I'm out of ideas.
How do I get notified of a selection change on a JComboBox?**
Edit: I have to apologize. It turns out I was using a misbehaving subclass of JComboBox, but I'll leave the question up since your answer is good.
It should respond to ActionListeners, like this:
combo.addActionListener (new ActionListener () {
public void actionPerformed(ActionEvent e) {
doSomething();
}
});
#John Calsbeek rightly points out that addItemListener() will work, too. You may get 2 ItemEvents, though, one for the deselection of the previously selected item, and another for the selection of the new item. Just don't use both event types!
Code example of ItemListener implementation
class ItemChangeListener implements ItemListener{
#Override
public void itemStateChanged(ItemEvent event) {
if (event.getStateChange() == ItemEvent.SELECTED) {
Object item = event.getItem();
// do something with object
}
}
}
Now we will get only selected item.
Then just add listener to your JComboBox
addItemListener(new ItemChangeListener());
I would try the itemStateChanged() method of the ItemListener interface if jodonnell's solution fails.
Here is creating a ComboBox adding a listener for item selection change:
JComboBox comboBox = new JComboBox();
comboBox.setBounds(84, 45, 150, 20);
contentPane.add(comboBox);
JComboBox comboBox_1 = new JComboBox();
comboBox_1.setBounds(84, 97, 150, 20);
contentPane.add(comboBox_1);
comboBox.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent arg0) {
//Do Something
}
});
You may try these
int selectedIndex = myComboBox.getSelectedIndex();
-or-
Object selectedObject = myComboBox.getSelectedItem();
-or-
String selectedValue = myComboBox.getSelectedValue().toString();
I was recently looking for this very same solution and managed to find a simple one without assigning specific variables for the last selected item and the new selected item. And this question, although very helpful, didn't provide the solution I needed. This solved my problem, I hope it solves yours and others. Thanks.
How do I get the previous or last item?
you can do this with jdk >= 8
getComboBox().addItemListener(this::comboBoxitemStateChanged);
so
public void comboBoxitemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
YourObject selectedItem = (YourObject) e.getItem();
//TODO your actitons
}
}
I use this:
cb = new JComboBox<String>();
cb.setBounds(10, 33, 46, 22);
panelConfig.add(cb);
for(int i = 0; i < 10; ++i)
{
cb.addItem(Integer.toString(i));
}
cb.addItemListener(new ItemListener()
{
#Override
public void itemStateChanged(ItemEvent e)
{
if(e.getID() == temEvent.ITEM_STATE_CHANGED)
{
if(e.getStateChange() == ItemEvent.SELECTED)
{
JComboBox<String> cb = (JComboBox<String>) e.getSource();
String newSelection = (String) cb.getSelectedItem();
System.out.println("newSelection: " + newSelection);
}
}
}
});

Why is itemStateChanged on JComboBox is called twice when changed?

I'm using a JComboBox with an ItemListener on it. When the value is changed, the itemStateChanged event is called twice. The first call, the ItemEvent is showing the original item selected. On the second time, it is showing the item that has been just selected by the user. Here's some tester code:
public Tester(){
JComboBox box = new JComboBox();
box.addItem("One");
box.addItem("Two");
box.addItem("Three");
box.addItem("Four");
box.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent e){
System.out.println(e.getItem());
}
});
JFrame frame = new JFrame();
frame.getContentPane().add(box);
frame.pack();
frame.setVisible(true);
}
So when I changed the Combo box once from "One" to "Three" the console shows:
One
Three
Is there a way I can tell using the ItemEvent maybe, that it's the second item (ie. the user selected item)? And if someone can explain why it gets called twice, that would be nice too!
Thanks
Have a look at this source:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Tester {
public Tester(){
JComboBox box = new JComboBox();
box.addItem("One");
box.addItem("Two");
box.addItem("Three");
box.addItem("Four");
box.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent e){
System.out.println(e.getItem() + " " + e.getStateChange() );
}
});
JFrame frame = new JFrame();
frame.getContentPane().add(box);
frame.pack();
frame.setVisible(true);
}
public static void main(String [] args) {
Tester tester = new Tester();
}
}
Use the getStateChange to determine if an item is selected or deselected
According to this thread,
It gets tripped when you leave one result and then called again when set to another result
Don't listen for itemStateChanged. Use an ActionListener instead, which is good for handling events of the combo.
You need a ItemStateListener if you need to separately handle deselection / selection depending on the item involved.
Changing the state of the item within itemStateChanged causes itemStateChanged to be fired... this called "reentrance".
I wanted to get the index string after selected and set in combobox
comboBox1.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange() == ItemEvent.SELECTED) {
comboBox1ItemStateChanged();
}
}
});
Yo can do it like this:
import java.awt.event.*;
jComboBox1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Hello");
}
});
private void dropDown_nameItemStateChanged(java.awt.event.ItemEvent evt) {
if(evt.getStateChange() == ItemEvent.SELECTED)
{
String item = (String) evt.getItem();
System.out.println(item);
}
}
Good Luck!
The code is:
public class Tester {
private JComboBox box;
public Tester() {
box = new JComboBox();
box.addItem("One");
box.addItem("Two");
box.addItem("Three");
box.addItem("Four");
box.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == 1) {
JOptionPane.showMessageDialog(box, e.getItem());
System.out.println(e.getItem());
}
}
});
JFrame frame = new JFrame();
frame.getContentPane().add(box);
frame.pack();
frame.setVisible(true);
}
}
Have a look here,
box.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent e){
if(e.getStateChange()== ItemEvent.SELECTED) {
//this will trigger once only when actually the state is changed
JOptionPane.showMessageDialog(null, "Changed");
}
}
});
When you select a new option, it will only once call the JOptionPane, indicating that the code there will be called once only.
Quote from Java Tutorial:
"Only one item at a time can be selected in a combo box, so when the user makes a new selection the previously selected item becomes unselected. Thus two item events are fired each time the user selects a different item from the menu. If the user chooses the same item, no item events are fired."
When the anyitem is selected from the combo box, it internally triggers selection change, i.e. it will call the function setSelectedItem.
If an explicit itemStateChanged event listener is implemented, the setSelectedItem will call itemStateChanged. So, when an item is selected it calls setSelectedItem then it calls itemStateChanged.
As the value of the combo box changes, even that too triggers itemStateChanged and hence itemStateChanged gets called.
I had written listener for item change to handle change in value of combo box when set internally from the code and that caused the function getting called twice.
Here are the 2 back traces, which gets invoked when a value is selected from combo box.
1st time on actual value change:
dataMgr.MainInterface.jComboBoxPaymentStatusValueChangeHandle(MainInterface.java:1431),
dataMgr.MainInterface.jComboBoxPaymentStatusItemStateChanged(MainInterface.java:1676),
dataMgr.MainInterface.access$600(MainInterface.java:28),
dataMgr.MainInterface$7.itemStateChanged(MainInterface.java:437),
javax.swing.JComboBox.fireItemStateChanged(JComboBox.java:1223),
javax.swing.JComboBox.selectedItemChanged(JComboBox.java:1271),
javax.swing.JComboBox.contentsChanged(JComboBox.java:1330),
javax.swing.AbstractListModel.fireContentsChanged(AbstractListModel.java:118),
javax.swing.DefaultComboBoxModel.setSelectedItem(DefaultComboBoxModel.java:93),
javax.swing.JComboBox.setSelectedItem(JComboBox.java:576), javax.swing.JComboBox.setSelectedIndex(JComboBox.java:622), javax.swing.plaf.basic.BasicComboPopup$Handler.mouseReleased(BasicComboPopup.java:852), java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:290), java.awt.Component.processMouseEvent(Component.java:6533), javax.swing.JComponent.processMouseEvent(JComponent.java:3324), javax.swing.plaf.basic.BasicComboPopup$1.processMouseEvent(BasicComboPopup.java:501), java.awt.Component.processEvent(Component.java:6298), java.awt.Container.processEvent(Container.java:2236), java.awt.Component.dispatchEventImpl(Component.java:4889), java.awt.Container.dispatchEventImpl(Container.java:2294), java.awt.Component.dispatchEvent(Component.java:4711), java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888), java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525), java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466), java.awt.Container.dispatchEventImpl(Container.java:2280), java.awt.Window.dispatchEventImpl(Window.java:2746), java.awt.Component.dispatchEvent(Component.java:4711), java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758), java.awt.EventQueue.access$500(EventQueue.java:97), java.awt.EventQueue$3.run(EventQueue.java:709), java.awt.EventQueue$3.run(EventQueue.java:703), java.security.AccessController.doPrivileged(Native Method), java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76), java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86), java.awt.EventQueue$4.run(EventQueue.java:731), java.awt.EventQueue$4.run(EventQueue.java:729), java.security.AccessController.doPrivileged(Native Method), java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76), java.awt.EventQueue.dispatchEvent(EventQueue.java:728), java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201), java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116), java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105), java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101), java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93), java.awt.EventDispatchThread.run(EventDispatchThread.java:82)]
2nd time from the due to operation on combobox
dataMgr.MainInterface.jComboBoxPaymentStatusValueChangeHandle(MainInterface.java:1431),
dataMgr.MainInterface.jComboBoxPaymentStatusItemStateChanged(MainInterface.java:1676),
dataMgr.MainInterface.access$600(MainInterface.java:28),
dataMgr.MainInterface$7.itemStateChanged(MainInterface.java:437),
javax.swing.JComboBox.fireItemStateChanged(JComboBox.java:1223),
javax.swing.JComboBox.selectedItemChanged(JComboBox.java:1280),
javax.swing.JComboBox.contentsChanged(JComboBox.java:1330),
javax.swing.AbstractListModel.fireContentsChanged(AbstractListModel.java:118),
javax.swing.DefaultComboBoxModel.setSelectedItem(DefaultComboBoxModel.java:93),
javax.swing.JComboBox.setSelectedItem(JComboBox.java:576),
javax.swing.JComboBox.setSelectedIndex(JComboBox.java:622),
javax.swing.plaf.basic.BasicComboPopup$Handler.mouseReleased(BasicComboPopup.java:852),
java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:290),
java.awt.Component.processMouseEvent(Component.java:6533),
javax.swing.JComponent.processMouseEvent(JComponent.java:3324),
javax.swing.plaf.basic.BasicComboPopup$1.processMouseEvent(BasicComboPopup.java:501),
java.awt.Component.processEvent(Component.java:6298), java.awt.Container.processEvent(Container.java:2236),
java.awt.Component.dispatchEventImpl(Component.java:4889), java.awt.Container.dispatchEventImpl(Container.java:2294),
java.awt.Component.dispatchEvent(Component.java:4711), java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888),
java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525), java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466),
java.awt.Container.dispatchEventImpl(Container.java:2280), java.awt.Window.dispatchEventImpl(Window.java:2746),
java.awt.Component.dispatchEvent(Component.java:4711), java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758),
java.awt.EventQueue.access$500(EventQueue.java:97), java.awt.EventQueue$3.run(EventQueue.java:709),
java.awt.EventQueue$3.run(EventQueue.java:703), java.security.AccessController.doPrivileged(Native Method),
java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76),
java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86),
java.awt.EventQueue$4.run(EventQueue.java:731), java.awt.EventQueue$4.run(EventQueue.java:729),
java.security.AccessController.doPrivileged(Native Method), java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76), java.awt.EventQueue.dispatchEvent(EventQueue.java:728), java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201), java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116), java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105), java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101), java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93), java.awt.EventDispatchThread.run(EventDispatchThread.java:82)]
JComboBox.setFocusable(false) will do the trick.

Categories