Reputation: 4650
This is more of a conceptual question, so it's hard to post a small workable code sample. But, I have a class that overrides paintComponent
here:
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);
}
}
Basically, I'd like this to be the "standard way" this base panel draws if paintComponent
is not overridden in a derived class. So, I have a derived class called AspectRatioPanel
which I'd like to re-specify how it draws things:
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);
}
}
The problem I'm having is the call super.paintComponent(g)
in the derived class. I intend for it to be calling paintComponent
in JComponent
, but it is going through BasePanel
first. Is there a better way to approach this problem? I could delete the paintComponent
method in BasePanel
, but having a standard way of drawing things is useful for me. I also can't seem to call JComponent.paintComponent
directly since it's protected
. Is there a solution for this? Also, am I doing something conceptually wrong?
Upvotes: 1
Views: 227
Reputation: 20069
You could simply not call super.paintComponent(Graphics); by overwriting paintComponent() you have 3 options:
a.) Call super at the beginning of the method; you paint code paints on top of what has been painted by the super class.
b.) Don't call super at all - your paintComponent needs to ensure it paints everything that is needed; if the components is opaque that means you need to paint the entire area the component occupies.
c.) Call super at your convinience; whatever is painted in super appears to be "layered" in sequence where you call it. Makes only sense if the super method doesn't paint the entire area.
If you insist to use paintComponent from a specific class of your inheritance hierarchy as super.paintComponent, regardless of inheritance hierarchy in between, thats also possible:
BasePanel extends JPanel {
protected final defaultPaintComponent(Graphics g) {
super.paintComponent(g);
}
}
Child classes can call "defaultPaintComponent" instead of super.paintComponent, thus bypassing any implementation classes in between in the hierarchy defined (I suggest declaring it final to prevent accidental overwrites).
Upvotes: 1
Reputation: 11327
Probably I misunderstood your problem, but I would separate standard and custom painting
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);
}
}
Upvotes: 4