java swing 退出程序_如何从cod中关闭Java Swing应用程序

在Java Swing中,要正确地从代码中关闭应用程序,通常需要设置JFrame的默认关闭操作为`DISPOSE_ON_CLOSE`。然而,这样做可能无法完全终止应用,尤其是存在未关闭的线程或窗口。确保关闭所有窗口并停止非守护线程,如Timer,是至关重要的。可以使用WindowListener或在关闭事件中执行清理操作。`EXIT_ON_CLOSE`可能导致立即关闭,但不推荐在需要清理时使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如何从cod中关闭Java Swing应用程序

从代码中终止Swing应用程序的正确方法是什么,有哪些陷阱?

我试图在计时器启动后自动关闭我的应用程序。 但是只是在JFrame上拨打dispose()并没有做到这一点 - 窗口消失但应用程序没有终止。 但是,当使用关闭按钮关闭窗口时,应用程序会终止。 我该怎么办?

hstoerr asked 2019-08-25T21:22:22Z

9个解决方案

102 votes

您的JFrame默认关闭操作可以设置为" DISPOSE_ON_CLOSE" 而不是Frame.getFrames()(为什么人们继续使用EXIT_ON_CLOSE超出我的意义)。

如果您有任何未曝光的窗口或非守护程序线程,您的应用程序将不会终止。 这应该被认为是一个错误(并使用System.exit解决它是一个非常糟糕的主意)。

最常见的罪魁祸首是java.util.Timer和你创建的自定义线程。 两者都应该设置为守护进程或必须被明确杀死。

如果要检查所有活动帧,可以使用Frame.getFrames().如果处理掉所有Windows /帧,则使用调试器检查仍在运行的任何非守护程序线程。

James Schek answered 2019-08-25T21:22:56Z

34 votes

我想一个EXIT_ON_CLOSE

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

在System.exit(0)之前更好,因为您可以在实际离开应用程序之前编写一个Window Listener来进行一些清理操作。

那个窗口监听器允许你定义:

public void windowClosing(WindowEvent e) {

displayMessage("WindowListener method called: windowClosing.");

//A pause so user can see the message before

//the window actually closes.

ActionListener task = new ActionListener() {

boolean alreadyDisposed = false;

public void actionPerformed(ActionEvent e) {

if (frame.isDisplayable()) {

alreadyDisposed = true;

frame.dispose();

}

}

};

Timer timer = new Timer(500, task); //fire every half second

timer.setInitialDelay(2000); //first delay 2 seconds

timer.setRepeats(false);

timer.start();

}

public void windowClosed(WindowEvent e) {

//This will only be seen on standard output.

displayMessage("WindowListener method called: windowClosed.");

}

VonC answered 2019-08-25T21:23:35Z

14 votes

尝试:

System.exit(0);

原油,但有效。

Daniel Spiewak answered 2019-08-25T21:24:02Z

11 votes

可能是安全的方式是这样的:

private JButton btnExit;

...

btnExit = new JButton("Quit");

btnExit.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e){

Container frame = btnExit.getParent();

do

frame = frame.getParent();

while (!(frame instanceof JFrame));

((JFrame) frame).dispose();

}

});

Kachwahed answered 2019-08-25T21:24:27Z

9 votes

以下程序包括将在没有显式调用System.exit()的情况下终止缺少无关线程的程序的代码。 为了将此示例应用于使用线程/侦听器/定时器/等的应用程序,在actionPerformed()中手动启动WindowEvent之前,只需要插入清除代码请求(以及,如果适用,等待)它们的终止。

对于那些希望复制/粘贴能够完全按照所示运行的代码的人来说,最后会包含一个稍微丑陋但不相关的主要方法。

public class CloseExample extends JFrame implements ActionListener {

private JButton turnOffButton;

private void addStuff() {

setDefaultCloseOperation(DISPOSE_ON_CLOSE);

turnOffButton = new JButton("Exit");

turnOffButton.addActionListener(this);

this.add(turnOffButton);

}

public void actionPerformed(ActionEvent quitEvent) {

/* Iterate through and close all timers, threads, etc here */

this.processWindowEvent(

new WindowEvent(

this, WindowEvent.WINDOW_CLOSING));

}

public CloseExample() {

super("Close Me!");

addStuff();

}

public static void main(String[] args) {

java.awt.EventQueue.invokeLater(new Runnable() {

public void run() {

CloseExample cTW = new CloseExample();

cTW.setSize(200, 100);

cTW.setLocation(300,300);

cTW.setVisible(true);

}

});

}

}

Eric Sadler answered 2019-08-25T21:25:00Z

4 votes

如果我理解正确,即使用户没有点击关闭按钮,也要关闭应用程序。 您可能需要使用addWindowListener()或enableEvents()注册WindowEvents,以更好地满足您的需求。

然后,您可以通过调用processWindowEvent()来调用该事件。 下面是一个示例代码,它将创建一个JFrame,等待5秒并关闭JFrame而无需用户交互。

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

public class ClosingFrame extends JFrame implements WindowListener{

public ClosingFrame(){

super("A Frame");

setSize(400, 400);

//in case the user closes the window

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setVisible(true);

//enables Window Events on this Component

this.addWindowListener(this);

//start a timer

Thread t = new Timer();

t.start();

}

public void windowOpened(WindowEvent e){}

public void windowClosing(WindowEvent e){}

//the event that we are interested in

public void windowClosed(WindowEvent e){

System.exit(0);

}

public void windowIconified(WindowEvent e){}

public void windowDeiconified(WindowEvent e){}

public void windowActivated(WindowEvent e){}

public void windowDeactivated(WindowEvent e){}

//a simple timer

class Timer extends Thread{

int time = 10;

public void run(){

while(time-- > 0){

System.out.println("Still Waiting:" + time);

try{

sleep(500);

}catch(InterruptedException e){}

}

System.out.println("About to close");

//close the frame

ClosingFrame.this.processWindowEvent(

new WindowEvent(

ClosingFrame.this, WindowEvent.WINDOW_CLOSED));

}

}

//instantiate the Frame

public static void main(String args[]){

new ClosingFrame();

}

}

正如您所看到的,processWindowEvent()方法会导致触发WindowClosed事件,如果您在关闭应用程序之前需要执行某些清理代码,则会触发该事件。

Vincent Ramdhanie answered 2019-08-25T21:25:40Z

2 votes

查看Oracle文档。

从JDK 1.4开始,应用程序在以下情况下终止:

没有可显示的AWT或Swing组件。

本机事件队列中没有本机事件。

java EventQueues中没有AWT事件。

Cornercases:

该文档声明某些包创建可显示的组件而不释放它们。调用Toolkit.getDefaultToolkit()的程序不会终止。 是作为一个例子给出的。

当其他原因将其发送到本机事件队列时,其他进程也可以使AWT保持活动状态。

另外我注意到在某些系统上,在应用程序实际终止之前需要几秒钟。

Reiner Lange answered 2019-08-25T21:27:02Z

0 votes

我认为,这个想法就在这里WindowListener - 你可以添加任何你希望在事情关闭之前运行的代码

Tamas Rev answered 2019-08-25T21:27:27Z

0 votes

为了响应其他注释,DISPOSE_ON_CLOSE似乎没有正确退出应用程序 - 它只会破坏窗口,但应用程序将继续运行。 如果要终止应用程序,请使用EXIT_ON_CLOSE。

JSideris answered 2019-08-25T21:27:52Z

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值