Java 在游戏循环之前或中运行时不显示Swing组件

Java 在游戏循环之前或中运行时不显示Swing组件,java,swing,components,event-dispatch-thread,Java,Swing,Components,Event Dispatch Thread,实际上,我正在尝试修复JFrame组件的一个问题,该组件在我运行游戏循环时不希望出现(请参见代码后面的问题)。我已将代码减少到最低限度,以便您快速理解我的意思: Run.class public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { Game game = new Ga

实际上,我正在尝试修复
JFrame
组件的一个问题,该组件在我运行游戏循环时不希望出现(请参见代码后面的问题)。我已将代码减少到最低限度,以便您快速理解我的意思:

Run.class

public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            Game game = new Game();
            game.loop();
        }
    });
}
private Frame frame;
private HashMap<String,ActionListener> actions;
private HashMap<String,Image> ressources;

public Game() {
    this.setActions();
    this.setRessources();
    frame = new Frame(actions,ressources);
}
public void loop() {
    double FPS = 60;
    double UPS = 60;
    long initialTime = System.nanoTime();
    final double timeU = 1000000000 / UPS;
    final double timeF = 1000000000 / FPS;
    double deltaU = 0, deltaF = 0;
    int frames = 0, ticks = 0;
    long timer = System.currentTimeMillis();
    boolean running = true;
    boolean RENDER_TIME = false;

    while (running) {
        ...code for update, render, with a fps control
    }
}
public Frame(HashMap<String,ActionListener> actions, HashMap<String,Image> ressources) {

    this.setTitle(Constants.GAME_NAME);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setSize(Constants.GAME_SIZE_X, Constants.GAME_SIZE_Y);
    this.setLayout(new FlowLayout());

    JButton myButton = new JButton("My Button");
    this.add(myButton);

    this.revalidate();
    this.repaint();
    this.setVisible(true);
}
游戏类

public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            Game game = new Game();
            game.loop();
        }
    });
}
private Frame frame;
private HashMap<String,ActionListener> actions;
private HashMap<String,Image> ressources;

public Game() {
    this.setActions();
    this.setRessources();
    frame = new Frame(actions,ressources);
}
public void loop() {
    double FPS = 60;
    double UPS = 60;
    long initialTime = System.nanoTime();
    final double timeU = 1000000000 / UPS;
    final double timeF = 1000000000 / FPS;
    double deltaU = 0, deltaF = 0;
    int frames = 0, ticks = 0;
    long timer = System.currentTimeMillis();
    boolean running = true;
    boolean RENDER_TIME = false;

    while (running) {
        ...code for update, render, with a fps control
    }
}
public Frame(HashMap<String,ActionListener> actions, HashMap<String,Image> ressources) {

    this.setTitle(Constants.GAME_NAME);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setSize(Constants.GAME_SIZE_X, Constants.GAME_SIZE_Y);
    this.setLayout(new FlowLayout());

    JButton myButton = new JButton("My Button");
    this.add(myButton);

    this.revalidate();
    this.repaint();
    this.setVisible(true);
}
私有帧;
私有HashMap操作;
私有HashMap资源;
公共游戏(){
这个.setActions();
这个.setResources();
框架=新框架(动作、资源);
}
公共void循环(){
双FPS=60;
双UPS=60;
long initialTime=System.nanoTime();
最终双倍时间U=100000000/UPS;
最终双倍时间=100000000/FPS;
双deltaU=0,deltaF=0;
int frames=0,ticks=0;
长定时器=System.currentTimeMillis();
布尔运行=真;
布尔渲染时间=false;
(跑步时){
…使用fps控件进行更新、渲染的代码
}
}
Frame.class

public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            Game game = new Game();
            game.loop();
        }
    });
}
private Frame frame;
private HashMap<String,ActionListener> actions;
private HashMap<String,Image> ressources;

public Game() {
    this.setActions();
    this.setRessources();
    frame = new Frame(actions,ressources);
}
public void loop() {
    double FPS = 60;
    double UPS = 60;
    long initialTime = System.nanoTime();
    final double timeU = 1000000000 / UPS;
    final double timeF = 1000000000 / FPS;
    double deltaU = 0, deltaF = 0;
    int frames = 0, ticks = 0;
    long timer = System.currentTimeMillis();
    boolean running = true;
    boolean RENDER_TIME = false;

    while (running) {
        ...code for update, render, with a fps control
    }
}
public Frame(HashMap<String,ActionListener> actions, HashMap<String,Image> ressources) {

    this.setTitle(Constants.GAME_NAME);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setSize(Constants.GAME_SIZE_X, Constants.GAME_SIZE_Y);
    this.setLayout(new FlowLayout());

    JButton myButton = new JButton("My Button");
    this.add(myButton);

    this.revalidate();
    this.repaint();
    this.setVisible(true);
}
公共帧(HashMap操作、HashMap资源){
这个.setTitle(常量.GAME_NAME);
此.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
这个.setSize(常数.GAME\u SIZE\u X,常数.GAME\u SIZE\u Y);
this.setLayout(新的FlowLayout());
JButton myButton=新JButton(“我的按钮”);
这个.add(我的按钮);
这个。重新验证();
这个。重新绘制();
此.setVisible(true);
}
这不是完整的代码,因为我不想给一个无用的东西。因此,我的问题是:

如果我运行此代码,按钮将不会显示在帧中。但是如果我在Run.class中注释
game.loop()
,窗口就会显示该按钮。我不明白为什么?

我已经试了几天想弄明白。我需要一些帮助。恐怕我一个人无法发现。

要想通过运行一个较长的进程来避免阻塞,您可以使用swing,它可以为您处理“循环”:

ActionListener animate = e -> {
    game.oneFrame();
    panel.repaint();  
};
timer = new Timer(50, animate); 
timer.start(); 

public void oneFrame(){
   //update what is needed for one "frame"
}
有关mcve后的更多帮助。

1)不要阻止EDT(事件调度线程)。发生这种情况时,GUI将“冻结”。有关详细信息和修复方法,请参阅。2) “这不是完整的代码,因为我不想给出无用的东西。”为了更快地获得更好的帮助,请添加or。