我们的任务是制作一款简单的游戏。现在,我们已经完成了很长一段时间的游戏,但我刚刚开始实现连接/主机菜单(在我们的JFrame中使用JPanel,它只包含一个用于渲染我们的精灵/形状的画布/等等。)。我们有4个JTextFields和两个JButtons。当显示该显示时,我们的画布被设置为禁用,以便不干扰输入(即,使用其鼠标监听器等)。在Windows机器上,我们可以点击所有的框,我们得到漂亮的工字梁光标等,我们可以正常输入,然后点击按钮。但是,在MacOS上尝试相同时,您无法单击框或按钮。你没有在盒子上得到工字梁。就像他们不存在一样。但是,我们可以使用tab键将焦点切换到所有元素,并可以使用它来键入框,按下按钮等,就像您应该可以使用鼠标一样。我试过像20种不同的方式请求焦点,但这似乎不起作用。我已经以相同的方式制作了许多其他应用程序(JFrame> JPanel> JButton / TextField),它们在MacOS上都运行得很好。我以前从未见过这样的事。
我不会发布一大堆整个文件,而是将其删除。第一个是我们的主要入口点,Game类。它看起来像这样:
public class Game extends Canvas implements Runnable
private JFrame frame;
private ConnectScreen connectScreen;
public getFrame() { /* get reference to frame */ }
public setFrame() { /* set the frame */ }
public void run() { /* game loop, calls render() */ }
public Game() { /* create window, add canvas to it, get reference to frame, instantiate stuff, etc. */ }
public void tick() { /* every frame this happens, just tells spawners to spawn stuff, etc. */ }
public void render() {
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
this.createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
///////// Draw things below this/////////////
g.setColor(Color.black);
g.fillRect(0, 0, WIDTH, HEIGHT);
// SCREEN
if (!isPaused()) {
// THIS is where we tell the canvas to enable if we're not on the connect screen
if (gameState != STATE.Join && gameState != STATE.Host) {
this.setEnabled(true);
}
/* i omitted rendering from all of these, since it's not useful here. most say somethingScreen.render(g) or something like that. */
if (gameState == STATE.Wave || gameState == STATE.Multiplayer || gameState == STATE.Bosses || gameState == STATE.Survival) { // render gameplay items
} else if (gameState == STATE.Menu || gameState == STATE.Help || gameState == STATE.Credits) { // render menu
} else if (gameState == STATE.Upgrade) { // render upgrade screen
} else if (gameState == STATE.GameOver) { // render game over screen
} else if (gameState == STATE.Leaderboard) { // render leaderboard
} else if (gameState == STATE.Color) { // render color picker screen
} else if (gameState == STATE.Join || gameState == STATE.Host) {
// if we are on the connect screen, disable this canvas
this.setEnabled(false);
connectScreen.render(g);
} else if (gameState == STATE.LeaderboardDisplay) { // render the leaderboard
}
} else {
pauseMenu.render(g);
}
if(!isPaused()) {} // renders the handler's things
///////// Draw things above this//////////////
g.dispose();
bs.show();
}
}
除此之外,对该课程没什么兴趣。这是(修剪过的)ConnectScreen类:
public class ConnectScreen extends JPanel {
JFrame frame; // this is the frame from the Game class
JTextField _____; // there are 4 of these
JButton _____; // there are 2 of these
public ConnectScreen(Game game) { // the game is passed in to get the frame from it
super();
this.setBackground(Color.black);
this.setPreferredSize(new java.awt.Dimension(Game.WIDTH, Game.HEIGHT));
this.setSize(new java.awt.Dimension(Game.WIDTH, Game.HEIGHT));
this.game = game;
this.mpSpawn = mp;
game.getFrame().add(this);
this.setFocusable(true);
/* set up each component */
/* add each component (click handlers, etc.) */
/* add panel to frame */
}
public void render(Graphics g) {
super.paintComponent(g);
this.paintComponents(g);
}
}
我们知道元素的设置,所有这些都有效,因为我们可以在Windows上查看和使用它们,但出于某种原因,当我们在MacOS上尝试它时,它不起作用。我们可以选择它们并键入/按下按钮,但由于某种原因,您无法单击它们进行聚焦。任何帮助,将不胜感激。谢谢!
答案 0 :(得分:0)
修复它,感谢MadProgrammer。显然,BufferStrategy不能用于渲染Swing组件。我刚刚在if
中添加了一个Game::render()
语句,如果未显示ConnectScreen,它只会进行任何渲染。如果是,它只是禁用并转动画布不可见,而ConnectScreen::render()
(重命名为覆盖JPanel::paintComponent()
)只是使用super.paintComponent()
来被动地绘制Swing组件。