我刚刚开始编写视频游戏,我听说在 JPanel 上进行所有绘图并将该面板附加到 JFrame 上比简单地在 JFrame 上绘图要好。我只是想知道为什么这更好?
3 回答
出于各种原因,它会更好,包括:
- 在大多数 Swing 组件中,自定义绘制是通过覆盖该
paintComponent(Graphics)
方法来实现的。顶级 Swing 容器(例如JFrame
,JApplet
)JWindow
只有paint(Graphics)
. 由于绘画的通用方法,回答的人经常忘记通用组件和顶级组件之间的这种区别,因此提出愚蠢的建议。;) - A
JComponent
可以添加到 aJFrame
或 aJApplet
或 a或JDialog
a 中的布局约束中。就在您认为您的 GUI 完成时,客户说“嘿,这不是很好加入工具栏并作为小程序提供?” 该方法很容易适应这一点。JPanel
JInternalFrame
JComponent
- 正如 Richante 所解释的(完整的代码!),更容易计算绘制自定义组件所需的坐标,如果它具有首选大小,则将其
JFrame
调整为“完全正确的大小”以包含 GUI (使用pack()
)。在添加其他组件时尤其如此。
现在,对所提供的建议有两个小分歧。
如果整个组件是自定义绘制的,最好在/组合BufferedImage
内简单地放置一个。这是一个绘制图像的示例。当需要更新它时:ImageIcon
JLabel
- 要求
getGraphics()
一个Graphics
或createGraphics()
一个Graphics2D
- 将自定义绘画绘制到该图形实例
- 处理图形实例
repaint()
在标签上调用。
这是进行双缓冲的一种简单方法。
让我详细说明一下。在电子游戏中,为了避免重绘造成的闪烁,显示更流畅的图形,人们通常会使用双缓冲。他们创建一个离屏表面,在其上绘制所有内容,然后一次性在屏幕上显示整个离屏表面。
在 Java2D 和 Swing 中,最简单的方法是在 JPanel 上绘制游戏精灵,然后将 JPanel 添加到 JFrame。
其次,通过在 JPanel 上绘制东西,您可以在 JFrame 上显示更多的 GUI 小部件和其他图形对象,而无需在游戏循环中手动绘制它们。例如按钮、菜单、其他面板,甚至其他渲染 JPanel。
第三,它允许您为您的游戏使用自动翻译的坐标。您可以绘制从左上角到右下角的所有内容,而不必担心窗口管理器的特定内容,例如窗口边框宽度、任务窗格、标题等!
此外,这不仅仅是 Java 游戏程序员使用的约定。在使用带有内部主循环的库(如 GUI 工具包)编写游戏时,创建单独的游戏板、渲染面板或图形小部件非常流行。您可以在 Windows 窗体中使用用户窗体,在 GTK+ 中使用绘图板。
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) 是整个帧的左上角,而不是可见区域的角。