Содержимое JPanel отображается только в верхней части страницы во время печати - PullRequest
0 голосов
/ 18 июня 2019

В настоящее время я пытаюсь добавить функцию печати в генератор символов, который создаю с использованием Java 8. Моя проблема в том, что каждый отдельный элемент будет отображаться только в верхней части страницы при использовании показанного кода.

screenshot

Весь код можно найти на github .Часть для печати расположена под src/main/java/antafes/vampireEditor/gui/BaseWindow.java, а объекты страницы можно найти в src/main/java/antafes/vampireEditor/print/.

Еще одна странная вещь для меня заключается в том, что часть влямбда-функция вызывается примерно 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 голосов
/ 26 июня 2019

Проблема заключалась в том, что компонент не был правильно размещен. @ секунда указала мне правильное направление. Как он и предложил, я заглянул в класс 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 за указание в правильном направлении.

0 голосов
/ 26 июня 2019

Печать нескольких страниц является легкой частью вашего вопроса. Используйте 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
}

(То есть каждую из ламд по-прежнему называют 2 раза, я также не уверен, почему это так).


Для вашей проблемы печати:

Пока что я не нашел (простого) решения, но основная причина, по-видимому, в том, что ваш макет просто не переносится при печати графического компонента.

В основном все на странице, но заканчивается в позиции 0,0 (верхний левый угол). Возможно, вам придется переделать макет, используя правильные координаты, или (что более вероятно) выяснить, почему макет не работает.


Edit: Я нашел класс Java, который может захватывать изображения компонентов, см https://tips4java.wordpress.com/2008/10/13/screen-image/

Кажется, есть некоторые общие проблемы при попытке использовать метод рисования JComponent, который не был визуализирован до / создан на лету без отображения.

С классом, представленным в 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());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...