解决常见的绘画问题

原文: https://docs.oracle.com/javase/tutorial/uiswing/painting/problems.html

问题:我不知道在哪里放我的绘画代码。

  • 绘画代码属于JComponent的任何组件的paintComponent方法。

问题:我画的东西没有显示出来。

  • 检查您的组件是否完全显示。 解决常见组件问题可以为您提供帮助。
  • 检查组件是否在需要更新其外观时调用repaint

问题:我的组件前景显示,但其背景不可见。结果是直接在我的组件后面的一个或多个组件出乎意料地可见。

  • 确保您的组件不透明。例如,JPanel在许多情况下默认是不透明的,但并非所有外观都是不透明的。要使JLabel和 GTK + JPanel等组件不透明,必须在它们上调用setOpaque(true)
  • 如果您的自定义组件扩展JPanel或更专业的JComponent后代,则可以在绘制组件内容之前通过调用super.paintComponent来绘制背景。
  • 您可以使用自定义组件paintComponent方法顶部的代码自己绘制背景:

    1. g.setColor(getBackground());
    2. g.fillRect(0, 0, getWidth(), getHeight());
    3. g.setColor(getForeground());

问题:我使用setBackground设置组件的背景颜色,但似乎没有效果。

  • 最有可能的是,您的组件不会绘制其背景,因为它不是不透明的,或者您的自定义绘制代码不会绘制背景。例如,如果为JLabel设置背景颜色,则还必须在标签上调用setOpaque(true)以使标签的背景被绘制。

问题:我使用完全相同的代码作为教程示例,但它不起作用。为什么?

  • 代码是否以与教程示例完全相同的方式执行?例如,如果教程示例在示例的paintComponent方法中包含代码,则此方法可能是保证代码有效的唯一位置。

问题:如何画粗线?模式?

  • Java™2D API 为实现线宽和样式提供了广泛的支持,以及用于填充和描边形状的模式。有关使用 Java 2D API 的更多信息,请参阅 2D 图形跟踪。

问题:特定组件的边缘看起来很奇怪。

  • 因为组件经常更新其边框以反映组件状态,所以除了JPanelJComponent的自定义子类之外,通常应该避免调用setBorder
  • 是否使用 UI 绘制的边框而不是Border对象来绘制具有外观和感觉的组件(如 GTK +或 Windows XP)?如果是这样,请不要在组件上调用setBorder
  • 组件是否具有自定义绘制代码?如果是这样,绘画代码是否考虑了组件的插图?

问题:视觉工件出现在我的 GUI 中。

  • 如果设置组件的背景颜色,请确保如果组件应该是不透明的,则颜色没有透明度。
  • 如有必要,使用setOpaque方法设置组件不透明度。例如,内容窗格必须是不透明的,但具有透明背景的组件不能是不透明的。
  • 如果它是不透明的,请确保您的自定义组件完全填充其绘画区域。

问题:我的自定义绘画代码的性能很差。

  • 如果可以绘制部件的一部分,请使用GraphicsgetClipgetClipBounds方法确定需要绘制的区域。你画的越少,它就越快。
  • 如果只需要更新组件的一部分,请使用指定绘制区域的repaint版本进行绘制请求。
  • 有关选择高效绘画技术的帮助,请在 Java Media API 主页中查找字符串“performance”。

问题:应用于看似相同的Graphics对象的相同变换有时会产生稍微不同的效果。

  • 因为 Swing 绘制代码在调用paintComponent之前设置变换(使用Graphics方法translate),所以应用的任何变换都具有累积效果。这在进行简单翻译时无关紧要,但更复杂的AffineTransform可能会产生意外结果。

如果在此列表中没有看到问题,请参阅解决常见组件问题解决常见布局问题