当前位置: 代码迷 >> java >> 为什么未从子JComponent调用paint(Graphics g)?
  详细解决方案

为什么未从子JComponent调用paint(Graphics g)?

热度:111   发布时间:2023-07-17 21:07:33.0

我有一个简单的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) PdfPage ,如下所示:

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类绘制突出显示的代码。

将组件添加到容器时,子组件将通过paintChildren(...)方法绘制。 阅读Swing教程中有关的更了解的部分,以获取更多信息。

如评论中所述,自定义绘制是在paintComponent()方法中完成的。 在您的情况下,您覆盖了paint(),但不调用super.paint(),因此永远不会调用paintChildren()方法,因此不会绘制子组件。

但是,当您解决此问题时,JComponent不使用布局管理器,因此当您将组件添加到PdfPage类时,它们将不会被绘制。 因此,您需要指定组件的大小和位置。 在您的情况下,看起来大小/位置将基于Rectangle。

因此,修复代码并让常规的Swing绘画机制起作用,而不要自己尝试这样做。

或者,如果您要进行自定义绘制,则addHighlight(...)一种方法是将PdfPage addHighlight(...)作为PdfPage类的方法。 然后,在这种情况下,您将保留一个要绘制的矩形列表,并在PdfPage类别的paintComponent()方法中遍历此列表。 查看“自的DrawOnComponent示例,以获取该方法的有效示例。

  相关解决方案