JCheckbox changes state twice when I show a dialog on statechange, how to fix?
Asked Answered
M

3

7

I have a checkbox that, when the user selects it, should spawn a dialog with further info, and upon reaction from the user, do something. My code looks basically like this:

private void onItemStateChanged(java.awt.event.ItemEvent evt) {
    System.out.println("STATE CHANGED!");//TODO debug code
    if (evt.getStateChange() == ItemEvent.SELECTED) {
        int returnVal = JOptionPane.showConfirmDialog(this, "blablatext");
        if (returnVal == JOptionPane.OK_OPTION) {
            this.field1TF.setText("");
            this.field1TF.setEditable(false);
            this.field2TF.setText("");
            this.filed2TF.setEditable(false);
        }else if(returnVal == JOptionPane.NO_OPTION){
            this.field1TF.setText("");
            this.field1TF.setEditable(false);
            this.field2TF.setText("");
            this.field2TF.setEditable(false);
        }
    } else if(evt.getStateChange() == ItemEvent.DESELECTED){
        this.field1TF.setEditable(true);
        this.field2TF.setEditable(true);
    }
}

My problem now is, that my checkbox changes state always twice when I click on it. It somehow has to do with the JOptionPane.showConfirmDialog because if I comment that out, it works as intended. Am I not aware of something simple I should care about here, or what do I have to do to get my desired reaction? (User clicks checkbox -> is asked a question -> chooses YES/NO/Cancel -> program acts accordingly)

Mycetozoan answered 27/4, 2011 at 15:36 Comment(0)
P
6

change that to the ActionListener

JCheckBox http://download.oracle.com/javase/tutorial/uiswing/components/button.html#checkbox

ActionListener http://download.oracle.com/javase/tutorial/uiswing/events/actionlistener.html

Polyandrist answered 27/4, 2011 at 16:35 Comment(5)
While it works like this (with a global variable for the state of the checkbox) I thought a handler for doing things on ItemStateChanged was exactly what I needed. Do you know why it doesn't work with that? I'll give the 'answer accepted' to you if no one else comes up with a solution to the original problem, since this is a valid workaround for me.Mycetozoan
ok check download.oracle.com/javase/tutorial/uiswing/events/… that's contains exaple with similair outPut and I'll send example about ActionListenerPolyandrist
I don't have a problem with writing the Listener, I have the problem that the state of the checkbox changes twice in a row, which somehow has to have its source in the JOptionpane.showDialog.. I do. I appreciate your help, and for now I used the actionListener, but the idea of this post was to get some hints as of why the dialog I spawn causes the checkbox to be unchecked againMycetozoan
I accepted your initial answer now, since it's what I ended up using. Thanks for the help.Mycetozoan
does not quite address the unwanted state change problem - this is more of an workaround.Reproof
P
1

eeerggrrhh, you have to look at ItemListener, and by using this demo ....

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/** @see http://stackoverflow.com/questions/5806712 */
public class ComponentEventDemo extends JPanel
    implements ActionListener, ComponentListener, ItemListener {

    private static final long serialVersionUID = 1L;
    private JFrame frame;
    private JTextArea display;
    private JLabel label;
    private String newline = "\n";
    private JTextField field1TF;
    private JTextField field2TF;
    private JCheckBox checkbox;

    public ComponentEventDemo() {
        super(new BorderLayout());
        display = new JTextArea();
        display.setEditable(false);
        JPanel panel = new JPanel(new GridLayout(0, 4));
        field1TF = new JTextField();
        field1TF.setDisabledTextColor(Color.red);
        field2TF = new JTextField();
        field2TF.setDisabledTextColor(Color.red);
        label = new JLabel("This is a label", JLabel.CENTER);
        label.addComponentListener(this);
        checkbox = new JCheckBox("Label visible", true);
        checkbox.addActionListener(this);
        checkbox.addComponentListener(this);
        checkbox.addItemListener(this);
        panel.add(checkbox);
        panel.add(label);
        panel.add(field1TF);
        panel.add(field2TF);
        panel.addComponentListener(this);
        JScrollPane scrollPane = new JScrollPane(display);
        scrollPane.setPreferredSize(new Dimension(650, 200));
        frame = new JFrame("ComponentEventDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(scrollPane, BorderLayout.CENTER);
        frame.add(panel, BorderLayout.SOUTH);
        frame.addComponentListener(this);
        frame.setLocation(200, 200);
        frame.pack();
        frame.setVisible(true);
    }

    public void itemStateChanged(ItemEvent evt) {
        System.out.println("STATE CHANGED!");//TODO debug code
        if (evt.getStateChange() == ItemEvent.SELECTED) {
            int returnVal = JOptionPane.showConfirmDialog(frame, "blablatext");
            if (returnVal == 0) {
                field1TF.setText("SELECTED - OK btn");
                field1TF.setEditable(false);
                field2TF.setText("SELECTED - OK btn");
                field2TF.setEditable(false);
            } else if (returnVal == 1) {
                field1TF.setText("SELECTED - canc btn");
                field1TF.setEditable(true);
                field2TF.setText("SELECTED - canc btn");
                field2TF.setEditable(true);
            }
        } else if (evt.getStateChange() == ItemEvent.DESELECTED) {
            field1TF.setEditable(true);
            field1TF.setText("DESELECTED");
            field2TF.setEditable(true);
            field2TF.setText("DESELECTED");
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        boolean selected = checkbox.isSelected();
        System.out.println("Checkbox "
            + (selected ? "is" : "is not") + " selected.");
            if (selected) {
                //some stuff
            } else {
                //some reversal stuff
            }
    }

    protected void displayMessage(String message) {
        display.append(message + newline);
        display.setCaretPosition(display.getDocument().getLength());
    }

    @Override
    public void componentHidden(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName() + " --- Hidden");
    }

    @Override
    public void componentMoved(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName() + " --- Moved");
    }

    @Override
    public void componentResized(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName() + " --- Resized ");
    }

    @Override
    public void componentShown(ComponentEvent e) {
        displayMessage(e.getComponent().getClass().getName() + " --- Shown");

    }

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

            @Override
            public void run() {
                ComponentEventDemo ced = new ComponentEventDemo();
            }
        });
    }
}
Polyandrist answered 28/4, 2011 at 18:20 Comment(2)
I took the liberty of reformatting your example and merging your other answer. It's generally better to update an answer, unless it's a significantly different approach. +1, btw.Uhhuh
@ trashgod agreed and with Delete tooPolyandrist
C
0

Adding an ItemListener and checking for isSelected did it for me :

        checkbox.addItemListener(new ItemListener() {
                @Override
                public void itemStateChanged(ItemEvent e) {
                    if(checkbox.isSelected()){
                        System.out.println(checkbox.getText() + " ++ " + checkbox.isSelected());
                        //do stuff
                    }else{
                        System.out.println(checkbox.getText() + " -- " + checkbox.isSelected());
                        //do other stuff
                    }

                }
        });
Cameral answered 2/12, 2014 at 13:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.