JCheckbox изменяет состояние дважды, когда я показываю диалог на statechange, как исправить?

У меня есть флажок, который, когда пользователь выбирает его, должен порождать диалог с дополнительной информацией, а по реакции пользователя что-то делать. Мой код выглядит в основном так:

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);
    }
}

моя проблема теперь в том, что мой флажок меняет состояние всегда дважды, когда я нажимаю на него. Это как-то связано с JOptionPane.showConfirmDialog, потому что, если я прокомментирую это, он работает по назначению. Разве я не знаю о чем-то простом, о чем я должен заботиться здесь, или что мне нужно сделать, чтобы получите желаемой реакции? (Пользователь нажимает флажок - > задается вопрос - > выбирает да / нет / отмена - > программа действует соответственно)

3 ответов



eeerggrrhh, вы должны посмотреть на ItemListener, и с помощью этой демонстрации ....

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();
            }
        });
    }
}

добавление ItemListener и проверка isSelected сделали это за меня:

        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
                    }

                }
        });