为什么没有从子 JComponent 调用 paint(Graphics g)?
Why is paint(Graphics g) not getting called from child JComponent?
我有一个简单的 JComponent
,它的功能类似于 PdfPage
,但基本上只是一个渲染的 Image
。
但是,这个 PdfPage
应该包含 Highlight
注释,例如标记 PDF 文档中的错误。
Highlight
只是另一个 JComponent
,它只是将自己绘制成一个矩形:
public class Highlight extends JComponent {
private Rectangle rectangle;
private Color borderColor = new Color(0, 0, 0, 0);
private Color fillColor;
public Highlight(Rectangle rectangle, Color fillColor) {
this.rectangle = rectangle;
this.fillColor = fillColor;
}
@Override
public void paint(Graphics g) {
g.setColor(this.fillColor);
g.fillRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
g.setColor(this.borderColor);
g.drawRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
}
}
问题是将Highlight
添加到PdfPage
不会导致它被绘制:
for (DatasheetError datasheetError : datasheetErrorList) {
Highlight highlight = createErrorHighlight(datasheetError);
int pageNumber = datasheetError.getPage() - 1;
PdfPage pdfPage = pdfPages[pageNumber];
pdfPage.add(highlight);
pdfPage.repaint() // Does not help here!
pdfPage.invalidate(); // Does not help here!
}
这就是为什么我对 PdfPage
的所有子 Component
对象进行循环,并在每个 PdfPage
内部调用 paint(Graphics g)
,如下所示:
public class PdfPage extends JComponent {
// ...
@Override
public void paint(Graphics g) {
// Paint the pdf page ..
g.setColor(Color.black);
g.fillRect(0, 0, getWidth(), getHeight());
if (pageImage != null) {
int x = 0, y = 0, width = pageImage.getWidth(null), height = pageImage.getHeight(null);
g.drawImage(pageImage, x, y, width, height, null);
}
// Paint all child components such as "Highlight"
for(Component component : this.getComponents()) {
component.paint(g);
}
}
}
这是我应该做的,还是有更好的方法来绘制 PdfPage
的子组件?我曾尝试在每个 PdfPage
上调用 repaint()
和 invalidate()
,但这没有用。
为什么不从每个 Highlight
调用 pain(Graphics g)
方法?我能以某种方式执行吗?
您不应该直接绘制组件,那是 Swing 的工作。摆脱试图从 PdfPage class.
绘制高光的代码
当您将组件添加到容器时,子组件由 paintChildren(...)
方法绘制。阅读有关 A Closer Look at the Paint Mechanism 的 Swing 教程部分了解更多信息。
如评论中所述,自定义绘画是在paintComponent()
方法中完成的。在您的情况下,您覆盖了 paint() 但不调用 super.paint() 因此永远不会调用 paintChildren() 方法,因此子组件不会被绘制。
然而,当您修复此问题时,JComponent 不使用布局管理器,因此当您将组件添加到 PdfPage class 时,它们将不会被绘制。因此,您需要指定组件的大小和位置。在您的情况下,size/location 看起来像是基于矩形。
所以修复代码,让正常的 Swing 绘画机制工作,而不是尝试自己做。
或者另一种方法,如果您想进行自定义绘画,可以使用 addHighlight(...)
作为 PdfPage
class 的方法。那么在这种情况下,您将保留一个要绘制的矩形列表,并在 PdfPage 类的 paintComponent()
方法中遍历此列表。查看 Custom Painting Approaches 中的 DrawOnComponent
示例,了解此方法的工作示例。
我有一个简单的 JComponent
,它的功能类似于 PdfPage
,但基本上只是一个渲染的 Image
。
但是,这个 PdfPage
应该包含 Highlight
注释,例如标记 PDF 文档中的错误。
Highlight
只是另一个 JComponent
,它只是将自己绘制成一个矩形:
public class Highlight extends JComponent {
private Rectangle rectangle;
private Color borderColor = new Color(0, 0, 0, 0);
private Color fillColor;
public Highlight(Rectangle rectangle, Color fillColor) {
this.rectangle = rectangle;
this.fillColor = fillColor;
}
@Override
public void paint(Graphics g) {
g.setColor(this.fillColor);
g.fillRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
g.setColor(this.borderColor);
g.drawRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
}
}
问题是将Highlight
添加到PdfPage
不会导致它被绘制:
for (DatasheetError datasheetError : datasheetErrorList) {
Highlight highlight = createErrorHighlight(datasheetError);
int pageNumber = datasheetError.getPage() - 1;
PdfPage pdfPage = pdfPages[pageNumber];
pdfPage.add(highlight);
pdfPage.repaint() // Does not help here!
pdfPage.invalidate(); // Does not help here!
}
这就是为什么我对 PdfPage
的所有子 Component
对象进行循环,并在每个 PdfPage
内部调用 paint(Graphics g)
,如下所示:
public class PdfPage extends JComponent {
// ...
@Override
public void paint(Graphics g) {
// Paint the pdf page ..
g.setColor(Color.black);
g.fillRect(0, 0, getWidth(), getHeight());
if (pageImage != null) {
int x = 0, y = 0, width = pageImage.getWidth(null), height = pageImage.getHeight(null);
g.drawImage(pageImage, x, y, width, height, null);
}
// Paint all child components such as "Highlight"
for(Component component : this.getComponents()) {
component.paint(g);
}
}
}
这是我应该做的,还是有更好的方法来绘制 PdfPage
的子组件?我曾尝试在每个 PdfPage
上调用 repaint()
和 invalidate()
,但这没有用。
为什么不从每个 Highlight
调用 pain(Graphics g)
方法?我能以某种方式执行吗?
您不应该直接绘制组件,那是 Swing 的工作。摆脱试图从 PdfPage class.
绘制高光的代码当您将组件添加到容器时,子组件由 paintChildren(...)
方法绘制。阅读有关 A Closer Look at the Paint Mechanism 的 Swing 教程部分了解更多信息。
如评论中所述,自定义绘画是在paintComponent()
方法中完成的。在您的情况下,您覆盖了 paint() 但不调用 super.paint() 因此永远不会调用 paintChildren() 方法,因此子组件不会被绘制。
然而,当您修复此问题时,JComponent 不使用布局管理器,因此当您将组件添加到 PdfPage class 时,它们将不会被绘制。因此,您需要指定组件的大小和位置。在您的情况下,size/location 看起来像是基于矩形。
所以修复代码,让正常的 Swing 绘画机制工作,而不是尝试自己做。
或者另一种方法,如果您想进行自定义绘画,可以使用 addHighlight(...)
作为 PdfPage
class 的方法。那么在这种情况下,您将保留一个要绘制的矩形列表,并在 PdfPage 类的 paintComponent()
方法中遍历此列表。查看 Custom Painting Approaches 中的 DrawOnComponent
示例,了解此方法的工作示例。