JDialog Stops execution of parent JFrame

2019-03-03 22:30发布

问题:

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..

回答1:

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();
         }
      });
   }
}


回答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.