【发布时间】:2018-11-20 04:46:40
【问题描述】:
我一直认为 Canvas 或 JPanel 是在 JFrame 上放置图形所必需的,但是我之前看到了一个视频,其中该人在扩展 JFrame 时使用了paint(graphics g),但没有制作面板或画布。如果是这种情况,为什么人们还要费心制作 Canvas 或 JPanel?
【问题讨论】:
标签: java canvas graphics jframe jpanel
我一直认为 Canvas 或 JPanel 是在 JFrame 上放置图形所必需的,但是我之前看到了一个视频,其中该人在扩展 JFrame 时使用了paint(graphics g),但没有制作面板或画布。如果是这种情况,为什么人们还要费心制作 Canvas 或 JPanel?
【问题讨论】:
标签: java canvas graphics jframe jpanel
JFrame 扩展自 Frame,它扩展自 Window,它扩展自 Container,扩展自 Component,它定义了 paint。
如果是这样,为什么人们还要费心制作 Canvas 或 JPanel?
要回答这个问题,您需要更好地了解JFrame(以及基于窗口的类)。
JFrame实际上是一个复合组件,也就是说,它由许多提供窗口核心功能的其他组件组成
这意味着,如果您覆盖 paint 并在框架上执行自定义绘制,您很可能会在子组件上绘制或者子组件将在其上绘制,并且由于绘制子系统的方式工作,将在没有调用框架的绘制方法的任何时候这样做。
框架包括其可用区域内的窗口装饰。这意味着“可视”区域实际上小于框架的定义区域。
这也是为什么建议使用pack 而不是setSize
这意味着如果您覆盖paint,您实际上可以在窗饰下进行绘画(是的,这种情况一直都在发生,我们已经厌倦了回答它)
来自How can I set in the midst?的屏幕截图
JFrame 的 contentPane 负责处理这一点,因为它布置在可视区域内。
顶级容器,如JFrame 不是双缓冲的,因此,即使您克服了上述所有问题,您也会得到闪烁的更新。当然你可以“设计”你自己的双缓冲算法,但在 Swing 中(即JPanel),它是免费的,所以何必费心
作为一般建议,我们通常不鼓励从 JFrame(或其他顶级容器)扩展,因为它会将您锁定在单个用例中并阻止重复使用的可能性。
另一方面,如果您使用JPanel,您可以随时将其添加到您想要的任何容器中
【讨论】: