Calm Sea
Calm Sea

Reputation: 181

control the size of the panel on printed page

i want to print jpanel with two tables . Two problems i faced , the first one is the Accuracy of the printed image is not very good. the second how can i control the size of the jpanel on the printed page??

here is an image of the printed page using xps viewer(the accuracy is not good) enter image description here

is there away to make the printed image with this accuracy enter image description herelike this

and this is the code:

     PrinterJob printjob = PrinterJob.getPrinterJob();
    printjob.setJobName(" TESSCO CUSTOMER CARD ");

    Printable printable = new Printable() {

            public int print(Graphics pg, PageFormat pf, int pageNum) {

                    if (pageNum > 0) {
                            return Printable.NO_SUCH_PAGE;
                    }

                    Dimension size = jPanel1.getSize();
                    BufferedImage bufferedImage = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);

                    jPanel1.print(bufferedImage.getGraphics());

                    Graphics2D g2 = (Graphics2D) pg;
                    g2.translate(pf.getImageableX(), pf.getImageableY());
                    g2.drawImage(bufferedImage, 0, 0, (int) pf.getWidth(), (int) pf.getHeight(), null);

                    return Printable.PAGE_EXISTS;
            }
    };

    Paper paper = new Paper();
    paper.setImageableArea(0, 0,700,890);
    paper.setSize(700,890);

    PageFormat format = new PageFormat();
    format.setPaper(paper);
    format.setOrientation(PageFormat.LANDSCAPE);

    printjob.setPrintable(printable, format);
    if (printjob.printDialog() == false)
            return;

    try {
            printjob.print();
    } catch (PrinterException ex) {
            System.out.println("NO PAGE FOUND." + ex);

    }

Upvotes: 0

Views: 1976

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347334

Firstly, don't use the pane size, you need to act as the layout manager and size the panel to fit the page.

Secondly, don't use a buffered image. This will not share the same properties as the graphics context past to you by the print engine. Also, another print method is re-entrant, meaning that it may called a number of times for each page, creating a buffered image this way is wasteful on resources

You might like to take a look at How to Print Tables

UPDATE

You could do something like...

public int print(Graphics pg, PageFormat pf, int pageNum) {
    if (page > 0) {
        return NO_SUCH_PAGE;
    }

    Graphics2D g2d = (Graphics2D)pg;

    double pageWidth = pf.getImageableWidth();
    double pageHeight = pf.getImageableHeight();

    double pageX = pf.getImageableX();
    double pageY = pf.getImageableY();

    g2d.translate(pageX, pageY);

    double tableHeight = pageHeight / 2d;

    jPanel1.setBounds(0, 0, (int)Math.floor(pageWidth), (int)Math.floor(pageHeight));
    jPanel1.printAll(g2d);

    return Printable.PAGE_EXISTS;

}

Just beware, that this could have the potential of truncating your table. Also, you should not do this with a Component that is already on the screen. You should create a new "print" component.

UPDATE with working example

Okay, so the concept is sound, just needed some tweaking to get it to work ;)

enter image description here

public class PrintTableTest {

    public static void main(String[] args) {

        final JTable table1 = new JTable(new AbstractTableModel() {
            @Override
            public int getRowCount() {
                return 3;
            }

            @Override
            public int getColumnCount() {
                return 3;
            }

            @Override
            public String getColumnName(int column) {
                String name = null;
                switch (column) {
                    case 0:
                        name = "Day";
                        break;
                    case 1:
                        name = "FirstName";
                        break;
                    case 2:
                        name = "LastName";
                        break;
                }
                return name;
            }

            @Override
            public Object getValueAt(int rowIndex, int columnIndex) {
                Object value = null;
                switch (columnIndex) {
                    case 0:
                        switch (rowIndex) {
                            case 0:
                                value = "First";
                                break;
                            case 1:
                                value = "Second";
                                break;
                            case 2:
                                value = "Final";
                                break;
                        }
                        break;
                }
                return value;
            }
        });
        int rowHeight = (int) Math.floor(((700f / 2f) - table1.getTableHeader().getPreferredSize().height) / 3f);
        table1.setRowHeight(rowHeight);

        PrinterJob printjob = PrinterJob.getPrinterJob();
        printjob.setJobName(" TESSCO CUSTOMER CARD ");

        Printable printable;
        printable = new Printable() {
            public int print(Graphics pg, PageFormat pf, int pageNum) {

                if (pageNum > 0) {
                    return NO_SUCH_PAGE;
                }

                Graphics2D g2d = (Graphics2D) pg;

                double pageWidth = pf.getImageableWidth();
                double pageHeight = pf.getImageableHeight();

                double pageX = pf.getImageableX();
                double pageY = pf.getImageableY();

                g2d.translate(pageX, pageY);

                // Each table will take half the page...
                double tableHeight = pageHeight / 2d;

                // We need to print the header as well...
                JTableHeader header = table1.getTableHeader();
                int headerHeight = header.getPreferredSize().height;

                int yOffset = 0;

                for (int index = 0; index < 2; index++) {
                    // Set the bounds of the components
                    // The yOffset is actuall irrelevent to us, but for consitency sake
                    // we'll keep it.
                    header.setBounds(0, yOffset, (int) Math.floor(pageWidth), headerHeight);
                    table1.setBounds(0, yOffset + headerHeight, (int) Math.floor(pageWidth), (int) Math.floor(tableHeight));
                    // Force the components to update there internal layouts to match
                    // the new size. We need to do this because, technically, we're not
                    // attached to any peer, nor do we want them to be taking into account
                    // the dimensions of any parent any way :P
                    table1.doLayout();
                    header.doLayout();

                    // Translate the graphics.  Components asume a position of 0x0 when
                    // painting.  This is a side effect of the AWT/Swing painting engine
                    // (for which we are greatful), but we need to simulate the change
                    g2d.translate(0, yOffset);
                    header.printAll(g2d);
                    // Translations are relative to the last translation...
                    g2d.translate(0, headerHeight);
                    table1.printAll(g2d);
                    // Reset the last translation
                    g2d.translate(0, -(headerHeight + yOffset));

                    // Next table...
                    yOffset += table1.getHeight();
                }
                return Printable.PAGE_EXISTS;
            }
        };

        Paper paper = new Paper();
        paper.setImageableArea(0, 0, 700, 890);
        paper.setSize(700, 890);

        PageFormat format = new PageFormat();
        format.setPaper(paper);
        format.setOrientation(PageFormat.LANDSCAPE);

//        printjob.setPrintable(printable, format);
        BufferedImage img = new BufferedImage(890, 700, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = img.createGraphics();
        g2d.setColor(Color.WHITE);
        g2d.fill(new Rectangle(0, 0, 890, 700));
        try {
            printable.print(g2d, format, 0);
        } catch (Exception exp) {
            exp.printStackTrace();
        }
        g2d.dispose();

        try {
            ImageIO.write(img, "png", new File("Print.png"));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

Upvotes: 1

Related Questions