
07-13-2009, 12:01 AM
|
|
Member
|
|
Join Date: Jul 2009
Posts: 7
Rep Power: 0
|
|
JProgressBar inside a JDialog
Hey folks, I was wondering.. I want to create a JDialog with a JProgressBar in it, while doing a process in the background, but unfortunately, JDialog blocks all java code until it is closed...
So I made something like this:
This is located inside a class which extends JDialog and implements runnable:
|
Code:
|
public void run() {
setVisible(true);
}
public void viewProgress() {
try {
CheckersClient client = new CheckersClient(serverIP, port);
client.connect();
progressBar.setIndeterminate(false);
progressBar.setValue(50);
statusLabel.setText("Connected, login with username...");
if (client.login(userName) == CheckersDataLogin.SERVER_LOGIN_SUCCESSFUL) {
progressBar.setValue(100);
statusLabel.setText("Login process completed");
//new Thread(client).start();
setVisible(false);
}
}
catch (InvalidLoginException e) {
System.out.println(e.toString());
}
catch (Exception e) {
System.out.println("Couldn't connect to server.");
}
} |
and I call it in the following way:
|
Code:
|
ConnectionStatusDialog d = new ConnectionStatusDialog(host, port, userName);
Thread dThread = new Thread(d);
dThread.start();
d.viewProgress(); |
It does open up the dialog window but it doesn't have anything in it, it seems transparent and I get an annoying exception:
|
Code:
|
Exception in thread "Thread-4" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at java.awt.Container.createHierarchyEvents(Container.java:1357)
at java.awt.Container.createHierarchyEvents(Container.java:1357)
at java.awt.Container.createHierarchyEvents(Container.java:1357)
at java.awt.Container.createHierarchyEvents(Container.java:1357)
at java.awt.Container.createHierarchyEvents(Container.java:1357)
at java.awt.Dialog.conditionalShow(Dialog.java:939)
at java.awt.Dialog.show(Dialog.java:1040)
at java.awt.Component.show(Component.java:1516)
at java.awt.Component.setVisible(Component.java:1468)
at java.awt.Window.setVisible(Window.java:841)
at java.awt.Dialog.setVisible(Dialog.java:991)
at checkers.GUICheckers.GUICheckersNetworkDialog$ConnectionStatusDialog.run(GUICheckersNetworkDialog.java:189)
at java.lang.Thread.run(Thread.java:619) |
Any idea how to solve this?
Thanks a lot!
Mikey
|
|

07-13-2009, 12:12 AM
|
 |
Moderator
|
|
Join Date: Jun 2008
Posts: 6,431
Rep Power: 8
|
|
Originally Posted by Mikey_S
|
|
Hey folks, I was wondering.. I want to create a JDialog with a JProgressBar in it, while doing a process in the background, but unfortunately, JDialog blocks all java code until it is closed...
|
only when called in a modal fashion. Non-modal dialogs will happily allow the calling Swing code to continue to run. Note that you most emphatically do not want to run your JDialog in any thread but the EDT, the event dispatch thread of Swing. Do not call it in a background thread unless you want some very hard to debug intermittent errors to crop up.
Myself, I'd do the client login process in a SwingWorker that is tied to the progress bar.
Last edited by Fubarable; 07-13-2009 at 12:16 AM.
|
|

07-13-2009, 12:15 AM
|
|
Member
|
|
Join Date: Jul 2009
Posts: 7
Rep Power: 0
|
|
Originally Posted by Fubarable
|
|
only when called in a modal fashion. Non-modal dialogs will happily allow the calling Swing code to continue to run.
|
That's true, but I don't want the user to be able to do anything while the dialog's open... that was the whole point...
|
|

07-13-2009, 12:23 AM
|
 |
Moderator
|
|
Join Date: Jun 2008
Posts: 6,431
Rep Power: 8
|
|
|
OK, you can call the JDialog modally, but you still need to run it on the EDT, there are no exceptions here, and you need to run the background process in a background thread, and again I suggest a SwingWorker here for this purposes. The code should work this way unless you have some bugs. If it doesn't, then why not post it here and let us have a look.
|
|

07-13-2009, 12:39 AM
|
|
Member
|
|
Join Date: Jul 2009
Posts: 7
Rep Power: 0
|
|
Originally Posted by Fubarable
|
|
OK, you can call the JDialog modally, but you still need to run it on the EDT, there are no exceptions here, and you need to run the background process in a background thread, and again I suggest a SwingWorker here for this purposes. The code should work this way unless you have some bugs. If it doesn't, then why not post it here and let us have a look.
|
Is there any way to trigger an event as soon as a JDialog is visible?
I did something like this inside the class that extends JDialog and which holds the JProgressBar:
|
Code:
|
new Thread(this).start();
setVisible(true);
}
public void run() {
//setVisible(true);
viewProgress();
}
public void viewProgress() {
try {
//Thread.sleep(5000);
CheckersClient client = new CheckersClient(serverIP, port);
client.connect();
progressBar.setIndeterminate(false);
progressBar.setValue(50);
statusLabel.setText("Connected, login with username...");
if (client.login(userName) == CheckersDataLogin.SERVER_LOGIN_SUCCESSFUL) {
progressBar.setValue(100);
statusLabel.setText("Login process completed");
//new Thread(client).start();
setVisible(false);
}
}
catch (InvalidLoginException e) {
System.out.println(e.toString());
}
catch (Exception e) {
System.out.println("Couldn't connect to server.");
}
}
} |
if I didn't have that Thread.sleep(5000); it would've called an exception... but with it it worked just fine... any idea how to solve this?
|
|

