【问题标题】:JFrame will not close when "X" button is clicked单击“X”按钮时,JFrame 不会关闭
【发布时间】:2013-10-25 01:08:22
【问题描述】:

单击默认的“X”按钮时,JFrame 不会关闭。我认为这个问题与没有被读取的主线程有关,但我不理解摆动的复杂性,或者说实话,一般来说,线程。 “Window”是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();
        }
    });
}
}

【问题讨论】:

  • 感谢你是一个不使用抽屉式 UI 的初学者

标签: java swing loops jframe


【解决方案1】:

我建议您使用

阻塞事件调度线程
while(forever){
    update();
    render();
    delay();
}

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

首先查看Concurrency in Swing。我建议你先看看javax.swing.Timer 之类的东西,但如果你想更好地控制帧速率,你将需要使用某种Thread。但请记住,Swing 期望所有更新都在 Event Dispatching Thread 的上下文中执行。

Swing 中的自定义绘画不是通过使用类似...的东西来完成的

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

Graphics 上下文是短暂的,任何你对它的绘制(使用此方法)都将在下一个绘制周期被销毁。

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

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

查看Performing Custom Painting了解更多详情。

我还建议您查看How to use Key Bindings 作为KeyListener 的替代品

【讨论】:

  • @HovercraftFullOfEels 我也在想同样的事情,已经 +1 你回答了
  • 有什么快速的解决方法吗?我不打算让这个程序与我看过的其他一些循环类型太长。这些是我程序中的所有类
  • JPanel 扩展Boxy,覆盖它的paintComponent 方法以执行所需的渲染。将此添加到框架中。使用javax.swing.Timer 重复更新 UI...
【解决方案2】:

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

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

它不是循环程序,而是通过绑定 Swing 事件线程或 EDT(对于 Event Dispatch Thread )。您应该使用 Swing Timer 代替此功能。

【讨论】:

    猜你喜欢
    • 2011-01-22
    • 1970-01-01
    • 2022-08-05
    • 2011-02-05
    • 2022-01-18
    • 1970-01-01
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多