我有一个关于Java Swing和JPanel的问题。我可以说我是一名没有经验的Java程序员,但对编程并不是全新的。
我的问题是我有一个名为RandomParticle
的课程,
public class RandomParticle extends Ellipse2D.Double {
private Ellipse2D.Double circle;
public RandomParticle(double xPos , double yPos,double rad) {
setCircle(new Ellipse2D.Double(xPos, yPos, rad, rad));
}
public Ellipse2D.Double getCircle() {
return circle;
}
public void setCircle(Ellipse2D.Double circle) {
this.circle = circle;
}
}
我想在屏幕上移动(当然是在JFrame中)。粒子是一个默认对象,只是为了获取图形。但是,在许多地方,例如here,可以说它能够绘制圆圈,以覆盖JPanel中的方法paintComponent
。确实合理的是,要在JFrame中绘制内容,它必须是JPanel。但是,这可能会导致麻烦,因为Java不支持多重继承。
在这种情况下,我并不需要RandomParticle
成为ellipse2D的孩子,但随着我的类变得越来越复杂,我很可能需要在某些时候从其他类中固有。但是,我觉得这个级别的问题对于SO来说是一个很好的部门,因为它不需要我的程序的任何具体知识。所以我想知道的是:是否有可能在没有班级成为JPanel的孩子的情况下画一个圆圈?
答案 0 :(得分:9)
是否可以在不将该类作为JPanel的孩子的情况下绘制一个圆圈?
有点儿,但它有问题。我会尝试解释
如果你想在Swing中执行自定义绘画,你应该覆盖从paintComponent
扩展的任何组件的JComponent
方法,JPanel
通常是最简单的解决方案,这就是绘画方式作品
有关绘画如何运作的详细信息,请查看Painting in AWT and Swing和Performing Custom Painting。
一般来说,尝试直接绘制到像JFrame
这样的顶级容器是不可取的,因为它包含了许多其他子组件,它们被绘在顶部(JRootPane
,{{1} },contentPane
,glassPane
等,可以独立于框架绘制,导致一些奇怪的绘画工件。
更详细地了解menuBar
实际上是什么样的......
JFrame
也不是双缓冲的,这意味着如果您尝试直接绘制它,尝试快速更新它,则会导致闪烁。 JFrame
默认情况下,它的死者是双缓冲的
Swing本身使用被动渲染引擎,这意味着您实际上并不控制绘制过程,只需在需要绘制组件时通知您(通过JComponent
方法)。 Swing可以选择绘制子组件而无需通知父容器,这是通常鼓励paintComponent
的原因之一。它还可以在尽可能少的调用中合并多个绘制请求,以优化流程。
所有这些都是在您不知情或无法控制的情况下完成的。
但是,如果您想要更好地控制绘制过程,可以考虑使用BufferStrategy,它可以直接(双缓冲)控制绘制过程,因此您可以决定何时以及应该使用什么绘。但即便如此,也需要使用paintComponent
作为生成输出的基础。
作为一般经验法则,一般不鼓励从java.awt.Canvas
(或大多数顶级容器)扩展,而是使用其中一个容器类作为基类。通过这种方式,您可以更自由地显示或重复使用它们,将它们添加到您希望的其他容器中