07-13-2009, 03:46 AM
|
 |
Moderator
|
|
Join Date: Jun 2008
Posts: 6,431
Rep Power: 8
|
|
|
Please let us know where else you have cross-posted this same question so we can avoid duplicate effort by answering things that have already been answered. Thanks.
|
|

07-13-2009, 03:58 AM
|
|
Member
|
|
Join Date: Jul 2009
Posts: 7
Rep Power: 0
|
|
|
only here and on the official sun forums...
|
|

07-13-2009, 04:14 AM
|
 |
Moderator
|
|
Join Date: Jun 2008
Posts: 6,431
Rep Power: 8
|
|
|
You're making calls to the JProgressBar off of the EDT. Are you using java 1.6? If so, have you tried using a SwingWorker here?
|
|

07-13-2009, 04:23 AM
|
|
Member
|
|
Join Date: Jul 2009
Posts: 7
Rep Power: 0
|
|
|
Never tries using SwingWorker, how can it help me with the above? sorry, I've been programming Java for only a few months...
|
|

07-13-2009, 04:46 AM
|
 |
Moderator
|
|
Join Date: Jun 2008
Posts: 6,431
Rep Power: 8
|
|
It can help separate that which needs to be called on the EDT from that which needs to be called in a background thread. As it is, you're mixing the two. For example (borrowing much code from the tutorial):
|
Code:
|
import java.awt.*;
import java.awt.Dialog.ModalityType;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import javax.swing.*;
public class ProgressInDialog {
private static void createAndShowUI() {
MainDisplay mainDisplay = new MainDisplay();
JFrame frame = new JFrame("ProgressInDialog");
frame.getContentPane().add(mainDisplay.getComponent());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
class MainDisplay {
private JPanel mainPanel = new JPanel();
public MainDisplay() {
JButton showDialogBtn = new JButton(new ShowDialogAction("Show Dialog"));
mainPanel.add(showDialogBtn);
}
public JComponent getComponent() {
return mainPanel;
}
private class ShowDialogAction extends AbstractAction {
public ShowDialogAction(String text) {
super(text);
}
public void actionPerformed(ActionEvent e) {
Window win = SwingUtilities.getWindowAncestor(mainPanel);
DialogDisplay dlgDisplay = new DialogDisplay();
JDialog dialog = new JDialog(win, "Progress Dialog", ModalityType.APPLICATION_MODAL);
dialog.getContentPane().add(dlgDisplay.getComponent());
dialog.pack();
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
}
}
}
class DialogDisplay {
private JPanel mainPanel = new JPanel();
private JProgressBar progressBar = new JProgressBar(0, 100);
private JLabel statusLabel = new JLabel("Login Beginning", SwingConstants.CENTER);
public DialogDisplay() {
progressBar.setIndeterminate(false);
progressBar.setStringPainted(true);
progressBar.setValue(0);
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
mainPanel.setLayout(new BorderLayout(10, 10));
mainPanel.add(progressBar, BorderLayout.CENTER);
mainPanel.add(statusLabel, BorderLayout.SOUTH);
final SwingWorker task = new SwingWorker<Void, Void>() {
private int value = 0;
@Override
protected Void doInBackground() throws Exception {
for (int i = 0; i < 10; i++) {
setProgress(10 * i);
Thread.sleep(1000);
}
setProgress(100);
Thread.sleep(1000);
return null;
}
@Override
protected void done() {
Window win = SwingUtilities.getWindowAncestor(mainPanel);
win.dispose();
}
};
task.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) {
int progress = task.getProgress();
progressBar.setValue(progress);
if (progress >= 50) {
statusLabel.setText("Halfway Done");
}
if (progress >= 100) {
statusLabel.setText("Done");
}
}
});
task.execute();
}
public JComponent getComponent() {
return mainPanel;
}
} |
|
|

07-13-2009, 03:55 PM
|
 |
Senior Member
|
|
Join Date: Sep 2008
Location: Madgaon, Goa, India
Posts: 726
Rep Power: 2
|
|
|
I've never used it, but this looks like a use case for javax.swing.ProgressMonitor
db
|
|
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT +2. The time now is 08:57 AM.
|
|