Reputation: 433
I am running out of ideas how to make my progress bar responsive during performing RMI connection, so I have decided to ask You for help.
Here's the code :
Thread performLogin = new Thread(new Runnable()
{
@Override
public void run()
{
LoginResult = TryLogin();
}
});
performLogin.start();
WaiterFrame.setVisible(true);
SetProgressDialog();
try
{
performLogin.join();
}
catch(InterruptedException exc)
{
System.err.println(exc.getLocalizedMessage());
}
if (LoginResult)
{ ... }
WaiterFrame.setVisible(false);
this.dispose();
Progress bar is unresponsive - does not animate as it should while performing performLogin thread. I was trying to run progress bar frame on the other thread too, but result was the same (as well as using Eventqueue.invokelater()).
Upvotes: 0
Views: 1566
Reputation: 433
Thank You very much MadProgrammer! Progress bar works as intended with SwingWorker usage. I'm posting code if someone would encourage same problem in future :
PerformLogin = new SwingWorker<Boolean, Object>()
{
@Override
protected Boolean doInBackground() throws Exception
{
LoginResult = TryLogin();
if (LoginResult)
{
MainF = new MainFrame();
MainF.Connection = DataEntry.TestConnection;
MainF.prepareFormToShow();
}
return LoginResult;
}
@Override
protected void done()
{
if (LoginResult == true)
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
MainF.setVisible(true);
WaiterFrame.setVisible(false);
}
});
}
else
{
setVisible(true);
this.cancel(true);
JOptionPane.showMessageDialog(null, "Wrong adress!",
"Błąd",JOptionPane.WARNING_MESSAGE);
}
}
and
WaiterFrame.setVisible(true);
PerformLogin.execute();
in the main thread
Upvotes: 0
Reputation: 347184
The likely cause is performLogin.join();
is blocking the Event Dispatching Thread, making the UI non-responsive.
Two things to remember with Swing (and most GUI frameworks);
You could use a SwingWorker
, which would allow you to run your long running process in a background thread but provides a number of mechanism through which you can send updates back to the EDT safely.
See Worker Threads and SwingWorker for more details and Issues with SwingWorker and JProgressBar for an example
Upvotes: 1
Reputation: 9625
If you're using Java 8 you could try something like this:
CompletableFuture<LoginResult> loginResult = CompletableFuture.supplyAsync(this::tryLogin);
WaiterFrame.setVisible(true);
setProgressDialog();
loginResult.thenAccept(lr -> {
//do your thing
WaiterFrame.setVisible(false);
})
There are other options to "thenAccept" depending on what you need to do. "thenAccept" only consumes the the content of the Future.
The same could be accomplished using Guava's ListenableFuture and Executors if Java 8 is not an option.
Upvotes: 1