我希望这个问题不会被认为太笼统。我知道要在 a 上绘图,JPanel
您会覆盖该paintComponent
方法并将所有绘图代码放在该方法中。我的问题是为什么!为什么 Java 似乎不允许/提供使用诸如panel.drawLine(x1,y1,x2,y2)
or之类的方法进行绘图panel.drawText(text,x,y)
?在delphi中这一切都容易得多。一定是有原因的,我就是想不通。
1 回答
那是因为这就是它的工作方式。它是这样设计的。但我想你的问题是关于“为什么”
请记住,Swing 于 15 年前首次问世。其中一个批评是 API 很慢(事实上,它很慢,因为人们并不真正了解如何使用它,但这是另一回事),因此 API 的设计必须考虑到性能。
涉及到很多因素...
Swing 使用被动绘制过程,这意味着绘制请求被发送到绘制子系统并安排(返回 EDT)进行处理。绘制子系统决定应该绘制什么、何时以及绘制多少。这是在亵渎油漆子系统时完成的。
这意味着您永远不会真正知道何时可以执行绘制周期,因此我们需要某种方式来响应这些请求。
多功能性是另一个因素。API 足够抽象,以至于组件被绘制到哪里并不重要(很多)。也就是说,您可能正在被绘制到屏幕、打印机甚至图像上。这意味着您不必重复大量的绘制代码即可使其在不同的设备上工作。
您也永远不知道组件何时会变得可显示(即,何时连接到本机对等点)。这意味着图形上下文可能是null
,因此拥有“帮助”方法实际上可能会导致更多问题。当paintComponent
被调用时,你(大部分)保证有一个有效的图形上下文来绘制。
可扩展性将是另一个因素。不仅很容易重写paintComponent
以改变某些组件的绘制方式,而且绘制系统还可以提供扩展的 Graphics 上下文,就像当前的情况一样。当paintComponent
被调用时(至少由绘制子系统调用),它保证Graphics
上下文将是 的实例Graphics2D
,它是 的扩展Graphics
,为 API 提供了许多重要的增强。
这一切都无需更改人们正在使用的基类即可完成,因此如果他们不想使用这些功能,则不会受到它们的影响。
你可能想通读一遍……
更多细节
并记住“绘画很有趣”;)
额外的想法
要考虑的其他考虑因素之一是Graphics
API 是绘画的核心,不仅要考虑 UI,还要考虑打印和图像处理。API 与其目标断开连接,从而提供更大的灵活性,但也具有通用性。
这意味着如果您需要打印到打印机或渲染到图像,您可以使用与在屏幕上绘画相同的 API。