9

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

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

4

2 回答 2

16

您根本不应更改传入的 Graphics 对象,而应在其副本上执行所有图形操作,然后将其处置。那时根本不需要重置状态。

public void paintComponent(Graphics g1) {
    super.paintComponent(g1);
    final Graphics2D g = (Graphics2D)g1.create();
    try {
         // ...Whole lotta drawing code...
    } finally {
         g.dispose();
    }
}
于 2009-05-23T09:00:06.077 回答
3

是的,这是一个非常好的做法。 您不会在性能上付出太多(相对于实际的绘画操作),如果您对图形上下文进行不寻常的更改,您会为自己省去一团糟。不过不要过度——例如,您可能不需要担心颜色设置。

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

如果修改,您应该始终恢复特定属性:(因为它们可能会做坏事并产生意外后果):

  • 变换 - 因为对此的修改将叠加在一起并且变得非常非常难以重置。注意:这是由 Graphics2D 的 translate、shear、scale、rotate 和 transform 方法修改的。修改转换应谨慎使用。
  • 中风 - 因为(至少在我的配置中),保留此默认设置比任何设置运行得快得多,即使相当于默认设置。别问——这是 Java2D 图形管道使用图形硬件加速默认情况的结果。
  • Clip:将导致仅绘制部分屏幕的奇怪错误。
  • 复合:大多数操作可能并不认为这是奇怪的事情。

不用担心的属性:

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