Reputation: 13
Okay so this isn't great code, but basically I need to force a more complicated version of this program to wait for a click while inside of a while loop. Any help on making the waitForClick() method below would be awesome. All that is supposed to happen is that the user clicks the JButton finish, and the program will set condition to false, and print "Done".
public class GUI extends JFrame {
private static final long serialVersionUID = 3560258176733156660L;
public static void main(String[] args) {
new GUI().setVisible(true);
}
private JButton finish;
private boolean condition;
public GUI() {
condition = true;
setLayout(null);
setSize(250, 120);
setTitle("Silly");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
finish = new JButton("Finish");
finish.setBounds(50, 40, 100, 30);
finish.addMouseListener(new MouseClickListener());
add(finish);
doThings();
}
public void doThings() {
while (condition) {
waitForClick();
}
System.out.println("Done");
}
public void waitForClick() {
// Need this method to make program wait for the Listener below, don't know how to do this!
}
public class MouseClickListener implements MouseListener {
public void mouseClicked(MouseEvent arg0) {
if (arg0.getSource()==finish) {
condition = false;
}
}
@Override
public void mouseEntered(MouseEvent arg0) {
}
@Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
}
Upvotes: 0
Views: 3528
Reputation: 86
Check out http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.concurrent.CountDownLatch;
import javax.swing.JButton;
import javax.swing.JFrame;
public class GUI extends JFrame implements ActionListener {
private static final long serialVersionUID = 3560258176733156660L;
public static void main(String[] args) {
new GUI().setVisible(true);
}
private JButton finish;
private boolean condition;
private CountDownLatch startSignal = new CountDownLatch(1);
private CountDownLatch doneSignal = new CountDownLatch(1);
public Main() {
condition = true;
setLayout(null);
setSize(250, 120);
setTitle("Silly");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
finish = new JButton("Finish");
finish.setBounds(50, 40, 100, 30);
finish.addActionListener(this);
add(finish);
//doThings();//Probably better not to put this here.
// If you need to do things on the button click simply place doThings() in the action listener.
}
public void doThings() {
new Thread(new Worker(startSignal, doneSignal)).start();
startSignal.countDown();
waitForClick();
System.out.println("Done");
System.exit(0);
}
public void waitForClick() {
try {
doneSignal.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void actionPerformed(ActionEvent arg0) {
if (arg0.getSource()==finish) {
condition = false;
doThings();
}
}
class Worker implements Runnable {
private final CountDownLatch startSignal;
private final CountDownLatch doneSignal;
public Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
this.startSignal = startSignal;
this.doneSignal = doneSignal;
}
public void run() {
try {
startSignal.await();
doWork();
doneSignal.countDown();
} catch (InterruptedException ex) {} // return;
}
void doWork() {
// Do work here before finish
for (int i = 0; i < 10000; i++) {
System.out.println("Running..." + Math.pow(i, i));
}
}
}
}
Upvotes: 0
Reputation: 36621
What you want to do is not possible.
Swing is single-threaded. So if you have an infinite loop running on that single thread (the EDT), your UI gets blocked and will not even be capable of handling that mouse click.
So what are your possibilities:
AtomicBoolean
. This is of course only an option if your loop actually has to do something. If you just want to wait, see the next option.doThings
from the constructor. The MouseClickListener
would then call doThings
, and you can remove the waiting loop from the doThings
method.Apart from that, I would strongly suggest to get rid of the null
layout and switch to a real LayoutManager
Upvotes: 3