有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

单击默认的“X”按钮时,JFrame不会关闭。我认为这个问题与主线程没有被读取有关,但我不理解swing的复杂性,或者说实话,一般的线程。“窗口”是JFrame的扩展,“Boxy”驱动程序。该计划仅处于初始阶段。另外,我想知道如何在每个循环上运行主线程。在其他问题中找不到与此相关的任何信息

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();
        }
    });
}
}

共 (2) 个答案

  1. # 1 楼答案

    您的程序的“游戏”循环不正确:

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

    它不是循环程序,而是通过绑定Swing事件线程或EDT(对于EventDispatchThread)来冻结程序。对于此功能,您应该使用Swing计时器

  2. # 2 楼答案

    我建议您使用阻止事件调度线程

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

    这将阻止事件队列处理将关闭窗口的事件

    首先看一下Concurrency in Swing。我建议您首先看一下类似javax.swing.Timer的东西,但是如果您想要更多地控制帧速率,您需要使用某种Thread。但是请记住,Swing希望所有更新都在事件调度线程的上下文中执行

    Swing中的自定义绘制不是通过使用

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

    Graphics上下文是短暂的,您对其进行的任何绘制(使用此方法)都将在下一个绘制周期中销毁

    相反,您应该使用类似于JPanel的东西作为绘制的基础,覆盖它的paintComponent方法,并在调用它时从其中渲染状态

    然后,当您想要更新组件时,只需调用repaint

    有关更多详细信息,请查看Performing Custom Painting

    我还建议您将How to use Key Bindings视为KeyListener的本地语言