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

时间:2009-05-23 07:05:29

标签: java swing graphics awt

我意识到大多数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);
}

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

2 个答案:

答案 0 :(得分:15)

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

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

答案 1 :(得分:3)

是的,这是一个非常好的做法。你的表现不是很高(相对于实际的绘画操作),如果你是的话,你可以省去一堆悲伤对图形上下文进行不寻常的更改。不要过分 - 例如,你可能不需要担心颜色设置。

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

如果修改后应始终恢复的特定属性:(因为它们可能会造成不良后果并产生意外后果):

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

不用担心的属性:

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