title: How to really close a JDialog with Java code?
body: <p>I know <code>setVisible(false)</code>,<code>dispose()</code>,but they can't really close a JDialog. When I have the other thread stop, the thread of the JDialog still runs.</p>
  
  <p>And I can't use <code>System.exit(0)</code>,because the other thread needs run for a while.</p>
  
  <p>Following the code, I finally resolve the problem by System.exit(0) at the end of the program.</p>
  
  <pre><code>public class CsUpdateCtrl {
  
  /**
   * 升级service
   */
  private CsUpdateService service;
  
  private CsUpdateCtrl() {
      this.service = (CsUpdateService) RmiUtil.getBean(RmiUtil.Service.csupdate);
  }
  
  private static final Logger log = Logger.getLogger(CsUpdateCtrl.class.getName());
  
  public static void main(String[] args) throws IOException {
  
      LogUtil.read();
  
      log.info("进入自动更新系统");
  
      CsUpdateCtrl ctrl = null;
      try {
          ctrl = new CsUpdateCtrl();
      } catch (Exception e) {
          SwingUtil.lookAndFeel();
          SwingUtil.message("无法连接服务器!");
          log.info("无法连接服务器:" + e.getMessage());
          return;
      }
      ctrl.start(ctrl.service.version());
  }
  
  /**
   * 根据版本号判断是否更新，更新完毕则启动程序
   */
  private void start(int version) {
      PropertyIO io = new PropertyIO();
      String oldVersion = io.get(PropertyKey.version);
      String serverAddress = io.get(PropertyKey.serverAddress);
      if (oldVersion == null || !oldVersion.equals(String.valueOf(version))) {// 版本号不相等,下载更新程序
          log.info("下载更新…");
          DownLoad download1 = new DownLoad("http://" + serverAddress + "sdxg-csupdate/sdxg-csclient/sdxg-csclient.jar", "sdxg-csclient\\sdxg-csclient.jar");
          Thread t1 = new Thread(download1);
          DownLoad download2 = new DownLoad("http://" + serverAddress + "sdxg-csupdate/sdxg-csclient/lib/sdxg-web.jar", "sdxg-csclient\\lib\\sdxg-web.jar");
          Thread t2 = new Thread(download2);
          t1.start();
          t2.start();
          SwingUtil.lookAndFeel();
          final DownloadView dialog = new DownloadView(new javax.swing.JFrame(), true);
          java.awt.EventQueue.invokeLater(new Runnable() {
              @Override
              public void run() {
                  dialog.setVisible(true);
              }
          });
          // 结果判断
          // 若未完成,则不进行下一步
          while(!download1.result.finish() || !download2.result.finish()) {
              // do nothing
          }
          if(download1.result == Result.Complete &amp;&amp; download2.result == Result.Complete) {// 更新完成
              // 版本号写入配置文件
              io.write(PropertyKey.version, String.valueOf(version));
              // Nothing is usefull here, include dispose,dispatchEvent and so on
              // 启用应用程序
              log.info("启用应用程序");
              this.runApp();
              System.exit(0);// well, this is usefull
          } else {// 更新失败
              // Nothing is usefull here, include dispose,dispatchEvent and so on
              JOptionPane.showMessageDialog(null, "下载应用程序失败!");
              log.info("下载应用程序失败!");
              System.exit(0);// well, this is usefull
          }
      }else {// 版本号一样
          log.info("启用应用程序");
          this.runApp();
      }
  }
  
  /**
   * 运行客户端程序
   */
  private void runApp() {
      try {
          Runtime.getRuntime().exec("java -jar " + "sdxg-csclient\\sdxg-csclient.jar");
      } catch (IOException ex) {
          JOptionPane.showMessageDialog(null, "启动应用程序失败!");
          log.info(LogUtil.ex(ex, "启动应用程序失败!"));
      }
  }
  
  /**
   * 线程执行的结果
   */
  enum Result {
      Complete,
      UnComplete,
      Fail;
  
      public boolean finish() {
          return this != UnComplete;
      }
  }
  
  /**
   * 下载文件
   * @param urlName
   * @param fileName
   * @throws MalformedURLException
   * @throws IOException 
   */
  class DownLoad implements Runnable {
  
      private String urlName;
      private String fileName;
  
      Result result = Result.UnComplete;
  
      public DownLoad(String urlName, String fileName) {
          this.urlName = urlName;
          this.fileName = fileName;
      }
  
      @Override
      public void run() {
          try {
              URL url = new URL(urlName);
              HttpURLConnection connection = (HttpURLConnection) url.openConnection();
              InputStream is = connection.getInputStream();
              BufferedInputStream bis = new BufferedInputStream(is);
              FileOutputStream fos = new FileOutputStream(fileName);
              int n = -1;
              while ((n = bis.read()) != -1) {
                  fos.write(n);
              }
              fos.flush();
              fos.close();
              bis.close();
              is.close();
              result = Result.Complete;
          } catch (Exception ex) {
              result = Result.Fail;
          }
      }
  }
  </code></pre>