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