0

I have a gif animation image that is showing infinite circle loading progress inside a jDialog...But problem is when i load this jDialog the parent frame codes is halt.? how to do this..here is my code..

ProgressDialouge pbDialog = new ProgressDialouge(this);
pbDialog.setVisible(true);
pbDialog.toFront();
postPairs.add(new BasicNameValuePair("PATH","authenticateUser.idoc"));
postPairs.add(new BasicNameValuePair("user_email",email));
postPairs.add(new BasicNameValuePair("user_password",password));
JSONArray jArray = asyncService.sendRequest(postPairs);
 if(jArray != null){
            new NewJFrame().setVisible(true);

            this.setVisible(false);
  }

if i change my JDiaog's ModalityType.MODELESS than it does't stop the execution of code but it's also not showing the progress bar..

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Haseeb Wali
  • 1,181
  • 3
  • 14
  • 34

2 Answers2

6

In all likelihood you've got a threading issue where you're running a long-running task on the Swing event thread, preventing the event thread from updating the GUI. The solution is to use a background thread such as one provided by a SwingWorker.

My guess is that the offending line is this one:

JSONArray jArray = asyncService.sendRequest(postPairs);

So again, do this in a background thread. For more on this, please check out this link: Concurrency in Swing

For example:

import java.awt.Point;
import java.awt.Window;
import java.awt.event.ActionEvent;

import javax.swing.*;

public class ShowSwingWorker {
   private JPanel mainPanel = new JPanel();
   private JButton myBtn = null;
   private ProgressDialouge pbDialog = null;

   public ShowSwingWorker() {
      myBtn = new JButton(new AbstractAction("Push Me") {

         @Override
         public void actionPerformed(ActionEvent evt) {
            JButton source = (JButton) evt.getSource();
            source.setEnabled(false); // disable button
            Window win = SwingUtilities.getWindowAncestor(source);
            new MySwingWorker().execute(); // start background thread

            if (pbDialog == null) {
               pbDialog = new ProgressDialouge(win);               
               pbDialog.pack();
               pbDialog.setLocationRelativeTo(win);
               Point loc = pbDialog.getLocation();
               pbDialog.setLocation(loc.x - 100, loc.y - 100);
            }
            pbDialog.setVisible(true);
            // pbDialog.toFront();
         }
      });

      mainPanel.add(myBtn);
   }

   public JComponent getMainPanel() {
      return mainPanel;
   }

   private class MySwingWorker extends SwingWorker<Void, Void> {
      @Override
      protected Void doInBackground() throws Exception {
         Thread.sleep(4000); // emulate a long-running task

         // postPairs.add(new BasicNameValuePair("PATH",
         // "authenticateUser.idoc"));
         // postPairs.add(new BasicNameValuePair("user_email", email));
         // postPairs.add(new BasicNameValuePair("user_password", password));
         // JSONArray jArray = asyncService.sendRequest(postPairs);
         // if (jArray != null) {
         // new NewJFrame().setVisible(true);
         //
         // this.setVisible(false);
         // }
         return null;
      }

      @Override
      protected void done() {
         // Here you change your display.
         // you were swapping JFrames, but I recommend that you instead change views.
         myBtn.setEnabled(true);
         pbDialog.setVisible(false);
      }
   }

   private class ProgressDialouge extends JDialog {

      public ProgressDialouge(Window win) {
         super(win, "MyDialog", ModalityType.APPLICATION_MODAL);
         JProgressBar pBar = new JProgressBar();
         pBar.setIndeterminate(true);
         add(pBar);
      }

   }

   private static void createAndShowGUI() {
      ShowSwingWorker paintEg = new ShowSwingWorker();

      JFrame frame = new JFrame("ShowSwingWorker");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(paintEg.getMainPanel());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGUI();
         }
      });
   }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
-2

The line pbDialog.setVisible(true) will block until the dialog is dismissed in the case of a modal dialog. If you want to have the dialog open without blocking you have to make it non-modal. Whatever stops your animation from working is probably due to writing synchronous code to repaint the dialog. You need to leverage the EventQueue to redraw the frames periodically. You could use a separate thread, or you could use some simpler code that doesn't require a thread like this:

public void paintComponent(Graphics g) {
    if( animate ) {
       Graphics2D g2d = (Graphics2D)g;
       BufferedImage frame = frames[currentFrame];
       g2d.drawImage(frame, null, x, y);
       frame.draw( g );
       currentFrame = (currentFrame + 1) % frames.length;
       repaint(); // this call will schedule a repaint at some point later.
    }
}

That requires no threads which is a good thing in terms of resources, and less likely to screw up and violate swing's single thread rule. You can also look at:

http://docs.oracle.com/javase/6/docs/api/java/awt/Graphics2D.html#drawImage(java.awt.Image, java.awt.geom.AffineTransform, java.awt.image.ImageObserver)

For performing animations across things like animated gifs.

chubbsondubs
  • 37,646
  • 24
  • 106
  • 138
  • 1) His dialog is already a non-modal dialog. 2) Why are you recommending that he call repaint() from within the paintComponent method? This should not be done. Please fix this soon. – Hovercraft Full Of Eels Dec 28 '12 at 03:18
  • 1) He doesn't seem to realize the difference between modal and non-modal and why it performs that way. I wanted to make it clear he needs non-modal. 2) There's nothing wrong with calling repaint within paint if you want it to redraw the component. This saves the use of a thread just to do the exactly same thing (ie call repaint()). You don't need a thread dedicated to invoking repaint(). Repaint will schedule something on the EventQueue to redraw the component. – chubbsondubs Dec 28 '12 at 03:24
  • The cost of using a Thread or a Swing Timer is minimal, and with a Thread or Timer you can control the speed and control stopping or stopping the animation. A basic rule to follow is that paint and paintComponent should be used for painting and painting only. It should never be used for program logic, or to set the state of the GUI or for animation. – Hovercraft Full Of Eels Dec 28 '12 at 03:41