Frame Refresh Thread issue.
Hello again,
Middleware Developer attempting Guis.
Have what appears to be a simple thread issue with the repaint and/or listener threads not performing correctly.
Heres what I did. I made a simple gui. Assigned listeners to buttons etc. In the actionperformed areas I just simply used them to begin a line of executing code. I did NOT start any task specific threads.
This problem is noticeable for me because I am trying to use a ProgressBar. In a hardcoded test of the progress bar I put a button on the gui and when clicked it . It would simply count up from min to max and change its display text. However the gui appears to be dead. meaning that I can drag a window over it and the Frames graphics are skewed and do not return until the task is completed. This makes me feel as if I have used the thread that calls the repaint() or whatever to keep the Gui alive, to do something else.
After reading this Im not sure if I can verbalize enough of what the problem is to get any help.
try 2: I got a gui when I click a button that leads directly to code that needs to be run by that thread my front end goes dead. Should I use different threads or can I start a thread to refresh the front constantly. I figure its just lack of experence that is causing this. So feel free to comment or direct me to the basics of Guis.
Thanks B
here's sun's JProgressBarDemo - 3 classes put together
run it, see how it works, then modify your code accordingly
(more info in the 3 http links at the top)
//http://java.sun.com/docs/books/tutorial/uiswing/components/example-1dot4/ProgressBarDemo.java
//http://java.sun.com/docs/books/tutorial/uiswing/components/example-1dot4/LongTask.java
//http://java.sun.com/docs/books/tutorial/uiswing/misc/example-1dot4/SwingWorker.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.SwingUtilities;
class ProgressBarDemo extends JPanel implements ActionListener {
public final static int ONE_SECOND = 1000;
private JProgressBar progressBar;
private Timer timer;
private JButton startButton;
private LongTask task;
private JTextArea taskOutput;
private String newline = "\n";
public ProgressBarDemo() {
super(new BorderLayout());
task = new LongTask();
startButton = new JButton("Start");
startButton.setActionCommand("start");
startButton.addActionListener(this);
progressBar = new JProgressBar(0, task.getLengthOfTask());
progressBar.setValue(0);
progressBar.setStringPainted(true);
taskOutput = new JTextArea(5, 20);
taskOutput.setMargin(new Insets(5,5,5,5));
taskOutput.setEditable(false);
taskOutput.setCursor(null);
JPanel panel = new JPanel();
panel.add(startButton);
panel.add(progressBar);
add(panel, BorderLayout.PAGE_START);
add(new JScrollPane(taskOutput), BorderLayout.CENTER);
setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
timer = new Timer(ONE_SECOND, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
progressBar.setValue(task.getCurrent());
String s = task.getMessage();
if (s != null) {
taskOutput.append(s + newline);
taskOutput.setCaretPosition(
taskOutput.getDocument().getLength());
}
if (task.isDone()) {
Toolkit.getDefaultToolkit().beep();
timer.stop();
startButton.setEnabled(true);
setCursor(null); //turn off the wait cursor
progressBar.setValue(progressBar.getMinimum());
}
}
});
}
public void actionPerformed(ActionEvent evt) {
startButton.setEnabled(false);
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
task.go();
timer.start();
}
private static void createAndShowGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("ProgressBarDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent newContentPane = new ProgressBarDemo();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
class LongTask {
private int lengthOfTask;
private int current = 0;
private boolean done = false;
private boolean canceled = false;
private String statMessage;
public LongTask() {
lengthOfTask = 1000;
}
public void go() {
final SwingWorker worker = new SwingWorker() {
public Object construct() {
current = 0;
done = false;
canceled = false;
statMessage = null;
return new ActualTask();
}
};
worker.start();
}
public int getLengthOfTask() {
return lengthOfTask;
}
public int getCurrent() {
return current;
}
public void stop() {
canceled = true;
statMessage = null;
}
public boolean isDone() {
return done;
}
public String getMessage() {
return statMessage;
}
class ActualTask {
ActualTask() {
while (!canceled && !done) {
try {
Thread.sleep(1000);
current += Math.random() * 100;
if (current >= lengthOfTask) {
done = true;
current = lengthOfTask;
}
statMessage = "Completed " + current +
" out of " + lengthOfTask + ".";
} catch (InterruptedException e) {
System.out.println("ActualTask interrupted");
}
}
}
}
}
abstract class SwingWorker {
private Object value;
private static class ThreadVar {
private Thread thread;
ThreadVar(Thread t) { thread = t; }
synchronized Thread get() { return thread; }
synchronized void clear() { thread = null; }
}
private ThreadVar threadVar;
protected synchronized Object getValue() {
return value;
}
private synchronized void setValue(Object x) {
value = x;
}
public abstract Object construct();
public void finished() {
}
public void interrupt() {
Thread t = threadVar.get();
if (t != null) {
t.interrupt();
}
threadVar.clear();
}
public Object get() {
while (true) {
Thread t = threadVar.get();
if (t == null) {
return getValue();
}
try {
t.join();
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
return null;
}
}
}
public SwingWorker() {
final Runnable doFinished = new Runnable() {
public void run() { finished(); }
};
Runnable doConstruct = new Runnable() {
public void run() {
try {
setValue(construct());
}
finally {
threadVar.clear();
}
SwingUtilities.invokeLater(doFinished);
}
};
Thread t = new Thread(doConstruct);
threadVar = new ThreadVar(t);
}
public void start() {
Thread t = threadVar.get();
if (t != null) {
t.start();
}
}
}