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