(Java SE 6) I'm trying to create a pop-up dialog that displays a "please wait" message while my program does some time-intensive work. To do this, I've chosen to use a modeless JDialog, so that the program continues to run and does work while the JDialog is visible (if you use a modal one, the program will halt until the dialog is closed by the user).
The problem is that when you use a modeless dialog in this fashion the JDialog with a title appears, but the contents don't (I'm guessing they don't get painted开发者_JS百科 for some reason). I've tried calling repaint etc but nothing seems to work.
Now, according to a bunch of people on the interwebs this is a genuine bug with Swing, and the only answers I've found are to not do things this way and find some other means of notifying the user to wait. I'm curious if anyone here has had this issue before and has figured out a work-around.
Thanks!
It´s not a bug, you have to run your heavy weight job and your light weight swing job in sepred thread´s next to the main thread. It´s necessary because of the logical inflictions between the Dialog GUI Thread and it´s ActionListenerEvents relation to the heavy weigth job in the backround. If you don´t seperate your Main thread will deterinate the Swing draw due to some notify Events. I had the same Problem, I tryed to monitor the progress of an FTP Upload Progress which I started out of a JFrame to show it in an JDialog.
First I tried:
//Activated by Upload Button
public void actionPerformed(ActionEvent e) {
if("Upload".equals(e.getActionCommand())){
// some Declarations
new Thread(){
public void run() {
/*Run JDialog with the Upload - ProgressBar*/
FileUploadProgressBar fileUploadProgressBar = new FileUploadProgressBar(localFile, remoteFile, ftpPersistence);
}
}.start();
/*Run the heavy weigth Job - the Upload*/
ftpPersistence.uploadFile(localFile, remoteFile);
// ...
}
//...
}
But this way i gaint a JDialog FrameBorder ans a balck Content Pane but ...
Next try:
//Activated by Upload Button
public void actionPerformed(ActionEvent e) {
if("Upload".equals(e.getActionCommand())){
// some Declarations
new Thread(){
public void run() {
/*Run JDialog with the Upload - ProgressBar*/
FileUploadProgressBar fileUploadProgressBar = new FileUploadProgressBar(localFile, remoteFile, ftpPersistence);
}
}.start();
new Thread(){
public void run()
/*Run the heavy weigth Job - the Upload*/
ftpPersistence.uploadFile(localFile, remoteFile);
}
}.start();
// ...
}
//...
}
and finally it worked, hope it will help ;)
As an alternative, consider using SwingWorker
and showing interim progress, as suggested in this example.
I'm using this and it works - the original code (without the fix I found for repainting as it runs) is from here: http://inversionconsulting.blogspot.com/2008/03/java-jdialog-and-jprogressbar-example.html
but I consolidated it to (with slight changes):
JProgressBar pb = new JProgressBar(0,100);
pb.setPreferredSize(new Dimension(275,30));
pb.setString("Running");
pb.setStringPainted(true);
pb.setValue(0);
JLabel label = new JLabel("Progress: ");
JPanel center_panel = new JPanel();
center_panel.add(label);
center_panel.add(pb);
JDialog dialog = new JDialog((JFrame)null, "Working ...");
dialog.getContentPane().add(center_panel, BorderLayout.CENTER);
dialog.pack();
dialog.setVisible(true);
dialog.setLocationRelativeTo(null); // center on screen
In my code later on, when it is running through my loop (being 1 to 10 using the variable 'tot') I repaint the dialog, updating the progress bar as the program runs through the loop, thusly (this is not given on the above page link) (I am not using multiple threads, all of this is in the main thread):
//set progress bar
pb.setValue(tot*10);
//repaint it
dialog.getContentPane().paintAll(pb.getGraphics());
It took a lot of time and trial and error to find this solution. Hope it works for you as it does for me.
Have You tried validate() (it is needed after adding components to a container) ? Also consider posting source code, so that we may check it. Good luck.
精彩评论