JPanel的内容仅在打印时显示在页面顶部

时间:2019-06-18 11:16:26

标签: java printing

我目前正在尝试向使用Java 8创建的字符生成器添加打印功能。我的问题是,在使用显示的代码时,每个元素都只会显示在页面顶部。

screenshot

完整的代码可以在github上找到。打印部分位于src/main/java/antafes/vampireEditor/gui/BaseWindow.java下,而页面对象可以在src/main/java/antafes/vampireEditor/print/中找到。

对我来说,另一个奇怪的事情是,lambda函数中的部分被调用了大约10次...这正常吗?

如果您需要更多信息,请告诉我。

如果已经使用一个字符显示的打印预览元素(至少用于当前选择的页面)(三行已注释掉),我就设法使其工作。

if (!this.isAnyCharacterLoaded()) {
    return;
}

PrinterJob printerJob = PrinterJob.getPrinterJob();
printerJob.setJobName(this.language.translate("printCharacter"));
printerJob.setPrintable ((graphics, pageFormat, pageNum) -> {
    if (pageNum > 0){
        return Printable.NO_SUCH_PAGE;
    }

    Graphics2D graphics2D = (Graphics2D) graphics;
    graphics2D.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
    //CharacterTabbedPane pane = (CharacterTabbedPane) charactersTabPane.getSelectedComponent();
    //PrintPreviewPanel printPreview = pane.getPrintPreview();
    //printPreview.printContent(graphics2D);
    PrintBase page;

    switch (pageNum) {
        case 0:
        default:
            page = new General(this.getActiveCharacter(), false);
            break;
    }

    Dimension dimension = new Dimension((int) pageFormat.getWidth(), (int) pageFormat.getHeight());
    page.setSize(dimension);
    page.create();
    page.paint(graphics2D);

    return Printable.PAGE_EXISTS;
});

if (!printerJob.printDialog()) {
    return;
}

try {
    printerJob.print();
} catch (PrinterException ex) {
    // handle exception
}

页面上的内容应在打印预览中显示。

screenshot print preview

2 个答案:

答案 0 :(得分:0)

打印多页是您问题的简单部分。 使用java.awt.print.Book。

可以这样做:

PrinterJob printerJob = PrinterJob.getPrinterJob();
printerJob.setJobName(this.language.translate("printCharacter"));

Book pBook = new Book();
pBook.append((graphics, pageFormat, pageNum) -> {

        graphics.setColor(Color.RED);
        graphics.fillRect(50, 50, 100, 100);

        return Printable.PAGE_EXISTS;
    },
    printerJob.defaultPage()
);

pBook.append(
    (graphics, pageFormat, pageNum) -> {

        graphics.setColor(Color.BLUE);
        graphics.fillRect(50, 50, 100, 100);

        return Printable.PAGE_EXISTS;
    },
    printerJob.defaultPage()
);

printerJob.setPageable(pBook);
if (!printerJob.printDialog()) {
    return;
}

try {
    printerJob.print();
} catch (PrinterException ex) {
    // handle exception
}

(因此每个lamda仍被调用2次,我也不知道为什么会这样)。


针对您的打印问题:

到目前为止,我还没有找到一个(简单的)解决方案,但是根本原因似乎是您的布局在打印图形组件时没有保留。

基本上所有内容都在页面上,但最终到达位置0,0(左上角)。 您可能需要使用适当的坐标来重做布局,或者(更可能是)弄清楚为什么布局不起作用。


编辑: 我发现了一个Java类,可以捕获组件的图像, 参见https://tips4java.wordpress.com/2008/10/13/screen-image/

在尝试使用JComponent的paint方法时似乎存在一些一般性问题,该方法在创建/时不呈现蜂鸣声的情况下尚未呈现。

使用Link中提供的类,它可以工作,但是缩放仍需要一些工作。

        Book pBook = new Book();
        pBook.append((graphics, pageFormat, pageNum) -> {

            Graphics2D graphics2D = (Graphics2D) graphics;
            graphics2D.translate(pageFormat.getImageableX(), pageFormat.getImageableY());

            PrintBase page = new General(this.getActiveCharacter(), false);

            Dimension dimension = new Dimension((int) pageFormat.getWidth(), (int) pageFormat.getHeight());
            page.setSize(dimension);
            page.create();

            BufferedImage image = ScreenImage.createImage(page);            
            graphics2D.drawImage(image,new AffineTransform(1f,0f,0f,1f,0,0), null);

            return Printable.PAGE_EXISTS;
        }, printerJob.defaultPage());

答案 1 :(得分:0)

问题是,组件的布局不正确。 @second为我指明了正确的方向。正如他建议的那样,我研究了ScreenImage类。使用此类创建图像很有效,因此我开始使用ScreenImage类来实现打印过程。

经过一段时间的思考之后,我发现我只需要该类的一个方法即可。我采用了layoutComponent()方法并仅使用了该方法。使用此功能后,元素将正确布局,现在显示出我想要它们的方式。

private void layoutComponent(Component component)
{
    synchronized (component.getTreeLock())
    {
        component.doLayout();

        if (component instanceof Container)
        {
            for (Component child : ((Container)component).getComponents())
            {
                this.layoutComponent(child);
            }
        }
    }
}

稍后对纸张进行一些调整,一切看起来都应该是:)

再次感谢@second将我指向正确的方向。