After many attempts trying to make a JProgressBar
work as expected, I finally became successful at achieving my goal. I had used @MadProgrammer's advice and used a SwingWorker
to finally get the program work as I want.
Now, I want the cursor to change into
when my JProgressBar
goes from 0% to 100%. I've googled and found out that
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
is the code to do it. I've tried it but it does not work as expected.
Relevant piece of code:
JProgressBar progress;
JButton button;
JDialog dialog; //Fields of my GUI class
progress=new JProgressBar(JProgressBar.HORIZONTAL,0,100);
button=new JButton("Done");
dialog=new JDialog(); //Done from methods
progress.setValue(0);
progress.setStringPainted(true);
progress.setBorderPainted(true); //Also done from methods
button.addActionListener(this); //Also done from methods
dialog.setLayout(new FlowLayout(FlowLayout.CENTER));
dialog.setTitle("Please wait...");
dialog.setBounds(475,150,250,100);
dialog.setModal(true); //Also done from methods
dialog.add(new JLabel("Loading..."));
dialog.add(progress); //Also done from methods
And here is the actionPerformed
method:
public void actionPerformed(ActionEvent e)
{
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
Task task=new Task();
task.addPropertyChangeListener(this);
task.execute();
dialog.setVisible(true);
}
The propertyChange
method:
public void propertyChange(PropertyChangeEvent evt) {
if("progress" == evt.getPropertyName()){
int progressnum = (Integer) evt.getNewValue();
progress.setValue(progressnum);
}
}
and the nested class Task
:
class Task extends SwingWorker<Void, Void> {
/*
* Main task. Executed in background thread.
*/
@Override
public Void doInBackground() {
int progressnum = 0;
setProgress(0);
while (progressnum < 100) {
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
System.err.println("An error occured:"+ex);
ex.printStackTrace();
}
progressnum ++;
setProgress(Math.min(progressnum, 100));
}
return null;
}
/*
* Executed in event dispatching thread
*/
@Override
public void done() {
//setCursor(null); //turn off the wait cursor
setCursor(Cursor.getDefaultCursor()); //Is this one or the one above it right?
dialog.dispose();
progress.setValue(progress.getMinimum());
}
}
When I press button
, the JDialog with the JProgressBar appears and the JProgressBar goes from 0% to 100%. During this time, the cursor needs to be changed into (busy cursor) and when the JProgressBar reaches 100%, the normal cursor(
) needs to be restored.
The problem is, when I press button
, the cursor changes to the busy cursor for a split second and then, changes back into the original cursor. I want the cursor to be busy until the JProgressBar reaches 100%.
I've added the code to convert the cursor into a busy cursor in the actionPerformed
method and the restore the normal cursor in the done
method of the nested class Task
. Note that I've also included the necessary packages.
Should I use
setCursor(null);
or
setCursor(Cursor.getDefaultCursor());
to restore the cursor?
When you call setCursor()
on the JFrame
, it only has effect for the frame, not the dialog. Similarly, when you call setCursor()
on the JDialog
, it only has effect for the dialog, not the frame. There the problem: you did not set the cursor for the dialog, right?
I'm not sure whether setCursor(null)
is safer than setCursor(Cursor.getDefaultCursor())
. :p