Java 如何在游戏循环中调用EDT?

Java 如何在游戏循环中调用EDT?,java,swing,loops,event-dispatch-thread,Java,Swing,Loops,Event Dispatch Thread,我做了别人让我做的关于我的游戏循环的事情,添加了swing定时器等(除了覆盖paintComponent,因为它不适用于这种情况),但是我的游戏循环拒绝调用事件调度线程。因此,JFrame不会关闭,键盘输入被禁用。我可以手动打电话给EDT吗?还是我缺少什么 public class Window extends JFrame implements KeyListener{ private static final long serialVersionUID = 1L; JPanel panel;

我做了别人让我做的关于我的游戏循环的事情,添加了swing定时器等(除了覆盖paintComponent,因为它不适用于这种情况),但是我的游戏循环拒绝调用事件调度线程。因此,JFrame不会关闭,键盘输入被禁用。我可以手动打电话给EDT吗?还是我缺少什么

public class Window extends JFrame implements KeyListener{
private static final long serialVersionUID = 1L;
JPanel panel;
public static int screenX = 500;
public static int screenY = 500;
private int w = 0, h = 0;
public Window(){
    super("FileTyper");
    super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    super.setSize(506,533);
    super.setResizable(false);
    panel = new JPanel();
    super.getContentPane().add(panel);
    super.setFocusable(true);
    addKeyListener(this);

    super.setVisible(true);
}
public void update(){
    w++;h++;
    if(w>500){
        w = 0;
        h = 0;
    }
}
public void render(Graphics2D g){
    g.setColor(Color.CYAN);
    g.fillRect(0,0,500,500);
    g.setColor(Color.black);
    g.fillOval(0, 0, w, h);
}
@Override
public void keyPressed(KeyEvent e) {

}
@Override
public void keyReleased(KeyEvent e) {
    switch(e.getKeyCode()) {
    case KeyEvent.VK_F9:
        panel.getGraphics().setColor(Color.green);
        panel.getGraphics().drawRect(0, 0, 100, 100);
        break;
    case KeyEvent.VK_F10:
        break;
    }

}
@Override
public void keyTyped(KeyEvent arg0) {

}
}

}

  • javax.swing.Timer
    保证分配的
    ActionListener
    方法的
    actionPerformed
    在EDT上下文中被调用
  • 在EDT中运行无限循环现在正在阻止它,从而阻止更新UI
  • 您的
    runGameLoop
    应该更像

    public void runGameLoop()
    {
        Timer timer = new Timer(20, new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                update();
                render();
            }    
        });
        timer.start();
    }
    
    在实施任何建议之前,建议尝试并了解这些建议试图实现的目标

    通读

    更多细节

  • javax.swing.Timer
    保证分配的
    ActionListener
    方法的
    actionPerformed
    在EDT上下文中被调用
  • 在EDT中运行无限循环现在正在阻止它,从而阻止更新UI
  • 您的
    runGameLoop
    应该更像

    public void runGameLoop()
    {
        Timer timer = new Timer(20, new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                update();
                render();
            }    
        });
        timer.start();
    }
    
    在实施任何建议之前,建议尝试并了解这些建议试图实现的目标

    通读


    查看更多详细信息。

    但是仍然可以使用无限循环调用EDT吗?我下载的一个演示程序就是这么做的,尽管我不知道why@Killam:
    “但是仍然可以使用无限循环调用EDT吗?”
    ——这就是使用Swing计时器的全部原因——使用一个不锁定EDT的循环。否则,无限循环将锁定在EDT或其他方式中调用的任何线程。这与Swing无关,而与基本Java有关。1+不,在EDT的上下文中永远不可能使用无限。它将停止EDT处理新事件,包括重新绘制事件。我打赌你的例子使用了某种背景线程除非你有理由控制更新之间的时间,否则Swing
    Timer
    是一个非常好的类。感谢feedbackBut,难道还不能用无限循环调用EDT吗?我下载的一个演示程序就是这么做的,尽管我不知道why@Killam:
    “但是仍然可以使用无限循环调用EDT吗?”
    ——这就是使用Swing计时器的全部原因——使用一个不锁定EDT的循环。否则,无限循环将锁定在EDT或其他方式中调用的任何线程。这与Swing无关,而与基本Java有关。1+不,在EDT的上下文中永远不可能使用无限。它将停止EDT处理新事件,包括重新绘制事件。我打赌您的示例使用了某种背景线程,除非您有理由控制更新之间的时间,否则Swing
    Timer
    是用于此目的的优秀类。感谢您的反馈,您正在通过调用
    thread.sleep
    阻止EDT。这里有多个帖子。您正在通过调用
    Thread.sleep
    阻止EDT。这上面有多个帖子。