Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The Need To Restore Graphics Original State When Overwritten paint or paintComponent

I realize most of the Java code to overwritten paint or paintComponent, most of them doesn't restore the old state of graphics object, after they had change the state of graphics object. For example, setStroke, setRenderingHint...

I was wondering whether it is a good practice that we restore back the old state of graphics object, before returning from the method. For example

public void paintComponent(Graphics g) {
    super.paintComponet(g);
    Stroke oldStroke = g.getStroke();
    g.setStroke(newStroke);
    // Do drawing operation.
    g.setStroke(oldStroke);
}

Is this a good practice? Or it is over done?

like image 533
Cheok Yan Cheng Avatar asked May 23 '09 07:05

Cheok Yan Cheng


2 Answers

You should not alter the Graphics object passed in at all, rather perform all your graphics operations on a copy of it which you then dispose. There'll be no need to reset the state at all then.

public void paintComponent(Graphics g1) {
    super.paintComponent(g1);
    final Graphics2D g = (Graphics2D)g1.create();
    try {
         // ...Whole lotta drawing code...
    } finally {
         g.dispose();
    }
}
like image 53
banjollity Avatar answered Nov 10 '22 15:11

banjollity


Yes, this is a very good practice to follow. You don't pay much in performance (relative to the actual painting operation), and you save yourself a mess of grief if you're making unusual changes to the graphics context. Don't overdo it though -- you probably don't need to worry about color settings, for example.

The alternative is to assume nothing about the graphics context, and set all the necessary properties before every painting, in case they're set to something wonky. Try to avoid freely creating and disposing Graphics objects for every operation.

Specific properties you should always restore if modified: (because they can do Bad Things and have Unexpected Consequences):

  • Transform - because modifications to this will stack on top of each other and get very, very hard to reset. Beware: this is modified by the translate, shear, scale, rotate, and transform methods of Graphics2D. Modifying transforms should be used with CAUTION.
  • Stroke -- because (at least in my configuration), leaving this default runs much faster than any setting even if equivalent to default. Don't ask -- it's a result of the Java2D graphics pipelines accelerating the default case using graphics hardware.
  • Clip: will result in weird bugs where only part of the screen draws.
  • Composite: most operations probably don't expect this to be something weird.

Properties to not worry about:

  • RenderingHints. These are things you can easy set and restore, and generally you want to leave them set a certain way (antialiasing on, etc) for the whole time the app is running. Changing RenderingHints will rarely break rendering of components, although it might make it uglier.
  • Background color and paint color. Most things will modify these before drawing anyway.
  • Font: likewise.
like image 31
BobMcGee Avatar answered Nov 10 '22 14:11

BobMcGee