Search code examples
javaswingjcheckbox

Java Swing Showing Button 2X for 1 Click - Why? 0_o


I coded a Java Swing component that shows a button twice when it is clicked. However, I only want the button to appear once when clicked. My code is below. Does anyone know what I am missing?

import java.awt.event.*;



public class checkIt2 implements ItemListener { 

    public void itemStateChanged(ItemEvent e) { 


   if(e.getStateChange() == ItemEvent.SELECTED) { 



         javax.swing.JOptionPane.showMessageDialog(null, "Check box 2 is selected");
         JDBC_Demo6.check2.setSelected(true);


    } 

    if (e.getStateChange() == ItemEvent.DESELECTED) { 

        JDBC_Demo6.check1.setSelected(false);
    }




    }

}

Here is the code in the JDBC_Demo6 class that pertains to the JCheckBox ItemListener class:

    public class JDBC_Demo6 extends JFrame implements ActionListener {

    public static JTextArea textArea;
    static String critical_data; 
    private final static String newline = "\n";
    public static JCheckBox check1;
    public static JCheckBox check2;



public JDBC_Demo6(String s) {
    super(s);

}

public void addComponentsToPane(final Container pane) { 

    textArea = new JTextArea(20, 75);

   /* final JPanel compsToExperiment = new JPanel(new GridBagLayout()); */

    // GridBagConstraint for button 
    /* This puts the buttons in the very center of the GUI */




    //get Database data 
    JsonDB a = new JsonDB();

    //store the output from the getDB method in this ArrayList collection 
    ArrayList<String> tmp = a.getDB();

    //loop through the ArrayList and append each string to the text area
    JScrollPane scrollPane = new JScrollPane();
    //add a scrollpane to the GUI
    //scrollPane.setSize(new Dimension(100, 100));


    /* loop through the ArrayList with the results of the SQL query and then add them to the JPanel  */
    for(String s: tmp) {

        textArea.append("From the database -> " + s + "\n");
    }


    scrollPane.setViewportView(textArea);
    this.add(scrollPane);
    scrollPane.updateUI();

    /* add buttons */ 
    JButton jB = new JButton("Send To ESB");
    JButton jB2 = new JButton("Cancel");

    jB.addActionListener(new goButton());
    jB2.addActionListener(new cancelButton());
    this.add(jB);
    this.add(jB2);

    /* check boxes */ 
    check1 = new JCheckBox("Check Box 1");
    check2 = new JCheckBox("Check Box 2");

    check1.addItemListener(new checkIt());
    check2.addItemListener(new checkIt2());

    this.add(check1);
    this.add(check2);



}



/**
 * Create the GUI and show it.  For thread safety,
 * this method should be invoked from the
 * event dispatch thread.
 */
private static void createAndShowGUI() {
    //Create and set up the window.
    JDBC_Demo6 frame = new JDBC_Demo6("JDBC Example #6");
    frame.setSize(50, 50);
    frame.setLayout(new FlowLayout());
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //Add contents to the window.
    frame.addComponentsToPane(frame.getContentPane());

    //Display the window.
    frame.pack();
    frame.setVisible(true);
}

public static void main(String[] args) {
    //Schedule a job for the event dispatch thread:
    //creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });
}

public void actionPerformed(ActionEvent ae) { 

}

} // end class 

Solution

  • It is happening twice because the call JDBC_Demo6.check1.setSelected(true); triggers another call to ItemListener.itemStateChanged(). In this case it would be easier to use an ActionLister or a ChangeLister instead of an ItemListener, like in the code that follows. Although the call JDBC_Demo6.check1.setSelected(true); wont trigger another ActionListener.actionPerformed(), like it does for ItemListeners, the call is redundant and you should remove it.
    Test this ActionListener to see if it works for you:

        public class checkIt2 implements ActionListener { 
    
            @Override
            public void actionPerformed(ActionEvent e) {
                javax.swing.JOptionPane.showMessageDialog(null, "selected: " +
                        ((JCheckBox)e.getSource()).isSelected());
            }
    
        }
    

    And use this to register the listener:

        check2.addActionListener(new checkIt2());