如何用Java代码真正关闭JDialog?

我知道setVisible(false)dispose()但是他们不能真正关闭JDialog。当我使另一个线程停止时,JDialog的线程仍然运行。

而且我不能使用System.exit(0),因为其他线程需要运行一段时间。

遵循代码,我终于在程序末尾通过System.exit(0)解决了问题。

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 && 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;

}

}

}

回答:

发送JDialog一个WindowEvent.WINDOW_CLOSING使用事件dispatchEvent()

附录:System.exit()应谨慎使用,在下面的示例中,第二个非守护线程正常完成,即使对话框在退出循环之前已关闭。有关详细信息,请参见JLS§12.8程序退出

import java.awt.EventQueue;

import java.awt.GridLayout;

import java.awt.event.ActionEvent;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import javax.swing.AbstractAction;

import javax.swing.JButton;

import javax.swing.JDialog;

import javax.swing.JLabel;

/**

* @see https://stackoverflow.com/questions/8336161

* @see https://stackoverflow.com/questions/6163606

*/

public class DialogEventTest extends JDialog {

public DialogEventTest() {

this.setLayout(new GridLayout(0, 1));

this.add(new JLabel("Dialog event test.", JLabel.CENTER));

this.add(new JButton(new AbstractAction("Close") {

@Override

public void actionPerformed(ActionEvent e) {

DialogEventTest.this.setVisible(false);

DialogEventTest.this.dispatchEvent(new WindowEvent(

DialogEventTest.this, WindowEvent.WINDOW_CLOSING));

}

}));

this.addWindowListener(new WindowAdapter() {

@Override

public void windowClosing(WindowEvent e) {

System.out.println(e.paramString());

}

});

}

private void display() {

this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

this.pack();

this.setLocationRelativeTo(null);

this.setVisible(true);

}

public static void main(String[] args) {

EventQueue.invokeLater(new Runnable() {

@Override

public void run() {

new DialogEventTest().display();

}

});

new Thread(new Runnable() {

@Override

public void run() {

System.out.println("Starting…");

for (int i = 0; i < 5; i++) {

try {

Thread.sleep(1000);

System.out.println((i + 1) + "s. elapsed.");

} catch (InterruptedException e) {

e.printStackTrace(System.err);

}

}

System.out.println("Finished.");

}

}).start();

}

}

以上是 如何用Java代码真正关闭JDialog? 的全部内容, 来源链接: utcz.com/qa/412964.html

回到顶部