mouseReleased在JDialog关闭后从未调用过

时间:2017-11-09 14:49:01

标签: java swing

我有一个按下然后松开的按钮。按下按钮时,可能会发生错误,并显示JDialog。关闭JDialog后,永远不会调用mouseReleased(...)方法。有办法解决这个问题吗?

如何使用示例重现问题:

  1. 启动该计划。
  2. 按下按钮,直到显示JDialog(启动程序后5秒出现)。
  3. 关闭mouseReleased(...)后永远不会调用
  4. JDialog

    import javax.swing.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    
    public class testJDialog {
    
        public static void main(String[] args) {
            final JFrame frame = new JFrame();
            JPanel panel = new JPanel();
            JButton button = new JButton("Push me");
    
            button.addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    System.out.println("pressed");
                }
    
                @Override
                public void mouseReleased(MouseEvent e) {
                    System.out.println("released");
                }
            });
    
            // JDialog shown after 5 seconds.
            Timer timer = new Timer(5000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JOptionPane.showMessageDialog(frame, "Hello");
                }
            });
    
            timer.setRepeats(false);
            timer.start();
    
            panel.add(button);
            frame.add(panel);
            frame.setLocation(0, 0);
            frame.setSize(800, 600);
            frame.setVisible(true);
        }
    }
    

1 个答案:

答案 0 :(得分:4)

您可以将ChangeListener添加到按钮的模型中,例如:

private class ModelListener implements ChangeListener {
    private boolean pressed = false;

    @Override
    public void stateChanged(ChangeEvent e) {
        boolean modelPressed = ((ButtonModel) e.getSource()).isPressed();
        if (modelPressed != pressed) {
            // if pressed state has changed
            pressed = modelPressed;  // update the state

            // and then do something with it
            System.out.println("Pressed: " + pressed);
        }
    }
}

整个例子:

import java.awt.Dimension;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

@SuppressWarnings("serial")
public class TestingDialog2 extends JPanel {
    private static final int TIMER_DELAY = 3000;
    private JButton button = new JButton("Press Me");

    public TestingDialog2() {
        button.getModel().addChangeListener(new ModelListener());

        setPreferredSize(new Dimension(300, 200));
        add(button);

        new Timer(TIMER_DELAY, e -> {
            JOptionPane.showMessageDialog(TestingDialog2.this, "Message");
            ((Timer) e.getSource()).stop();
        }).start();
    }

    private class ModelListener implements ChangeListener {
        private boolean pressed = false;

        @Override
        public void stateChanged(ChangeEvent e) {
            boolean modelPressed = ((ButtonModel) e.getSource()).isPressed();
            if (modelPressed != pressed) {
                pressed = modelPressed;
                System.out.println("Pressed: " + pressed);
            }
        }
    }

    private static void createAndShowGui() {
        TestingDialog2 mainPanel = new TestingDialog2();

        JFrame frame = new JFrame("TestingDialog2");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

这应该在不再按下时准确注册,不仅如此,当按钮被禁用时不应该工作,MouseListener将无法正常工作。