Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
578 views
in Technique[技术] by (71.8m points)

swing - printing a 2 pages of jframe in java

i would like to print a jframe that contain a lot of textfield and buttons that contain a data. i want to print this jframe by clicking a Print jbutton. i tried this code.

protected void print() {
PrinterJob job = PrinterJob.getPrinterJob();
if(job.printDialog()){
  try {
    job.setPrintable(new Printable() {

      @Override
      public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
        if(pageIndex == 0){
          Graphics2D g2d = (Graphics2D)graphics;
          g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());

        Dimension dim = ODietListJFrame.this.getSize();
        double cHeight = dim.getHeight();
        double cWidth = dim.getWidth();

        // get the bounds of the printable area
        double pHeight = pageFormat.getImageableHeight();
        double pWidth = pageFormat.getImageableWidth();

        double xRatio = pWidth / cWidth;
        double yRatio = pHeight / cHeight;

        g2d.scale(xRatio, yRatio);

          ODietListJFrame.this.printAll(g2d);
          return PAGE_EXISTS;
        }
        return NO_SUCH_PAGE;
      }
    });
    job.print();
  } catch (PrinterException e) {
    e.printStackTrace();
  }
} else {
  System.err.println("Error printing");
}

}

My problem is that my jframe is too large that is must be print in two pages and this code print the second page. i want to print the first part from the jframe.

Thanks for help.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

So, the first thing we need to is make sure that the component been printed is at it's preferred size...

component.setSize(component.getPreferredSize());

This is important, but also remember, that this will affect the component that is on the screen...

Next, we need to work out if we are printing a new page or re-printing the current page. This occurs because print might be called multiple times for a given page...

if (lastPage != pageIndex) {
    lastPage = pageIndex;
    //...
}

We then need to calculate the y offset of the component that fits the current page...

yOffset = height * pageIndex;
if (yOffset > component.getHeight()) {
    yOffset = -1;
}

If the yOffset is greater then the component height, then we don't want to print any more pages.

Next, we print the page, to do this, we need to translate the Graphics context so that the yOffset becomes the new 0 position...

g2d.translate(0, -yOffset);

Then we print the component...

component.printAll(g2d);

For example...

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.PrinterResolution;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Scrollable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class PrintMe {

    public static void main(String[] args) {
        new PrintMe();
    }

    public PrintMe() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                TestPane testPane = new TestPane();

                JButton btn = new JButton("Print");
                btn.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
                        aset.add(MediaSizeName.ISO_A4);
                        aset.add(new PrinterResolution(300, 300, PrinterResolution.DPI));

                        PrinterJob pj = PrinterJob.getPrinterJob();
                        pj.setPrintable(new MultiPagePrintable(testPane));

                        if (pj.printDialog(aset)) {
                            try {
                                pj.print(aset);
                                testPane.getParent().invalidate();
                                testPane.getParent().validate();
                            } catch (PrinterException ex) {
                                ex.printStackTrace();
                            }
                        }
                    }
                });

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(testPane));
                frame.add(btn, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel implements Scrollable {

        private BufferedImage img;

        public TestPane() {
            try {
                img = ImageIO.read(new File("Get your own image"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return img == null ? new Dimension(200, 200) : new Dimension(img.getWidth(), img.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (img != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                int x = (getWidth() - img.getWidth()) / 2;
                int y = (getHeight() - img.getHeight()) / 2;
                g2d.drawImage(img, x, y, this);
                g2d.dispose();
            }
        }

        @Override
        public Dimension getPreferredScrollableViewportSize() {
            return new Dimension(200, 200);
        }

        @Override
        public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 128;
        }

        @Override
        public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 128;
        }

        @Override
        public boolean getScrollableTracksViewportWidth() {
            return false;
        }

        @Override
        public boolean getScrollableTracksViewportHeight() {
            return false;
        }

    }

    public class MultiPagePrintable implements Printable {

        private JComponent component;
        private int lastPage = 0;
        private double yOffset;

        public MultiPagePrintable(JComponent component) {
            this.component = component;
        }

        @Override
        public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
            int result = NO_SUCH_PAGE;

            double height = pageFormat.getImageableHeight();
            component.setSize(component.getPreferredSize());

            if (lastPage != pageIndex) {
                lastPage = pageIndex;
                yOffset = height * pageIndex;
                if (yOffset > component.getHeight()) {
                    yOffset = -1;
                }
            }

            if (yOffset >= 0) {
                Graphics2D g2d = (Graphics2D) graphics;

                g2d.translate((int) pageFormat.getImageableX(),
                                (int) pageFormat.getImageableY());

                g2d.translate(0, -yOffset);
                component.printAll(g2d);
                result = PAGE_EXISTS;
            }
            return result;
        }

    }

}

Now, this example only prints in the vertical direction, if you need it to print the horizontal direction as well, it gets a little more complicated, but that the basic concept remains the same


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...