JDialog with a JProgressBar [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java GUI JProgressBar not painting
I have a GUI that has the GUI Locked while processing an Action Event, so I need a progress bar to show up. I can get the JDialog to show up but the progress bar won't show up. I used SwingUtilities.invokeLater() and invokeAndWait() but to no avail. The progress bar will not show up. Any hints or help would be appreciated.
pb = new JProgressBar(0, 100);
pb.setPreferredSize(new Dimension(175, 40));
pb.setString("Working");
pb.setStringPainted(true);
JLabel label = new JLabel("Progress: ");
JPanel center_panel = new JPanel();
center_panel.add(label);
center_panel.add(pb);
dialog = new JDialog((JFrame) null, "Working ...");
dialog.getContentPane().add(center_panel, BorderLayout.CENTER);
dialog.pack();
dialog.setLocationRelativeTo(this); // center on screen
dialog.toFront(); // raise above other java windows
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
dialog.setVisible(true);
pb.setIndeterminate(true);
}
});
Thread.sleep(5000);
template = AcronymWizardController
.sharedInstance().readAndDislpayDocx(contdFile);
parseDocxText(contdFile);
pb.setIndeterminate(false);
savedFile.setText(contdFile.toString());
dialog.dispose();

Swing is a single threaded API, that is, all the UI updates and modifications are performed from within a single thread (known as the Event Dispatching Thread or EDT). Anything that blocks this thread will stop it from processing additional updates, like repaints.
You have a number of choices. Your immediate requirement is to move the long running task off the EDT. To do this you can either use a SwingWorker or a Thread.
From your description, a SwingWorker will be easier.
For a simple example, check out JProgressBar won't update
For more information, you should check out Concurrency in Swing
You other choice would be to use something like a ProgressMonitor, example here

Related

How to close a JDialog after a certain period of timeopened from a Jframe

So I am trying to make a shopping cart app using Java Swing forms with MYSQL JDBC Connectivity, In one part of the app, when a user clicks a button like "View Product", it takes time for the machine to load the information from the database and output in the app, so in that time I want to show a loading icon until the work is done.To achieve this I created a separate JDialog to be used to show a loading gif, and open it from a JFrame on the ActionPerformed event of a button. Here's my work:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
JDialog dialog = new loader(this, true);
dialog.setLocationRelativeTo(this);
dialog.setVisible(true);
Timer timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
dialog.dispose();
}
});
timer.setRepeats(false);
timer.start();
}
But using a Swing Timer to close the JDialog after 1sec, as suggested by other QA on Stack Overflow, doesn't work as expected, so is there any way to achieve this task, that is, to closethe JDialog window after a certain period of time?
Your dialog is modal. So the setVisible(true) method call doesn't return until the dialog has been closed. So the timer is only created once the dialog is closed.
You need to create it and start it before making the dialog visible.

java swing progressBar [duplicate]

This question already has answers here:
Prevent Swing GUI locking up during a background task
(5 answers)
Closed 6 years ago.
I have written code using swing libs, that when added an actionlistener, won't update a progressBar.
Without a button and action listener, it works great. How to force a progressBar update as simply and cleanly as possible? Appended code is an easy to understand example that sums up my problem. If you comment out an ActionPerformed method and execute the program from main, it works just fine.
Do not just paste code whithout explaining.
ps.: I have seen this: swing progressBar threading
public class Okno {
private JProgressBar progressBar = new JProgressBar(0,306);
JFrame f = new JFrame("JProgressBar Sample");
JButton b = new JButton("start");
ActionListener a = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
barupdate();
}
};
private void barupdate(){
for(int p = 1; p<308;p=p+2){
System.out.println(p);
progressBar.setValue(p);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private Okno(){
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
progressBar.setStringPainted(true);
f.add(progressBar, BorderLayout.SOUTH);
f.add(b, BorderLayout.NORTH);
b.addActionListener(a);
f.setSize(300, 300);
f.setVisible(true);
}
public static void main(String[] args) {
Okno okno = new Okno();
}
}
The problem is you have a loop where you are adjusting the progress bar setting that is being called from an action listener. The problem is, the bar won't update until after the listener is finished. And so you will get no updates. Not only that but you will bog down the gui because the window can't react to mouseclicks etc while you are in that action listener.
So the best way to handle this is instead to create a swing timer, in the action listener, and put the code for updating the button there, and start the timer in the action listener.
The timer should only update the bar once. and you should allow the fact that the swing timer will be called multiple times, to play the part of the repetitiveness. So you don't want to have any loops in your code.
Thread.sleep(50);
Don't use Thread.sleep(...). This will prevent the GUI from repainting itself until the loop has finished executing.
Instead you can use a SwingWorker.
Read the section from the Swing tutorial on Concurrency in Swing which has more information and contains a working example with a SwingWorker.
Also, look at the tutorial table of contents. There is a section on How to Use ProgressBars that also contains a working example. The tutorial is the first place to look for examples.

"Please wait" message with delay

I have a long task and I show "please wait" message during its execution.
I use SwingWorker for it. But sometimes long task is not long, so I want to show message with 1 second delay, but I don't know how to do it.
SwingWorker<Void, Void> mySwingWorker = new SwingWorker<Void, Void>(){
#Override
protected String doInBackground() throws InterruptedException
/** Execute some operation */
}
#Override
protected void done() {
dialog.dispose();
}
};
mySwingWorker.execute();
JProgressBar progressBar = new JProgressBar();
progressBar.setIndeterminate(true);
JPanel panel = new JPanel(new BorderLayout());
panel.add(progressBar, BorderLayout.CENTER);
panel.add(new JLabel("Please wait......."), BorderLayout.PAGE_START);
dialog.add(panel);
dialog.pack();
dialog.setLocationRelativeTo(win);
dialog.setVisible(true);
}
Before you start the SwingWorker, start a Swing Timer with (at least) a one second delay and set not to repeat.
Pass this Timer to your SwingWorker so it has access to it. When the worker's done method is called, stop the Timer
If the Timer is triggered, you would display your wait message.
With a little bit of effort, you could wrap the whole thing up in a self contained class, using the SwingWorker's PropertyListener support to detect when the worker was started and completed
Why dont you use Thread.sleep(1000); between each display of "please wait"
A simple way to do it would be to set
long startTime = System.getNanoTime();
then before displaying the "please wait" you could check if it was > 1 second (1×10^9 nanos)
this may not be the most efficient way, but it will work

