当覆盖paint或paintComponent时需要恢复图形原始状态

我意识到大多数Java代码都会覆盖paint或paintComponent,它们中的大多数都没有恢复图形对象的旧状态,之后它们就改变了图形对象的状态。 例如,setStroke,setRenderingHint ……

我想知道在从方法返回之前恢复图形对象的旧状态是否是一个好习惯。 例如

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

这是一个好习惯吗? 还是结束了?

你根本不应该改变传入的Graphics对象,而是在你随后处理它的副本上执行所有图形操作。 那时根本不需要重置状态。

 public void paintComponent(Graphics g1) { super.paintComponent(g1); final Graphics2D g = (Graphics2D)g1.create(); try { // ...Whole lotta drawing code... } finally { g.dispose(); } } 

是的, 这是一个非常好的做法。 你没有付出太多的性能(相对于实际的绘画操作),如果你对图形上下文做了不寻常的改变,你就可以省去一堆悲伤。 不要过分 – 例如,您可能不需要担心颜色设置。

另一种方法是不假设图形上下文,并在每次绘画之前设置所有必要的属性,以防它们被设置为不稳定的东西。 尽量避免为每个操作自由创建和处理Graphics对象。

如果修改了应该总是恢复的特定属性:(因为它们可以做坏事并且有意想不到的后果):

  • 转换 – 因为对此的修改将叠加在一起并且非常非常难以重置。 注意:这是通过Graphics2D的平移,剪切,缩放,旋转和变换方法修改的。 修改变换应与“小心”一起使用。
  • 笔划 – 因为(至少在我的配置中),保留此默认值比任何设置都快得多,即使等效于默认值。 不要问 – 这是Java2D图形管道加速使用图形硬件的默认情况的结果。
  • 剪辑:将导致奇怪的错误,只有部分屏幕绘制。
  • 综合:大多数操作可能不会指望这是一个奇怪的东西。

属性不用担心:

  • RenderingHints中。 这些是您可以轻松设置和恢复的内容,通常您希望在应用程序运行的整个过程中将它们设置为某种方式(抗锯齿等)。 更改RenderingHints很少会破坏组件的渲染,尽管它可能会使它变得更加丑陋。
  • 背景颜色和油漆颜色。 无论如何,大多数事情都会在绘制之前修改它
  • 字体:同样。