简体   繁体   English

单击“ X”按钮时,JFrame将不会关闭

[英]JFrame will not close when “X” button is clicked

The JFrame will not shut down when the default "X" button is clicked. 单击默认的“ X”按钮时,JFrame不会关闭。 I think this problem has something to do with the main thread not being read, but I don't understand the intricacies of swing or honestly, threads in general. 我认为这个问题与未读取主线程有关,但我不理解一般来说,swing或说实话的复杂性。 "Window" is an extension of JFrame, "Boxy" drives the program. “窗口”是JFrame的扩展,“ Boxy”驱动程序。 Program is only in initial stages. 程序仅处于初始阶段。 Also, I'd like to know how to get the main thread run on every loop-over. 另外,我想知道如何在每次循环中运行主线程。 Couldn't find anything about this in other questions. 在其他问题中找不到关于此的任何内容。

public class Window extends JFrame implements KeyListener{
    private static final long serialVersionUID = 1L;
JPanel panel;
public Window(){
    super("FileTyper");
    super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    super.setSize(200,100);
    super.setResizable(false);
    panel = new JPanel();
    super.getContentPane().add(panel);
    super.setFocusable(true);
    addKeyListener(this);

    super.setVisible(true);
}
public void update(){

}
public void render(Graphics2D g){

}
@Override
public void keyPressed(KeyEvent e) {

}
@Override
public void keyReleased(KeyEvent e) {
    switch(e.getKeyCode()) {
    case KeyEvent.VK_F9:
        break;
    case KeyEvent.VK_F10:
        break;
    }

}
@Override
public void keyTyped(KeyEvent arg0) {

}

} }

public class Boxy {
public Window window;

public static void main (String args[]){
    start();
}
public Boxy(){
    init();
    boolean forever = true;
    while(forever){
        update();
        render();
        delay();
    }
}
private void init(){
    window = new Window();
}
private void update(){
    window.update();
}
private void render(){
    Graphics2D g2 = (Graphics2D) window.getContentPane().getGraphics();
    window.render(g2);
    g2.fillRect(0, 0, 100, 100);
}
private void delay(){
    try {Thread.sleep(20);} catch (InterruptedException ex) {System.out.println("ERROR: Delay compromised");}
}
public static void start(){
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            Boxy box = new Boxy();
        }
    });
}
}

Your program's "game" loop is incorrect: 您的程序的“游戏”循环不正确:

while(forever){
    update();
    render();
    delay();
}

Rather than looping the program, it freezes it by tying up the Swing event thread or EDT (for E vent D ispatch T hread). 它不会循环程序,而是通过绑定Swing事件线程或EDT(对于E vent D ispatch T hread)来冻结它。 You should use a Swing Timer instead for this functionality. 您应该使用摇摆计时器代替此功能。

I would suggest that you are blocking the Event Dispatching Thread with 我建议您使用以下方式阻止事件调度线程

while(forever){
    update();
    render();
    delay();
}

This is preventing the Event Queue from processing the event that would close the window. 这阻止了事件队列处理将关闭窗口的事件。

Start by taking a look at Concurrency in Swing . 首先看一下Swing中的并发 I would suggest you might like to take a look at something like javax.swing.Timer to start with, but if you want more control of the frame rate, you're going to need to use some kind of Thread . 我建议您首先看一下像javax.swing.Timer东西,但是如果您想更好地控制帧速率,则需要使用某种Thread Remember though, Swing expects all updates to be executed from within the context of the Event Dispatching Thread. 不过请记住,Swing希望所有更新都将从事件调度线程的上下文中执行。

Custom painting in Swing is not done by using something like... Swing中的自定义绘画无法通过使用诸如...

Graphics2D g2 = (Graphics2D) window.getContentPane().getGraphics();

The Graphics context is short lived, anything your paint to it (using this method) will be destroyed on the next paint cycle. Graphics上下文的寿命很短,在下一个绘制周期中,您使用它绘制的任何内容(使用此方法)都将被破坏。

Instead, you should use something like a JPanel as the bases for your painting and override it's paintComponent method and render the state from within it, when ever it is called. 相反,应该使用JPanel类的东西作为绘画的基础,并覆盖它的paintComponent方法,并在paintComponent调用它时从其中渲染状态。

You would then simply need to call repaint when you want to update the component. 然后,您只需要在要更新组件时调用repaint

Take a look at Performing Custom Painting for more details. 有关更多详细信息,请参见“ 执行自定义绘画 ”。

I would also recommend that you take a look at How to use Key Bindings as an aletrnative to KeyListener 我还建议您看一下如何使用键绑定作为KeyListener的代名词

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM