是否所有图形对象都必须从JPanel继承?

pat*_*rik 5 java swing

我有一个关于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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我想在屏幕上移动(当然是在JFrame中).粒子是一个默认对象,只是为了获取图形.然而,在许多地方,例如在这里,可以说,为了能够绘制圆圈,它必须覆盖paintComponentJPanel中的方法.确实合理的是,要在JFrame中绘制内容,它必须是JPanel.但是,这可能会导致麻烦,因为Java不支持多重继承.

在这种情况下,我真的不需要RandomParticle成为ellipse2D的孩子,但随着我的类变得越来越复杂,我很可能需要在某些时候从其他类中固有.但是,我觉得这个级别的问题对于SO来说是一个很好的部门,因为它不需要我的程序的任何具体知识.所以我想知道的是:是否有可能在没有班级成为JPanel的孩子的情况下画一个圆圈?

Mad*_*mer 9

是否有可能在没有班级成为JPanel的孩子的情况下绘制一个圆圈?

有点,但它有问题.我会试着解释一下

如果你想在Swing中执行自定义绘画,你应该覆盖paintComponent任何扩展的组件的方法JComponent,JPanel通常是最简单的解决方案,这就是绘画的工作原理

看看画中的AWT和Swing执行风俗画为更多细节绘画如何工作的.

一般来说这是不妥当的尝试,并直接描绘到顶层容器一样JFrame,因为它包含了许多其他的子组件,其在上面绘制它(JRootPane,contentPane,glassPane,menuBar,等),其可以独立帧的画引起一些怪异绘画文物.

更详细的看看JFrame实际上是什么样的......

的rootPane

JFrame也不是双缓冲,这意味着如果您尝试直接绘制它,尝试快速更新它,它会导致闪烁. JComponent并且默认情况下,它的死者是双缓冲的

Swing本身使用被动渲染引擎,这意味着您实际上并不控制绘制过程,只需在需要绘制组件时通知您(通过该paintComponent方法).Swing可以选择绘制子组件而无需通知父容器,这paintComponent是通常鼓励的原因之一.它还可以在尽可能少的调用中合并多个绘制请求,以优化该过程.

所有这些都是在您不知情或无法控制的情况下完成

但是,如果您想要更多地控制绘制过程,可以考虑使用BufferStrategy,它可以直接(双缓冲)控制绘制过程,因此您可以决定何时绘制以及绘制什么.但即便如此,也需要使用a java.awt.Canvas作为生成输出的基础.

作为一般经验法则,通常不鼓励从JFrame(或大多数顶级容器)扩展,而是使用其中一个容器类作为基类.通过这种方式,您可以更自由地显示或重复使用它们,将它们添加到您希望的其他容器中

  • 根据您的代码示例很难知道,但是您更有可能拥有一个"JPanel"/表面,其他所有元素都将被绘制(他们不应该知道面板本身).FYI`Graphics2D`(其实例传递给`paintComponent`)可以使用`Graphics2D#draw`或`Graphics2D#fill`绘制`Ellipse2D`.现在,所有`RandomParticle`都是一个形状的概念,它不能自我渲染.看看[2D图形](https://docs.oracle.com/javase/tutorial/2d/) (2认同)