Swing wait()/ notifyAll()

时间:2015-06-07 04:35:31

标签: java multithreading swing user-interface jframe

我正在开发一个Java应用程序,当按下GUI中的按钮时,用户可以点击屏幕上的任意位置来记录他们点击的x和y坐标。

这是通过在侦听鼠标点击的整个屏幕上放置一个未装饰的,部分透明的JFrame,记录x / y坐标,然后在点击时关闭。

透明JFrame类(注意:扩展JFrame)

setUndecorated(true);
    setOpacity((float) 0.75);
    W = Toolkit.getDefaultToolkit().getScreenSize().width;
    H = Toolkit.getDefaultToolkit().getScreenSize().height;
    setSize(W,H);
    addMouseListener(new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent e) {
            X = e.getX();
            Y = e.getY();
            System.out.println(X + ":" + Y);
            closed = true;
            dispose();
        }
    });
}

public void start() {
    java.awt.EventQueue.invokeLater(() -> {
        this.setVisible(true);
    });
}

public boolean closed = false;
public int X = -1;
public int Y = -1;
按下按钮的方法(注意:扩展JFrame)

    setVisible(false);
    click_frame.start();
    while(!click_frame.closed) {

    }
    setVisible(true);
    System.out.println(click_frame.X + "," + click_frame.Y);

我遇到的问题是while循环挂起整个应用程序而不仅仅是主GUI。我想使用wait()和notifyAll(),因为我试图故意挂起主GUI,直到click_frame.X和click_frame.Y有值。

当我尝试没有while循环的其他方法时,“click_frame JFrame类”与主GUI一起运行,而不是阻止它,这不是我想要发生的。

我的问题是如何让主GUI使用wait()/ notifyAll(),以便在第二个JFrame记录输入时停止。

1 个答案:

答案 0 :(得分:4)

Swing是一个单线程框架,这意味着在Event Dispatching Thread的上下文中执行的任何长时间运行或阻塞进程都将阻止框架响应新事件

  

我的问题是如何让主GUI使用wait()/ notifyAll(),以便在第二个JFrame记录输入时停止。

别。与大多数UI框架一样,Swing是事件驱动的,这意味着,某些事情会发生(在某个时间点)并且您会对其做出响应。

相反,只需使用MouseListener并监控mouseClicked事件即可。发生这种情况时,您可以使用MouseEvent#getLocationOnScreen方法确定用户点击屏幕的位置。

单击时,应该会向调用者报告(通过某种观察者模式)调用的结果。

当然,你可以作弊并简单地使用一个模态JDialog,它会在对话框可见时阻止(安全),直到它被解除(关闭)