Reputation: 137
I am developing a Java application where when a button in the GUI is pressed, the user can click anywhere on the screen to record the x and y coordinates where they clicked.
This is done by putting an undecorated, partly transparent JFrame over the entire screen that listens for a mouse click, records the x/y coords, then closes itself upon being clicked.
Transparent JFrame class (note: extends 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;
method from button press (note: extends JFrame)
setVisible(false);
click_frame.start();
while(!click_frame.closed) {
}
setVisible(true);
System.out.println(click_frame.X + "," + click_frame.Y);
The problem I am having is that the while loop hangs the entire application not just the main GUI. I want to use wait() and notifyAll() because I am trying to intentionally hang the main GUI until click_frame.X and click_frame.Y have values.
When I tried other methods without the while loop, the "click_frame JFrame class" ran alongside the main GUI, instead of blocking it, which is not what I want to happen.
My question is how can I make the main GUI use wait()/notifyAll() so it will stop while the second JFrame records the input.
Upvotes: 0
Views: 123
Reputation: 347234
Swing is a single threaded framework, this means that any long running or blocking process which is executed within the context of the Event Dispatching Thread, will prevent the framework from responding to new events
My question is how can I make the main GUI use wait()/notifyAll() so it will stop while the second JFrame records the input.
Don't. Swing, like most UI frameworks is event driven, this means, something happens (at some point in time) and you respond to it.
Instead, simply make use of a MouseListener
and monitor the mouseClicked
event. When it occurs, you can use the MouseEvent#getLocationOnScreen
method to determine where on the screen the user clicked.
When clicked, this should then report back to the caller (via some kind of observer pattern) the results of the call.
Of course, you could cheat and simply use a modal JDialog
, which will block (safely) at the point the dialog is made visible, until it is dismissed (closed)
Upvotes: 4