Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java图形程序未按预期关闭_Java_Swing - Fatal编程技术网

Java图形程序未按预期关闭

Java图形程序未按预期关闭,java,swing,Java,Swing,我试图在内置Java图形系统的基础上创建一种简化的图形库。我想在教学中使用它,这样学生就可以创建图形程序,而无需创建自己的类,或者特别需要使用继承 无论如何,就我所知,窗户并没有像我期望的那样关闭,我也不知道为什么。奇怪的是,如果我在主程序循环中有一个println,它就可以工作了。发生什么事?下面是一个简单的例子: package test; import javax.swing.JFrame; import java.awt.event.WindowListener; import jav

我试图在内置Java图形系统的基础上创建一种简化的图形库。我想在教学中使用它,这样学生就可以创建图形程序,而无需创建自己的类,或者特别需要使用继承

无论如何,就我所知,窗户并没有像我期望的那样关闭,我也不知道为什么。奇怪的是,如果我在主程序循环中有一个println,它就可以工作了。发生什么事?下面是一个简单的例子:

package test;

import javax.swing.JFrame;
import java.awt.event.WindowListener;
import java.awt.event.WindowEvent;
import java.util.Queue;
import java.util.LinkedList;

/** enumeration of the different types of events which a window can produce */
enum EventType {
    Closed,
    KeyPressed,
    KeyReleased,
    MousePressed,
    MouseReleased,
    MouseMoved
}

/** a class which represents an event which a window can produce */
class Event {
    private EventType t;

    /** create a new event of a given type */
    public Event(EventType type) {
        t = type;
    }

    /** check which type of event it is */
    public EventType getType( ) {
        return t;
    }
}

/** a graphics window */
class Window implements WindowListener {
    private JFrame frame;
    private boolean open;
    private Queue<Event> events;

    /** create the window */
    public Window(String title, int width, int height, boolean resizable) {
        frame = new JFrame(title);
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.setSize(width, height);
        frame.setResizable(resizable);
        frame.setVisible(true);
        frame.addWindowListener(this);
        events = new LinkedList<>( );
        open = true;
    }

    /** checks whether the window is still open or not */
    public boolean isOpen( ) {
        return open;
    }

    /** closes the window */
    public void close( ) {
        open = false;
        frame.dispose( );
    }

    /** returns the next event, or null if there is none */
    public Event pollEvent( ) {
        return events.poll( );
    }

    /* functions which implement window listening */
    public void windowOpened(WindowEvent e) { }
    public void windowIconified(WindowEvent e) { }
    public void windowDeiconified(WindowEvent e) { }
    public void windowActivated(WindowEvent e) { }
    public void windowDeactivated(WindowEvent e) { }
    public void windowClosed(WindowEvent e) { }
    public void windowClosing(WindowEvent e) {
        System.out.println("Adding close event");
        events.add(new Event(EventType.Closed));
    }
}

public class Test {
    public static void main(String args[]) {
        // create the window
        Window window = new Window("Hello world!", 800, 600, false);

        // while the window is open
        while (window.isOpen( )) {
            // check for events
            Event event = window.pollEvent( );
            if (event != null) {
                switch (event.getType( )) {
                    // handle the window close event
                    case Closed:
                        System.out.println("Calling close");
                        window.close( );
                        break;
                }
            }

            // when this line is un-commented, it works as expected???
            //System.out.print('.');
        }
        System.out.println("All done!");
    }
}
试着改变

frame.setDefaultCloseOperationJFrame.DO\u NOTHING\u打开\u关闭

frame.setDefaultCloseOperationJFrame.DISPOSE\u ON\u CLOSE

试试换衣服

frame.setDefaultCloseOperationJFrame.DO\u NOTHING\u打开\u关闭

frame.setDefaultCloseOperationJFrame.DISPOSE\u ON\u CLOSE

确保您正在从中调用dispose。这应该适合您:

   switch (event.getType()) {
    // handle the window close event
        case Closed:
            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    System.out.println("Calling close");
                    window.close();
                }
            });

            break;
    }
确保您正在从中调用dispose。这应该适合您:

   switch (event.getType()) {
    // handle the window close event
        case Closed:
            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    System.out.println("Calling close");
                    window.close();
                }
            });

            break;
    }

好的,我知道了。问题是Java事件线程和我的主线程之间缺乏同步。我的主线程不断调用,从事件队列中提取事件

然后Java事件线程会在某个时候将close事件添加到队列中。这是不同步的,因此事件不知何故丢失了。我猜它是在检查队列时调用的,没有提交

将synchronized关键字添加到windowClosing中,使事件排队,pollEvent修复了该问题


谢谢大家

好吧,我想出来了。问题是Java事件线程和我的主线程之间缺乏同步。我的主线程不断调用,从事件队列中提取事件

然后Java事件线程会在某个时候将close事件添加到队列中。这是不同步的,因此事件不知何故丢失了。我猜它是在检查队列时调用的,没有提交

将synchronized关键字添加到windowClosing中,使事件排队,pollEvent修复了该问题



谢谢大家

不相关,但为什么括号之间有空格window.close?@LuxxMiner,我想显式捕捉结束符,这就是我实现WindowListener的原因。根据文档,这应该是一个正常的方法?@MuratK。可能是一个代码格式化程序设置。。。例如,您可以在Eclipse中定义相同的内容……您能告诉我您想要实现什么吗?我已经启动了这个程序,在关闭它之后,我添加了关闭事件调用close All done@穆拉克。那正是我的风格。我知道这很不寻常,但它们在我看来也很奇怪。我可能应该学着这样做……不相关,但是为什么在括号之间有空格window.close?@LuxxMiner,我想显式地捕捉结束,这就是我实现WindowListener的原因。根据文档,这应该是一个正常的方法?@MuratK。可能是一个代码格式化程序设置。。。例如,您可以在Eclipse中定义相同的内容……您能告诉我您想要实现什么吗?我已经启动了这个程序,在关闭它之后,我添加了关闭事件调用close All done@穆拉克。那正是我的风格。我知道这很不寻常,但它们在我看来也很奇怪。我可能应该学着这样做,但这并没有真正的帮助。它确实会导致窗口关闭,但程序仍然永远挂起,永远不会完成main。删除while循环,它看起来可能是一个无限循环。设置DISPOSE\u ON\u CLOSE应该在windows关闭时完全停止VM。这是有道理的,但我不希望它这样工作。我想在基于回调的API之上添加一个过程式API。这样你就可以在一个主函数中编写图形程序了,但这并没有什么帮助。它确实会导致窗口关闭,但程序仍然永远挂起,永远不会完成main。删除while循环,它看起来可能是一个无限循环。设置DISPOSE\u ON\u CLOSE应该在windows关闭时完全停止VM。这是有道理的,但我不希望它这样工作。我想在基于回调的API之上添加一个过程式API。这样您就可以只在主函数中编写图形程序了。@JamesWierzba它是从他的window.close方法调用的。非常感谢。这并不是我所需要的,但谈到我从未听说过的EDT,我找到了答案。谢谢@JamesWierzba从他的窗口调用。关闭方法。非常感谢。这并不是我所需要的,但谈到我从未听说过的EDT,我找到了答案。谢谢