Java 覆盖组件两次

Java 覆盖组件两次,java,swing,Java,Swing,这更多的是一个概念性的问题,所以很难发布一个小的可行的代码示例。但是,我有一个类在这里重写paintComponent: public abstract class BasePanel extends JPanel { ... @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 =

这更多的是一个概念性的问题,所以很难发布一个小的可行的代码示例。但是,我有一个类在这里重写
paintComponent

public abstract class BasePanel extends JPanel {

    ...    

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);       
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                            RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);

        this.standardDraw(drawObjects,g2);
    }   
}
基本上,如果
paintComponent
在派生类中未被重写,我希望这是这个基础面板绘制的“标准方式”。因此,我有一个名为
AspectRatioPanel
的派生类,我想重新指定它如何绘制东西:

public class AspectRatioPanel extends BasePanel {

    ...

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);       
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                            RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);

        // Get ViewPort Bounding Box to clip
        BoundingBox viewPortBoundingBox = this.getViewPortBoundingBox();

        // Clip to viewport
        g2.setClip((int)viewPortBoundingBox.topLeft.getX(),(int)viewPortBoundingBox.topLeft.getY(),(int)viewPortBoundingBox.getWidth(),(int)viewPortBoundingBox.getHeight());

        this.standardDraw(drawObjectsBuf,g2);
    }   
}

我遇到的问题是在派生类中调用super.paintComponent(g)。我希望它在
JComponent
中调用
paintComponent
,但它首先要通过
BasePanel
。有没有更好的方法来解决这个问题?我可以删除
BasePanel
中的
paintComponent
方法,但是有一种标准的绘图方式对我很有用。我似乎也不能直接调用
JComponent.paintComponent
,因为它受
保护。有解决办法吗?还有,我在概念上做错了什么吗?

可能我误解了你的问题,但我会将标准绘画和定制绘画分开

public abstract class BasePanel extends JPanel {

...    

  @Override
  protected void paintComponent(Graphics g) {
    super.paintComponent(g);       
    provideCustomPainting(g);
  }   

  protected void provideCustomPainting(Graphics g) {
    Graphics2D g2 = (Graphics2D)g;
    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                        RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);

    this.standardDraw(drawObjects,g2);
  }
}

public class AspectRatioPanel extends BasePanel {
  protected void provideCustomPainting(Graphics g) {
    Graphics2D g2 = (Graphics2D)g;
    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                        RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);

    // Get ViewPort Bounding Box to clip
    BoundingBox viewPortBoundingBox = this.getViewPortBoundingBox();

    // Clip to viewport
    g2.setClip((int)viewPortBoundingBox.topLeft.getX(),(int)viewPortBoundingBox.topLeft.getY(),(int)viewPortBoundingBox.getWidth(),(int)viewPortBoundingBox.getHeight());

    this.standardDraw(drawObjectsBuf,g2);
  }
}

也许我误解了你的问题,但我会把标准画和定制画分开

public abstract class BasePanel extends JPanel {

...    

  @Override
  protected void paintComponent(Graphics g) {
    super.paintComponent(g);       
    provideCustomPainting(g);
  }   

  protected void provideCustomPainting(Graphics g) {
    Graphics2D g2 = (Graphics2D)g;
    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                        RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);

    this.standardDraw(drawObjects,g2);
  }
}

public class AspectRatioPanel extends BasePanel {
  protected void provideCustomPainting(Graphics g) {
    Graphics2D g2 = (Graphics2D)g;
    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                        RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);

    // Get ViewPort Bounding Box to clip
    BoundingBox viewPortBoundingBox = this.getViewPortBoundingBox();

    // Clip to viewport
    g2.setClip((int)viewPortBoundingBox.topLeft.getX(),(int)viewPortBoundingBox.topLeft.getY(),(int)viewPortBoundingBox.getWidth(),(int)viewPortBoundingBox.getHeight());

    this.standardDraw(drawObjectsBuf,g2);
  }
}
您不能简单地调用super.paintComponent(图形);通过覆盖paintComponent(),您有3个选项:

a、 )在方法的开头调用super;您可以在超级类所绘制的内容之上绘制代码绘制

b、 )根本不要调用super-您的paintComponent需要确保它能够绘制所需的所有内容;如果零部件是不透明的,则意味着您需要绘制零部件占据的整个区域

c、 )在你方便的时候打电话给super;在super中绘制的任何东西都会按照您所称的顺序“分层”。只有在超级方法不绘制整个区域时才有意义

如果您坚持将继承层次结构的特定类中的paintComponent用作super.paintComponent,而不管两者之间的继承层次结构如何,也可以:

BasePanel extends JPanel {
     protected final defaultPaintComponent(Graphics g) {
         super.paintComponent(g);
     }
}
子类可以调用“defaultPaintComponent”而不是super.paintComponent,从而绕过定义的层次结构中介于两者之间的任何实现类(我建议将其声明为final以防止意外覆盖)。

您不能简单地调用super.paintComponent(图形);通过覆盖paintComponent(),您有3个选项:

a、 )在方法的开头调用super;您可以在超级类所绘制的内容之上绘制代码绘制

b、 )根本不要调用super-您的paintComponent需要确保它能够绘制所需的所有内容;如果零部件是不透明的,则意味着您需要绘制零部件占据的整个区域

c、 )在你方便的时候打电话给super;在super中绘制的任何东西都会按照您所称的顺序“分层”。只有在超级方法不绘制整个区域时才有意义

如果您坚持将继承层次结构的特定类中的paintComponent用作super.paintComponent,而不管两者之间的继承层次结构如何,也可以:

BasePanel extends JPanel {
     protected final defaultPaintComponent(Graphics g) {
         super.paintComponent(g);
     }
}

子类可以调用“defaultPaintComponent”而不是super.paintComponent,从而绕过定义的层次结构中介于两者之间的任何实现类(我建议将其声明为final以防止意外重写)。

我想知道是否希望两者都实现一个共享接口,并且可能共享相同的合成组件以允许共享行为,而不是在此处使用继承。您可能希望签出。另一种方法是,如果面板在其他方面相同,则只有一个实现,可以在保持纵横比的模式下工作。@Rob感谢链接!我想知道您是否希望两者都实现一个共享接口,或者共享同一个组合组件以允许共享行为,而不是在此处使用继承。您可能希望签出。另一种方法是,如果面板在其他方面相同,则只使用一个实现,这有可能在纵横比保持模式下工作。@Rob感谢链接<代码>“可能我误解了你的问题,…”
--不,这个答案对我来说很贴切。100+这将起作用,我将继续接受它。不过,我确实想知道我是否能以更好的方式处理这件事。谢谢<代码>“可能我误解了你的问题,…”--不,这个答案对我来说很贴切。100+这将起作用,我将继续接受它。不过,我确实想知道我是否能以更好的方式处理这件事。谢谢我感谢你的建议。这是我必须考虑的问题。我很感谢你的建议。这是我必须多考虑的事情。