Brian T Hannan
Brian T Hannan

Reputation: 4005

Why does my wait cursor not show sometimes when updating data in JTable?

I have a JTable that will reload sorted data from the database when the user clicks on a column header. MainView (JFrame) contains the GUI elements that will create a new SwingWorker and start it. The SwingWorker's doInBackGround() function changes the cursor of the MainView to be the wait cursor. Then when the doInBackground() function is completed doing its work and before it leaves the doBackground function it changes the cursor back to the default cursor.

Sometimes the cursor shows up but after a while it stops showing the cursor each time I click on the header. It probably works the first few times and seems kind of random.

Why does the cursor show sometimes, but not others? Is there a particular way I should be setting the wait cursor? Should I set the wait cursor from the SwingWorker thread or from the MainView GUI thread?

Upvotes: 0

Views: 1759

Answers (3)

Alberto Solano
Alberto Solano

Reputation: 8227

From the Oracle's Swing Concurrency page:

Swing event handling code runs on a special thread known as the event dispatch thread. Most code that invokes Swing methods also runs on this thread. This is necessary because most Swing object methods are not "thread safe": invoking them from multiple threads risks thread interference or memory consistency errors.

The SwingWorker API page reports, about the doInBackground() method:

Computes a result, or throws an exception if unable to do so.

Then it's used from the worker to execute some tasks, executing on a worker thread.

and about the done() method:

Executed on the Event Dispatch Thread after the doInBackground method is finished. The default implementation does nothing. Subclasses may override this method to perform completion actions on the Event Dispatch Thread. Note that you can query status inside the implementation of this method to determine the result of this task or whether this task has been cancelled.

Commonly, it's used to display the final results after the doInBackground() completes its work.

Then, I think you should set the cursor on the doInBackground() SwingWorker method using code like:

public Void doInBackground() {
     setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
...
}

and deactivate it on the done() SwingWorker method, with:

public void done() {
 setCursor(Cursor.getDefaultCursor());
 ...
}

You can find other info about these cursor methods on the Cursor class API.

Here a page with some busy cursor code examples, here a SO question related to cursor.

Upvotes: 0

Logan
Logan

Reputation: 2364

You may want to let your jtable sort the data instead of calling the database again. It's pretty easy to setup. table sorting

Upvotes: 0

Logan
Logan

Reputation: 2364

You should set the wait cursor before the doinbackground. I've done that in the constructor of the worker thread class or right before calling execute. You need to set your cursor back to normal in the done method. That is probably where your problem is. The done method runs on the event dispatch thread, which must be used for UI updates.

Do not update any gui components from the doinbackground method or you will see this type of behavior. I didn't know that and did the same thing you are doing. It can be confusing.

Upvotes: 1

Related Questions