Results 1 to 11 of 11
  1. #1
    Mikey_S is offline Member
    Join Date
    Jul 2009
    Posts
    7
    Rep Power
    0

    Default 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:

    Java 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:

    Java 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:

    Java 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

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Quote Originally Posted by Mikey_S View Post
    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.

  3. #3
    Mikey_S is offline Member
    Join Date
    Jul 2009
    Posts
    7
    Rep Power
    0

    Default

    Quote Originally Posted by Fubarable View Post
    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...

  4. #4
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    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.

  5. #5
    Mikey_S is offline Member
    Join Date
    Jul 2009
    Posts
    7
    Rep Power
    0

    Default

    Quote Originally Posted by Fubarable View Post
    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:

    Java 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?

  6. #6
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    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.

  7. #7
    Mikey_S is offline Member
    Join Date
    Jul 2009
    Posts
    7
    Rep Power
    0

    Default

    only here and on the official sun forums...

  8. #8
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    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?

  9. #9
    Mikey_S is offline Member
    Join Date
    Jul 2009
    Posts
    7
    Rep Power
    0

    Default

    Never tries using SwingWorker, how can it help me with the above? sorry, I've been programming Java for only a few months...

  10. #10
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    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):
    Java 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;
      }
    }

  11. #11
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,423
    Rep Power
    20

    Default

    I've never used it, but this looks like a use case for javax.swing.ProgressMonitor

    db

Similar Threads

  1. Updating a JProgressBar from another thread?
    By Xiphias in forum AWT / Swing
    Replies: 3
    Last Post: 03-18-2009, 02:48 AM
  2. Placing a JProgressBar over my JPEG image
    By hitmen in forum AWT / Swing
    Replies: 7
    Last Post: 03-08-2009, 11:16 AM
  3. setLocation on a JDialog is ignored
    By ScottVal in forum AWT / Swing
    Replies: 7
    Last Post: 01-13-2009, 08:35 AM
  4. [SOLVED] Netbeans Desktop App &amp; JProgressBar
    By SebScoFr in forum NetBeans
    Replies: 3
    Last Post: 11-28-2008, 12:00 AM
  5. help with jdialog
    By leonard in forum AWT / Swing
    Replies: 1
    Last Post: 08-05-2007, 06:37 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •