JFrame无法通过“X”关闭

5

这段代码以前是完全正常的,但现在它无法完全关闭,似乎会在我点击窗口上的“X”时挂起。当我关闭后,如果我最小化屏幕再将其最大化,它就只有黑屏。唯一能让它完全关闭的方法是退出Eclipse,我的IDE。

在此之前,我的外观和感觉是不同的。我偷了一些GUI代码,在netbeans中制作它使它看起来比我手工做的好看。所以我认为可能是与“nimbus”外观和感觉有关,但也可能是我没有正确地关闭其他对象,因此现在出现了问题?

static CLUtilCompact app = null; // this
static AuxPPanel aux = null; // JPanel
static StatusPanel stat = null; // JPanel
static UserActPanel user = null; // JPanel
static InputPanel input = null; // JPanel
static Automator auto = null;   
        //public class Automator extends Thread 
       //   implements NativeMouseInputListener, NativeKeyListener  

public CLUtilCompact() 
{
    aux = new AuxPPanel();
    stat = new StatusPanel();
    user = new UserActPanel();
    auto = new Automator();
    input = new InputPanel();
    GlobalScreen.getInstance().addNativeKeyListener(auto);
    GlobalScreen.getInstance().addNativeMouseListener(auto);
    GlobalScreen.getInstance().addNativeMouseMotionListener(auto);
    auto.start();
}

public static void main(String[] args) 
{
    // Create the App, and panels
    app = new CLUtilCompact();
    // Let the panels have access to app now
    aux.setApp(app);
    stat.setApp(app);
    user.setApp(app);
    auto.setApp(app);
    app.updateOutput("Started");
    app.updateStatus("Started");
    input.setApp(app);

    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(CLUtilCompact.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(CLUtilCompact.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(CLUtilCompact.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(CLUtilCompact.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            app.setDefaultCloseOperation(EXIT_ON_CLOSE);
            app.setAlwaysOnTop(true);
            app.setVisible(true);
        }
    });
}

自动化程序的运行和关闭

public void run()
{
    try // to make the Global hook
    {
        GlobalScreen.registerNativeHook();
    }
    catch (NativeHookException ex){theApp.updateOutput("No Global Keyboard or Mouse Hook");return;}
    try // to create a robot (can simulate user input such as mouse and keyboard input)
    {
        rob = new Robot();
    } 
    catch (AWTException e1) {theApp.updateOutput("The Robot could not be created");return;}

    while(true) {}
}

public void OnClose()
{
    GlobalScreen.unregisterNativeHook();
}

编辑:在Eclipse中,小红框关闭了它,但是仍然无法自行关闭。

不确定您的意思,您是指当我关闭Eclipse时吗?所有内容都会关闭,程序完全关闭。问题在于当我将其作为可运行的.jar文件时,没有办法关闭它。它甚至不会出现在任务管理器中。 - user1311286
我指的是这个小“X” THIS - CodyBugstein
2
你有一个非守护线程正在运行,这会阻止Swing退出。你在使用什么库来处理全局监听器?我建议你去看一下。 - Hovercraft Full Of Eels
你应该阅读Javadocs。你遇到了一个窗口无法关闭的问题。如果你不知道它是java.awt.Frame还是javax.swing.JFrame,那么你需要一本书或教程。如果你知道它是一个frame,那么就去看看Javadocs吧。JFrame有一些关于如何响应用户尝试关闭窗口的概念...调用setDefaultCloseOperation(int)方法即可。http://docs.oracle.com/javase/6/docs/api/javax/swing/JFrame.html - tgkprog
同时遵循将 JNativeHookSwing 混合使用的一般规则 -- 链接 **在此**。 - Extreme Coders
显示剩余7条评论
6个回答

8

将默认关闭操作设置为“DISPOSE_ON_CLOSE”,而不是EXIT_ON_CLOSE(通用提示)

Hovercraft Full Of Eels的评论非常有用。如果您有任何未处理的窗口或非守护程序线程,则应用程序将无法终止。

检查所有活动框架...使用Frame.getFrames()如果所有Windows / Frames都已处理完毕,则调试以检查是否存在任何仍在运行的非守护程序线程。

一个残忍但有效的解决方案是System.exit(0)

类应实现WindowListener

// Use this method
public void windowClosed(WindowEvent e){
    System.exit(0);
}

我是一个残忍的人,但有时也很优雅。因此从Eels的评论和其他评论来看,这是否意味着我需要使用isDaemon(true)将某些内容标记为守护进程?还是一旦我实际调用了我的OnClose方法,我的守护进程(全局键盘和鼠标监听器)将被关闭,我的程序将死亡并且不会处于僵尸模式中? - user1311286
我认为你不需要担心线程,进程会被清理。如果你有打开的文件,最好将它们刷新并关闭,除此之外,System.exit(0)就可以了。 - tgkprog
请参见http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#exit%28int%29。 - tgkprog

2

我猜测这行代码的作用是

while(true) {}

可能是罪魁祸首。

1

0
 https://dev59.com/OXE95IYBdhLWcg3wV8e_

   JButton button = new JButton("exit");
    button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
   frame.setVisible(false);
            frame.dispose();

        }

0

推测性的。拥有静态(swing)类可以为Nimbus保留一些东西。由于经常使用静态也不太好看,因此尝试将它们作为JFrame应用程序的字段去掉。


-1
我遇到了同样的问题,我只是在最后添加了这段代码,每当它变成黑色并且无法关闭时,我只需输入1,就可以在下一次修复。
Scanner scan=new Scanner(System.in);
int exit=scan.nextInt();
if (exit==1) System.exit(0);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接