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