Java Swing JFrame为游戏启动另一个JFrame
我正在用Java开发一个小游戏。我的应用程序有一个主JFrame,可以通过单击JButton创建另一个窗口(游戏窗口)。 我已经单独测试了我的游戏窗口,一切正常 这是我的游戏窗口构造器:Java Swing JFrame为游戏启动另一个JFrame,java,swing,event-dispatch-thread,Java,Swing,Event Dispatch Thread,我正在用Java开发一个小游戏。我的应用程序有一个主JFrame,可以通过单击JButton创建另一个窗口(游戏窗口)。 我已经单独测试了我的游戏窗口,一切正常 这是我的游戏窗口构造器: public GameWindow(final GameController controller) { super("Boulder Dash Game"); this.controller = controller; this.controller.registerObserver
public GameWindow(final GameController controller)
{
super("Boulder Dash Game");
this.controller = controller;
this.controller.registerObserver(getCurrentFrame());
this.gamePanel = new GamePanel(controller);
this.frameWidth = controller.getColumns() * 16;
this.frameHeight = controller.getRows() * 16 + 76;
getContentPane().add(gamePanel, BorderLayout.CENTER);
setSize(frameWidth, frameHeight);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
controller.startGame();
}
方法启动游戏循环。
当我直接从主窗口启动此窗口时,游戏循环工作正常
现在,我想从我的主框架启动这个游戏窗口框架。
以下是我的主框架中的代码:
playButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final @Nullable ActionEvent e)
{
String selectedItem = (String) levelsComboBox.getSelectedItem();
assert selectedItem != null;
controller.lauchGame(selectedItem);
}
});
controller.launchGame(String selectedItem)是一种用于加载游戏级别和启动游戏窗口的方法。
这是密码
public void lauchGame(final String levelQueried)
{
assert levelQueried != null;
Level level = LevelRepository.load(levelQueried);
assert level != null;
GameController controller = new GameController(model);
GameWindow view = new GameWindow(controller);
}
我的问题是,当我从另一个JFrame启动GameWindow时,上面没有任何元素。如果我没有在构造器中启动游戏循环,我的游戏窗口似乎初始化正确(内容、关闭时退出…)。但是当我启动gameloop时,我只是有一个空的JFrame(大小正确),没有内容。。当我试图退出画面时,我不能
以下是我的游戏循环代码:
public void start() throws InterruptedException // Game loop method
{
boolean updateGame = true;
while ( !isFinish() ) {
// We update the elements only 1 round of 2
if ( updateGame ) {
updateExitState();
getPlayField().updateMoovableEntities();
updateGame = false;
} else {
updateGame = true;
}
Thread.sleep(100);
// Animate the sprite at every round
setChanged();
notifyObservers(); // inform that a repaint is necessary
}
LOGGER.debug("The game loop for the current level is now finished.");
}
在控制台上,我可以看到gameloop正在运行,并且正确地调用了update方法。。。但是paintComponent从未被称为。。。所以我的镜框上什么都没有
我对这个问题一无所知。。。有人能帮我吗
编辑:
谢谢你的回答。我已经使用
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run()
{
controller.startGame();
}
});
这是一个更好的一点,现在我的框架已正确初始化。但现在还有另一个问题,监听器不再可用。。。我根本无法与我的框架交互(无法退出或执行任何其他操作…)。怎么了?通过在Swing事件线程(EDT或事件调度线程)上运行
while(true)
循环,您完全冻结了它。不要那样做。相反,在后台线程中运行while循环,或者使用Swing计时器驱动游戏循环。阅读更多关于此的信息。另外,请阅读本网站上的问题
请注意,当您(错误地)在main方法中启动GUI和游戏循环时,游戏循环在主线程中运行,而不是在Swing事件线程中运行,因此在这种情况下,游戏可以正常运行,但这不是一个好的解决方案,因为主GUI也从Swing事件线程启动,这可能会导致间歇性的难以调试的线程错误 通过在Swing事件线程(EDT或事件调度线程)上运行
while(true)
循环,您完全冻结了Swing事件线程。不要那样做。相反,在后台线程中运行while循环,或者使用Swing计时器驱动游戏循环。阅读更多关于此的信息。另外,请阅读本网站上的问题
请注意,当您(错误地)在main方法中启动GUI和游戏循环时,游戏循环在主线程中运行,而不是在Swing事件线程中运行,因此在这种情况下,游戏可以正常运行,但这不是一个好的解决方案,因为主GUI也从Swing事件线程启动,这可能会导致间歇性的难以调试的线程错误 你在EDT的上下文中启动游戏循环,这会阻止它,阻止它处理事件队列,包括绘制请求。当你单独运行它时,它工作的原因是因为类us在“main”循环中启动,这意味着你在EDT的上下文中启动了游戏循环,这会阻止它,阻止它处理事件队列,包括绘制请求。当您单独运行它时,它工作的原因是因为类us在“main”循环中启动,这意味着您侥幸成功。您可能会提到“main”循环和EDT之间的差异,以便op了解它为什么单独工作,这样可能会避免“但它在我这样做时工作…”注释:PYou可能会提到“main”循环和EDT之间的区别,以便op理解它为什么独立工作,这样可能会避免“但它在我这样做时工作…”注释:P