Examples
Example9 - Threads
This example demonstrates threads handling.
All methods of QSwing components are reentrant i.e. they can be called
from other threads but they are not thread-safe. Unlike Swing all
method calls from other threads are automatically scheduled and executed inside
the GUI event loop. A calling thread is blocked until a call returns
(implicit invokeAndWait).
All QSwing native objects live in
the GUI thread (a thread that runs the GUI event loop) regardless
of the thread in which their Java counterparts are created.
Even though the objects can be accessed from other threads it is preferable that
they are created and used inside the GUI thread.
This is due to performance reasons.
Code
package yu.ac.bg.etf.javaqx.examples;
import java.util.Random;
import yu.ac.bg.etf.javaqx.qswing.JQButton;
import yu.ac.bg.etf.javaqx.qswing.JQContainer;
import yu.ac.bg.etf.javaqx.qswing.JQProgressBar;
import yu.ac.bg.etf.javaqx.qswing.QSwing;
import yu.ac.bg.etf.javaqx.qswing.events.ActionEvent;
import yu.ac.bg.etf.javaqx.qswing.events.ActionListener;
/**
* Threads Example.
*/
public class Example9Threads extends JQContainer {
final JQProgressBar progressBar1;
final JQProgressBar progressBar2;
final JQButton button;
final RandomThread randomThread11;
final RandomThread randomThread12;
final RandomThread randomThread21;
final RandomThread randomThread22;
/**
* GUI Building.
*/
public Example9Threads() {
super(null);
setName("Threads");
setFixedSize(300, 100);
progressBar1 = new JQProgressBar();
progressBar1.setValue(50);
add(progressBar1);
progressBar1.setBounds(10, 10, 274, 20);
progressBar2 = new JQProgressBar();
progressBar2.setValue(50);
add(progressBar2);
progressBar2.setBounds(10, 40, 274, 20);
button = new JQButton("Pause");
add(button);
button.setBounds(120, 70, 60, 25);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (randomThread11.isWorking()) {
randomThread11.pauseTimer();
randomThread12.pauseTimer();
randomThread21.pauseTimer();
randomThread22.pauseTimer();
button.setText("Resume");
} else {
randomThread11.resumeTimer();
randomThread12.resumeTimer();
randomThread21.resumeTimer();
randomThread22.resumeTimer();
button.setText("Pause");
}
}
});
randomThread11 = new RandomThread(progressBar1);
randomThread12 = new RandomThread(progressBar1);
randomThread21 = new RandomThread(progressBar2);
randomThread22 = new RandomThread(progressBar2);
}
/**
* Non-GUI Thread.
*/
static class RandomThread extends Thread {
private static final Random random = new Random();
private boolean pause;
private final JQProgressBar progressBar;
public RandomThread(JQProgressBar progressBar) {
this.progressBar = progressBar;
setDaemon(true);
start();
}
public synchronized boolean isWorking() {
return !pause;
}
public synchronized void pauseTimer() {
pause = true;
notifyAll();
}
public synchronized void resumeTimer() {
pause = false;
notifyAll();
}
public void run() {
try {
while (true) {
sleep(500 + random.nextInt(1000));
synchronized (this) {
while (pause) {
wait();
}
}
int value = 50 + (int)(40 * random.nextGaussian());
progressBar.setValue(value); // <-- a regular call from non-GUI thread
}
} catch (InterruptedException e) {
}
}
}
public static void main(String[] args) {
Example9Threads threadsExample = new Example9Threads();
threadsExample.setVisible(true);
QSwing.startEventLoop(true);
}
}
|
Screenshots