Отправьте JPanel на принтер

Можно ли просто отправить на принтер JPanel или любой другой компонент? Или мне нужно вручную реализовать весь рисунок графического объекта?

Я пытался использовать функции Print * JPanel для печати в графический объект, но печатаемая страница остается пустой.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
5 841
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Этот учебник упоминает перевод объекта Graphics. Вы пробовали это?

Ответ принят как подходящий

Ознакомьтесь с API печати Java и учебник вместе с JComponent.print (Graphics).

Вот элементарный класс, который будет печатать любой компонент, который умещается на 1 странице (я не могу поверить в это, я получил код от Учебник Марти Холла):

import java.awt.*;
import java.awt.print.*;
import javax.swing.*;

/**
 * Generic component printer.  This object allows any AWT or Swing component  (or DCT system)
 * to be printed by performing it pre and post print responsibilities.
 * <p>
 * When printing components, the role of the print method is nothing more than to scale the Graphics, turn off double
 * buffering, and call paint.  There is no particular reason to put that print method in the component being printed.  A
 * better approach is to build a generic printComponent method to which you simply pass the component you want printed.
 * <p>
 * With Swing, almost all components have double buffering turned on by default. In general, this is a great benefit,
 * making for convenient and efficient painting. However, in the specific case of printing, it can is a huge problem.
 * First, since printing components relies on scaling the coordinate system and then simply calling the component's
 * paint method, if double buffering is enabled printing amounts to little more than scaling up the buffer (off-screen
 * image) which results in ugly low-resolution printing like you already had available. Secondly, sending these huge
 * buffers to the printer results in huge print spooler files which take a very long time to print. Consequently this
 * object globally turns off double buffering before printing and turns it back on afterwards.
 * <p>
 * Threading Design : [x] Single Threaded  [ ] Threadsafe  [ ] Immutable  [ ] Isolated
 */

public class ComponentPrinter
extends Object
implements Printable
{

// *****************************************************************************
// INSTANCE PROPERTIES
// *****************************************************************************

private Component                       component;                              // the component to print

// *****************************************************************************
// INSTANCE CREATE/DELETE
// *****************************************************************************

public ComponentPrinter(Component com) {
    component=com;
    }

// *****************************************************************************
// INSTANCE METHODS
// *****************************************************************************

public void print() throws PrinterException {
    PrinterJob                          printJob=PrinterJob.getPrinterJob();

    printJob.setPrintable(this);
    if (printJob.printDialog()) {
        printJob.print();
        }
    }

public int print(Graphics gc, PageFormat pageFormat, int pageIndex) {
    if (pageIndex>0) {
        return NO_SUCH_PAGE;
        }

    RepaintManager                      mgr=RepaintManager.currentManager(component);
    Graphics2D                          g2d=(Graphics2D)gc;

    g2d.translate(pageFormat.getImageableX(),pageFormat.getImageableY());
    mgr.setDoubleBufferingEnabled(false);                                       // only for swing components
    component.paint(g2d);
    mgr.setDoubleBufferingEnabled(true);                                        // only for swing components
    return PAGE_EXISTS;
    }

// *****************************************************************************
// STATIC METHODS
// *****************************************************************************

static public void printComponent(Component com) throws PrinterException {
    new ComponentPrinter(com).print();
    }

} // END PUBLIC CLASS

пожалуйста, рассмотрите этот ответ для печати Component на нескольких страницах:

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.*;

import javax.swing.RepaintManager;

public class PrintMultiPageUtil implements Printable, Pageable {
    private Component componentToBePrinted;
    private PageFormat format;
    private int numPages;

    public PrintMultiPageUtil(Component componentToBePrinted) {
        this.componentToBePrinted = componentToBePrinted;

        // get total space from component  
        Dimension totalSpace = this.componentToBePrinted.getPreferredSize();

        // calculate for DIN A4
        format = PrinterJob.getPrinterJob().defaultPage();
        numPages = (int) Math.ceil(totalSpace .height/format.getImageableHeight());
    }

    public void print() {
        PrinterJob printJob = PrinterJob.getPrinterJob();

        // show page-dialog with default DIN A4
        format = printJob.pageDialog(printJob.defaultPage());

        printJob.setPrintable(this);
        printJob.setPageable(this);

        if (printJob.printDialog())
            try {
                printJob.print();
            } catch(PrinterException pe) {
                System.out.println("Error printing: " + pe);
            }
    }

    public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
        if ((pageIndex < 0) | (pageIndex >= numPages)) {
            return(NO_SUCH_PAGE);
        } else {
            Graphics2D g2d = (Graphics2D)g;
            g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY() - pageIndex * pageFormat.getImageableHeight());
            disableDoubleBuffering(componentToBePrinted);
            componentToBePrinted.paint(g2d);
            enableDoubleBuffering(componentToBePrinted);
            return(PAGE_EXISTS);
        }
    }

    public static void disableDoubleBuffering(Component c) {
        RepaintManager currentManager = RepaintManager.currentManager(c);
        currentManager.setDoubleBufferingEnabled(false);
    }

    public static void enableDoubleBuffering(Component c) {
        RepaintManager currentManager = RepaintManager.currentManager(c);
        currentManager.setDoubleBufferingEnabled(true);
    }

    @Override
    public int getNumberOfPages() {
        // TODO Auto-generated method stub
        return numPages;
    }

    @Override
    public PageFormat getPageFormat(int arg0) throws IndexOutOfBoundsException {
        return format;
    }

    @Override
    public Printable getPrintable(int arg0) throws IndexOutOfBoundsException {
        // TODO Auto-generated method stub
        return this;
    }
}

Другие вопросы по теме