java - 将多个对象添加到 JPanel 后,仅绘制最后一个 JComponent

标签 java swing

事实证明是我在错误的坐标系中思考。它总是按预期工作,但我基本上是在屏幕外绘制矩形的。 See my other stackoverflow question .

注意:我要求删除此问题,但版主决定保留此问题。

<小时/>

我有一个PdfPage extends JPanel,它代表一个被绘制为Image的PDF页面。首先,我加载图像(使用 PDFBox 渲染)并将其添加到我编写的简单分页器中。然后,我使用 PdfPage.add(JComponent component)Highlight 对象添加到每个 PdfPage,其中每个 Highlight 是应该在我的文档中注释一个错误。

我的问题是只有最后添加的Highlight被绘制,其他的都是不可见的..

public DatasheetReviserRenderer(File file, List<DatasheetError> datasheetErrorList, int resolution) {

    // ..
    this.pdfViewer = new PdfViewer(file, resolution);

    PdfPage[] pdfPages = this.pdfViewer.getPdfPages();

    List<Highlight> highlights = new ArrayList<Highlight>();

    for (DatasheetError datasheetError : datasheetErrorList) {

        int pageNumber = datasheetError.getPage();
        Highlight highlight = createErrorHighlight(datasheetError);
        highlights.add(highlight);

        PdfPage pdfPage = pdfPages[pageNumber];         
        pdfPage.add(highlight); 
    }

    this.pdfViewer.setVisible(true);
}

private Highlight createErrorHighlight(DatasheetError datasheetError) {
    // ..
    return new Highlight(rectangle, new Color(0.5f, 0.1f,0.3f, 0.4f));
}

这就是 PdfPage.java 的样子:

public class PdfPage extends JPanel {
    private static final long serialVersionUID = 7756137054877582063L;

    final Image pageImage;

    public PdfPage(Image pageImage) {
        super(new BorderLayout());
        // ..
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        paintPdfPage(g);
    }

    private void paintPdfPage(Graphics g) {
        // just draws pageImage
    }
}

这是Highlight.java:

public class Highlight extends JComponent {
    private static final long serialVersionUID = -5376556610591196188L;

    /** The rectangle that represents the highlight. */
    private Rectangle rectangle;

    /** Border is invisible per default. */
    private Color borderColor = new Color(0, 0, 0, 0);

    /** The highlight color. */
    private Color fillColor;

    public Highlight(Rectangle rectangle, Color fillColor) {
        this.setBounds(rectangle);
        this.rectangle = rectangle;
        this.fillColor = fillColor; 
    }

    @Override
    protected void paintComponent(Graphics g) {

        super.paintComponent(g);

        g.setColor(this.fillColor);
        g.fillRect(this.rectangle.x, this.rectangle.y, this.rectangle.width, this.rectangle.height);

        g.setColor(this.borderColor);
        g.drawRect(this.rectangle.x, this.rectangle.y, this.rectangle.width, this.rectangle.height);
    }

}

为什么没有绘制所有Highlight对象?

最佳答案

罪魁祸首是:

super(new BorderLayout());

每次向 PdfPage 添加组件时,它都会替换中心中的组件,并丢弃之前添加的组件。

如果您将其保留为:

super();

它将与 FlowLayout 一起使用,您可以在其中拥有任意数量的组件。但是,Highlight 组件的大小将为 0x0(因为您从未给它们指定大小),因此您绘制的任何内容也将不可见。

有两种方法可以解决这个问题:

  1. 如评论所述,使 Highlight 成为一个 POJO,并直接从 PdfPage.paint() 绘制它。
  2. 使用 null 布局和 give your components hard-coded dimensions and bounds (虽然不是一个干净的解决方案)。

关于java - 将多个对象添加到 JPanel 后,仅绘制最后一个 JComponent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31813411/

相关文章:

java - 在java中显示线程的繁忙状态

java - 显示数字小数部分的问题

java - Netbeans GUI 编程

java - 我如何使用 Java Swing 创建这个特殊的菜单栏?

java - 调用函数时按钮不会禁用

java - 图形用户界面 : action listener compiler-error

java - 当一列是派生值时,使用复合键关联两个表

java - 用一行二维 ArrayList 填充一维 Arraylist

java - SharedPreferenceclear() 抛出空指针异常

java - 如何更改 JFreeChart 的大小