我刚开始编写视频游戏代码,我听说在JPanel上绘制所有绘图并将该面板附加到JFrame上比简单地绘制JFrame更好。我只是想知道为什么这样更好?
答案 0 :(得分:9)
最好有各种原因,包括:
paintComponent(Graphics)
方法来实现自定义绘制。顶级Swing容器(例如JFrame
,JApplet
,JWindow
)只有paint(Graphics)
。作为绘画的常用方法的结果,回答的人经常忘记普通和顶级组件之间的这种差异,因此建议愚蠢的建议。 ;)JComponent
添加到JFrame
,JApplet
或JDialog
,或JPanel
中布局的约束,或者JInternalFrame
,或者......当你认为你的GUI完成时,客户说:“嘿,放入工具栏并将它作为小程序提供也不是很好吗? “ JComponent
方法很容易适应。JFrame
的大小设置为“完全”正确的大小'包含GUI(使用pack()
)。当添加其他组件时尤其如此。现在,对提供的建议存在两点轻微的分歧。
如果整个组件是自定义绘制的,最好只在BufferedImage
/ ImageIcon
组合中放置JLabel
。以下是painting to an image的示例。
当需要更新时:
getGraphics()
致Graphics
或createGraphics()
致Graphics2D
repaint()
。答案 1 :(得分:6)
这是一种简单的双缓冲方式。
让我详细说明一下。在视频游戏中,为了避免重绘和显示更平滑的图形所引起的闪烁,人们通常使用双缓冲。他们创建一个屏幕外表面,在其上绘制所有内容,然后一次性在屏幕上显示整个屏幕外表面。
在Java2D和Swing中,最简单的方法是在JPanel上简单地进行游戏精灵绘制,然后将JPanel添加到JFrame。
其次,通过在JPanel上绘制内容,您可以在JFrame上显示更多GUI小部件和其他图形对象,而无需在游戏循环中手动绘制它们。例如按钮,菜单,其他面板,甚至其他渲染JPanel。
第三,它允许您为游戏使用自动翻译的坐标。您可以从左上角到右下角绘制所有内容,而不必担心窗口管理器特定的内容,如窗口边框宽度,任务窗格,标题等。!
此外,这不仅仅是Java中游戏程序员使用的惯例。在使用带有内部主循环(如GUI Toolkit)的库编程游戏时,创建单独的游戏板,渲染面板或图形窗口小部件非常流行。您可以在Windows窗体中使用用户窗体,在GTK +中使用绘图板。
答案 2 :(得分:5)
JFrame包括菜单,标题栏和边框等内容。因此,当您参考坐标时,您必须考虑这些。您可能还决定向框架添加菜单栏或其他一些组件。如果您的绘画都在JPanel中,那么这不会改变您需要引用坐标的方式。
例如,尝试:
public class Test extends JFrame {
public Test() {
super();
setVisible(true);
setBounds(100, 100, 200, 100);
}
@Override
public void paint(Graphics g) {
g.fillRect(0, 0, 50, 50);
}
public static void main(String[] args) {
new Test();
}
}
你会看到黑色方块不是正方形!因为(0,0)是整个框架的左上角,而不是可见区域的角落。