解决常见的绘画问题
原文: https://docs.oracle.com/javase/tutorial/uiswing/painting/problems.html
问题:我不知道在哪里放我的绘画代码。
- 绘画代码属于
JComponent
的任何组件的paintComponent
方法。
问题:我画的东西没有显示出来。
- 检查您的组件是否完全显示。 解决常见组件问题可以为您提供帮助。
- 检查组件是否在需要更新其外观时调用
repaint
。
问题:我的组件前景显示,但其背景不可见。结果是直接在我的组件后面的一个或多个组件出乎意料地可见。
- 确保您的组件不透明。例如,
JPanel
在许多情况下默认是不透明的,但并非所有外观都是不透明的。要使JLabel
和 GTK +JPanel
等组件不透明,必须在它们上调用setOpaque(true)
。 - 如果您的自定义组件扩展
JPanel
或更专业的JComponent
后代,则可以在绘制组件内容之前通过调用super.paintComponent
来绘制背景。 您可以使用自定义组件
paintComponent
方法顶部的代码自己绘制背景:g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(getForeground());
问题:我使用setBackground
设置组件的背景颜色,但似乎没有效果。
- 最有可能的是,您的组件不会绘制其背景,因为它不是不透明的,或者您的自定义绘制代码不会绘制背景。例如,如果为
JLabel
设置背景颜色,则还必须在标签上调用setOpaque(true)
以使标签的背景被绘制。
问题:我使用完全相同的代码作为教程示例,但它不起作用。为什么?
- 代码是否以与教程示例完全相同的方式执行?例如,如果教程示例在示例的
paintComponent
方法中包含代码,则此方法可能是保证代码有效的唯一位置。
问题:如何画粗线?模式?
- Java™2D API 为实现线宽和样式提供了广泛的支持,以及用于填充和描边形状的模式。有关使用 Java 2D API 的更多信息,请参阅 2D 图形跟踪。
问题:特定组件的边缘看起来很奇怪。
- 因为组件经常更新其边框以反映组件状态,所以除了
JPanel
和JComponent
的自定义子类之外,通常应该避免调用setBorder
。 - 是否使用 UI 绘制的边框而不是
Border
对象来绘制具有外观和感觉的组件(如 GTK +或 Windows XP)?如果是这样,请不要在组件上调用setBorder
。 - 组件是否具有自定义绘制代码?如果是这样,绘画代码是否考虑了组件的插图?
问题:视觉工件出现在我的 GUI 中。
- 如果设置组件的背景颜色,请确保如果组件应该是不透明的,则颜色没有透明度。
- 如有必要,使用
setOpaque
方法设置组件不透明度。例如,内容窗格必须是不透明的,但具有透明背景的组件不能是不透明的。 - 如果它是不透明的,请确保您的自定义组件完全填充其绘画区域。
问题:我的自定义绘画代码的性能很差。
- 如果可以绘制部件的一部分,请使用
Graphics
的getClip
或getClipBounds
方法确定需要绘制的区域。你画的越少,它就越快。 - 如果只需要更新组件的一部分,请使用指定绘制区域的
repaint
版本进行绘制请求。 - 有关选择高效绘画技术的帮助,请在 Java Media API 主页中查找字符串“performance”。
问题:应用于看似相同的Graphics
对象的相同变换有时会产生稍微不同的效果。
- 因为 Swing 绘制代码在调用
paintComponent
之前设置变换(使用Graphics
方法translate
),所以应用的任何变换都具有累积效果。这在进行简单翻译时无关紧要,但更复杂的AffineTransform
可能会产生意外结果。