Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么附加JPanel更好?_Java_Swing_Jframe_Jpanel - Fatal编程技术网

Java 为什么附加JPanel更好?

Java 为什么附加JPanel更好?,java,swing,jframe,jpanel,Java,Swing,Jframe,Jpanel,我刚刚开始编写视频游戏,我听说在JPanel上绘制所有的图形并将面板连接到JFrame上比简单地在JFrame上绘制要好。我只是想知道为什么这样更好?这是一种实现双缓冲的简单方法 让我详细说明一下。在视频游戏中,为了避免因重画而引起的闪烁和显示更平滑的图形,人们通常使用双缓冲。他们创建一个屏幕外表面,在上面绘制所有内容,然后在屏幕上一次性显示整个屏幕外表面 在Java2D和Swing中,最简单的方法是在JPanel上绘制游戏精灵,然后将JPanel添加到JFrame中 其次,通过在JPanel

我刚刚开始编写视频游戏,我听说在JPanel上绘制所有的图形并将面板连接到JFrame上比简单地在JFrame上绘制要好。我只是想知道为什么这样更好?

这是一种实现双缓冲的简单方法

让我详细说明一下。在视频游戏中,为了避免因重画而引起的闪烁和显示更平滑的图形,人们通常使用双缓冲。他们创建一个屏幕外表面,在上面绘制所有内容,然后在屏幕上一次性显示整个屏幕外表面

在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)是整个帧的左上角,而不是可见区域的角。

出于各种原因,它更好,包括:

  • 在大多数Swing组件中,自定义绘制是通过覆盖
    paintComponent(Graphics)
    方法实现的。顶层回转容器(例如
    JFrame
    JApplet
    JWindow
    )只有
    油漆(图形)
    。由于采用了常见的绘画方法,回答问题的人往往忘记了常见组件和顶级组件之间的区别,因此提出了愚蠢的建议
  • JComponent
    可以添加到
    JFrame
    ,或
    JApplet
    ,或
    JDialog
    ,或
    JPanel
    中的布局约束,或
    JInternalFrame
    或A。。当您认为GUI已经完成时,客户机会说:“嘿,如果加入一个工具栏并将其作为小程序提供,那不是很好吗?”JComponent方法很容易适应这一点
  • 正如Richante所解释的(连同代码!),更容易计算绘制自定义组件所需的坐标,如果它有一个首选尺寸,则将
    JFrame
    的尺寸调整为包含GUI的“完全正确的尺寸”(使用
    pack()
    )。当添加其他组件时,情况尤其如此

现在,对所提出的建议有两个小的分歧

如果整个组件都是自定义绘制的,则最好在
ImageIcon
/
JLabel
组合中放置一个
buffereImage
。以下是更新时的一个示例。

  • 调用
    getGraphics()
    查看
    Graphics
    createGraphics()
    查看
    Graphics2D
  • 将自定义绘制绘制到该图形实例
  • 处理图形实例
  • 调用标签上的
    repaint()

  • 在JPanel上绘制一个图像,然后将JPanel添加到JFrame并不是进行双缓冲的方法。我很确定你可以在JFrame中使用双缓冲。@Richante我很清楚你可以在JFrame中使用双缓冲,我说的是使用JPanel是最简单的方法,而不是使用Java2D和Swing进行双缓冲的唯一方法。@Richante还有,为什么它不是进行双缓冲的一种方法?它经常用于这个目的。哦,是的,我没有注意到JPanel在默认情况下是双缓冲的。那么你可能是对的。@mre这是我通常推荐的(或接近推荐的-见我的答案),但我也有兴趣听到OP关于该信息的确切来源。问问题的人。这将成为一个有少量额外信息的“好问题”。+1,我知道答案的为数不多的Java问题之一。一旦创造了一个新的世界,就要尽情享受它。:)获得面板的UI委托有一些好处。@垃圾神谢谢你提醒我。不过,有些事情我不明白。1) 面板UI似乎是从中获得的,对吗?2) 为什么
    JComponent
    不能(拥有/访问)自己的UI委托?3) 我应该就这些问题开始我自己的问题吗?
    JComponent
    本身没有委托,但它为委托的子类提供了一些基本的基础结构。就是一个例子。不,我太累了,心烦意乱,无法充分利用你的时间。我会一直在这里闲逛,直到我能承担得起犯错误的代价&浪费人们的时间,稍后再阅读文档,并将其作为一个问题来讨论。谢谢你的提议。:)我最近遇到了一个有趣的问题,
    JPanel
    UI委托就是问题所在。切换到
    JComponent
    是解决方案。