它有各种原因,包括:
paintComponent(Graphics)方法来实现自定义绘制.顶层Swing容器(如JFrame,JApplet,JWindow)只paint(Graphics).作为绘画的常用方法的结果,回答的人经常忘记普通和顶级组件之间的这种差异,因此建议愚蠢的建议.;)JComponent可以被添加到JFrame,或JApplet,或JDialog,或布局的约束JPanel,或者JInternalFrame,或者..当你认为你的GUI是完整的,客户说:"嘿,那岂不是巨大的投入工具栏并将其作为小程序提供?" 该JComponent方法很容易适应.JFrame大小设置为包含GUI的"完全正确的大小" (使用pack()).当添加其他组件时尤其如此.现在,两个小小的分歧与提供的建议.
如果整个组件的定制画,它可能是最好只放一个BufferedImage内部ImageIcon/ JLabel组合.这是绘制图像的示例.
什么时候更新它:
getGraphics()一个Graphics或createGraphics()一个Graphics2Drepaint()给标签.这是一种简单的双缓冲方式.
让我详细说明一下.在视频游戏中,为了避免重绘和显示更平滑的图形所引起的闪烁,人们通常使用双缓冲.他们创建一个屏幕外表面,在其上绘制所有内容,然后一次性在屏幕上显示整个屏幕外表面.

在Java2D和Swing中,最简单的方法是在JPanel上简单地进行游戏精灵绘制,然后将JPanel添加到JFrame中.
其次,通过在JPanel上绘制内容,您可以在JFrame上显示更多GUI小部件和其他图形对象,而无需在游戏循环中手动绘制它们.例如按钮,菜单,其他面板,甚至其他渲染JPanel.
第三,它允许您为游戏使用自动翻译的坐标.您可以从左上角到右下角绘制所有内容,而无需担心窗口管理器特定的内容,如窗口边框宽度,任务窗格,标题等!

而且,这不仅仅是Java中游戏程序员使用的惯例.使用带有内部主循环(如GUI Toolkit)的库编程游戏时,创建单独的游戏板,渲染面板或图形小部件非常流行.您可以在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();
}
}
Run Code Online (Sandbox Code Playgroud)
你会看到黑色方块不是正方形!因为(0,0)是整个框架的左上角,而不是可见区域的角落.