我有一个名为 SpacePotaters(JFrame 的子类)的顶级 GUI 类,并在其内容窗格中添加了一个名为 panelViews 的 JPanel(它使用 CardLayout 布局管理器)。除其他外,我将 MainMenu 对象(JPanel 的子类)和 GameView 对象(JPanel 的子类)作为卡片添加到 panelView。
public SpacePotaters(){
super("Space Potaters");
Container content = getContentPane();
// initialize components
gameView = new GameView(this);
mainMenu = new MainMenu(this);
leaderboard = new Leaderboard(this);
instructions = new JPanel(); // to do
cLayout = new CardLayout();
// add "cards" to CardLayout manager
panelViews = new JPanel(cLayout);
panelViews.setPreferredSize(new Dimension(WINDOW_WIDTH, WINDOW_HEIGHT));
panelViews.add("gameView", gameView);
panelViews.add("mainMenu", mainMenu);
panelViews.add("leaderboard", leaderboard);
panelViews.add("instructions", instructions);
// initially display menu menu
content.add(panelViews);
cLayout.show(panelViews,"mainMenu");
addWindowListener(this);
pack();
setResizable(false);
// relocate window to center of screen
setLocationRelativeTo(getRootPane());
}
如果它有用,主菜单绘制方法在这里:
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(mainMenuBackground, 0, 0, spTop.getWindowWidth(), spTop.getWindowHeight(), null);
}
现在我只绘制背景图像 - 稍后我将添加 JButtons,单击它会切换到不同的卡片。
这个想法是我从主菜单卡开始,必要时切换到其他卡。我运行程序并注意到主菜单卡在被为 gameView 创建的图像替换之前短暂闪烁。我知道我应该等到真正切换到该卡之前渲染 gameView 图形,这样游戏才不会过早启动。那不是我感到困惑的地方。即使我不等待,gameView 不应该只是开始运行而无法查看它吗?换句话说,不管gameView里面发生了什么,mainMenu不应该是唯一可见的卡片吗?
我认为问题出在 gameView 中,它使用主动渲染和双缓冲。GameView 有这个方法,在游戏的每个循环中调用一次:
public void paintScreen(){
// get fresh graphics context for GameView each time
Graphics context = getGraphics();
if (context != null && dbImage != null){
context.drawImage(dbImage, 0, 0, null);
}
context.dispose();
}
注释掉此方法的主体会产生所需的结果 - 仅显示 mainMenu。我很困惑为什么会这样。我认为每个组件(JFrame、JPanel 等)都有自己的图形上下文。因此,当我在 GameView 中调用 getGraphics() 时,它不应该返回 gameView 面板的图形上下文,而不是 spTop 或 panelViews 的图形上下文吗?而且由于它只更改特定的图形上下文,如果 gameView 面板不可见(如果我在 mainMenu 对象上使用 CardLayout 的 show() 方法,它不应该是可见的),那么它不应该影响我对主菜单的视图. 有任何想法吗?
注意:如果我用 isVisible() 测试 gameView 和 mainMenu,gameView 返回 false,mainMenu 返回 true。此外,我使用 getGraphics() 来测试 mainMenu、spTop 和 gameView 图形上下文是否都不同——它们是不同的。所以gameView在它自己的图形上下文中绘制一个图像并且是不可见的,但是paintScreen()中drawImage()的效果仍然显示!真的很迷茫。