new thread not showing the frame

I am trying to establish a network connection and the details are in a JFrame. When user clicks a button, it should start the new thread and should show the wait message to the user until, the main thread establish a network connection. I wrote this code
public void actionPerformed(ActionEvent arg0) {
Thread ref = new Thread(new Test());//Create a new thread
ref.start();
new AIDRTConnManager().createConnection(ipAddress, portAddress);//main thread
}
//This is my Thread Class
public class Test implements Runnable{
JDialog waitDialog;
JPanel panel1 = new JPanel();
JLabel waitLabel;
JFrame frame;
public void run(){
frame = new JFrame();
waitDialog = new JDialog( frame,AIRDT.toolName, true );
waitDialog.setDefaultCloseOperation( JDialog.DO_NOTHING_ON_CLOSE );
JLabel waitLabel = new JLabel( "Trying to Connect to PleaseWait...",ErrorDialog.icon,SwingConstants.CENTER );
panel1.add( waitLabel );
waitDialog.add( panel1 );
waitDialog.setSize( 100, 40 );
waitDialog.setBounds( 500,300, 300, 80 );
waitDialog.setVisible( true );
}
}
But when I click the button, the Jdialog shows the empty frame, without the wait message (JLable) and once I done with the network connection, this wait message shows properly.
Where I am going wrong? Is this a Swing Issue (Or) Thread Issue?
Could you please help me to show a wait message until the completion of back end activity?
You're mixing up your threads here - all operations that interact with the UI, such as creating a new frame, must occur on the Event Dispatch Thread (EDT), or the "main" thread as you call it. Background tasks should be performed on a different thread.
Basically you have it backwards - you should perform the background work in the new thread, and create the new frame in the main thread, which is the opposite way to how you have it now.
The code under the actionPerformed executes under the Event Dispatch Thread (EDT), not on the main thread as you say in the comment.
This means that as long as the connection thing happens, the EDT is blocked, so it doesn't have to chance to process some other UI stuff like displaying your JDialog.
Also, not related to the issue, but please note that you create a JFrame that is never displayed and that is the parent of your JDialog.

Swing: How to prohibit interaction outside of JFrame/JDialog?

I'd like to show a progressbar and block interaction with my application frame while a thread is being executed.
In another thread someone suggested using JDialog instead of JFrame and setModal(true). However, when doing so the Dialog blocks the entire application.
This is essentially my code:
MyDialog dlg = new MyDialog();
dlg.setModal(true);
dlg.setVisible(true);
//do some stuff....
//(never executed when setModal(true)
dlg.setVisible(false);
The easiest way to do it would be using JXLayer and LockableUI.
Look here for an example of how this can be done.
Also note, that JXLayer made it into Java 7, and is available as javax.swing.JLayer.
The other thing is, that you should not execute long-running tasks insite Event Dispatch Thread. Read about SwingWorker and learn to write multithreaded code for Swing.
That is the point of a modal dialog, no interaction will happen outside the "box". The modal popup also halts the thread while waiting for user input. If you want to do other stuff while showing the dialog you will either have to do it in the dialog itself or start a new thread to take care of it.
Hope that helps!
With modal dialog try something like this:
final JDialog dlg = new JDialog();
dlg.setModal(true);
dlg.setSize(500, 500);
dlg.addWindowListener(new WindowAdapter() {
#Override
public void windowActivated(WindowEvent e) { //or other method
new Thread(new Runnable() {
public void run() {
try {
//execute your long running task
} //you should catch exception
finally {
dlg.setVisible(false);
dlg.dispose();
}
}
}).start();
}
});
dlg.setVisible(true);
I can also set GlassPane on your JFrame which will intercept any event from the user.

Categories