Java 关闭JDialog后从未调用MouseRelease

Java 关闭JDialog后从未调用MouseRelease,java,swing,Java,Swing,我有一个按钮,按下后松开。按下按钮时,可能会发生错误,并显示JDialog。关闭JDialog后,将永远不会调用mousererelease(…)方法。有办法解决这个问题吗 如何通过示例再现问题: 启动该计划 按下按钮,直到显示JDialog(启动程序5秒后显示) 关闭JDialog后,将永远不会调用MouseRelease(…) import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.Acti

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

如何通过示例再现问题:
  • 启动该计划
  • 按下按钮,直到显示
    JDialog
    (启动程序5秒后显示)
  • 关闭
    JDialog
    后,将永远不会调用
    MouseRelease(…)

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

  • 例如,您可以将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());
        }
    }
    

    当不再按下按钮时,这应该准确地注册,不仅如此,当按钮被禁用时,它也不应该工作,这是鼠标侦听器无法正确执行的操作。

    为什么您甚至要在JButton中添加鼠标侦听器而不是ActionListener?此侦听器不适合此组件。因为我想管理
    mousePressed
    mouseerelease
    。首先产生此问题的根本动机是什么,因为我担心这可能是一种伪装?但还有其他方法可以做类似的事情,它们对JButton更友好——只要我们知道你的基本推理是什么。
    我移动滑块。它是加号和减号按钮
    -为什么需要按钮来实现这一点。您只需单击滑块的右/左侧。关闭
    JDialog
    后,
    ChangeListener
    不会自动调用,尽管。。。您必须再次单击该按钮以触发“已释放”。@dguay:当对话框弹出时,将立即调用“已释放”,因为该按钮失去焦点且不再“按下”。如果您还需要对话框关闭的通知,则必须侦听该消息。同样,所有这些都取决于总体需求。