重写paintComponent两次

时间:2014-09-19 14:08:33

标签: java swing

这更像是一个概念性问题,因此很难发布一个小的可行代码示例。但是,我有一个在此处覆盖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)。我打算在paintComponent中调用JComponent,但它首先会经过BasePanel。有没有更好的方法来解决这个问题?我可以删除paintComponent中的BasePanel方法,但使用标准方法绘制内容对我很有用。我似乎也无法直接致电JComponent.paintComponent,因为它是protected。这有解决方案吗?另外,我在概念上做错了吗?

2 个答案:

答案 0 :(得分:4)

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

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);
  }
}

答案 1 :(得分:1)

你可以简单地调用super.paintComponent(Graphics);通过覆盖paintComponent(),您有3个选项:

a。)在方法开始时调用super;你在超级类画的基础上绘制代码颜料。

b。)不要打电话给超级 - 你的paintComponent需要确保它描绘所需的一切;如果组件是不透明的,则意味着您需要绘制组件占据的整个区域。

c。)以你的方便打电话给超级;在super中绘制的任何东西看起来都是按顺序“分层”的,你称之为。只有当超级方法不绘制整个区域时才有意义。

如果你坚持使用继承层次结构的特定类中的paintComponent作为super.paintComponent,不管它们之间的继承层次结构如何,那也是可能的:

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

子类可以调用“defaultPaintComponent”而不是super.paintComponent,从而绕过定义的层次结构中的任何实现类(我建议将其声明为最终以防止意外覆盖)。