在java中打印2页的jframe

时间:2015-03-16 06:21:25

标签: java swing printing jframe

我想打印一个包含大量文本字段和包含数据的按钮的jframe。我想通过单击打印jbutton打印此jframe。我试过这段代码。

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");
}

}

我的问题是我的jframe太大了,必须打印两页,这段代码打印第二页。我想从jframe打印第一部分。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

所以,我们需要做的第一件事是确保打印的组件符合它的首选尺寸...

component.setSize(component.getPreferredSize());

这很重要,但请记住,这会影响屏幕上的组件......

接下来,我们需要确定是否要打印新页面或重新打印当前页面。发生这种情况是因为对于给定页面可能会多次调用print ...

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

然后我们需要计算适合当前页面的组件的y偏移量...

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

如果yOffset大于component高度,那么我们就不想再打印任何页面了。

接下来,我们打印页面,要执行此操作,我们需要翻译Graphics上下文,以便yOffset成为新的0位置...

g2d.translate(0, -yOffset);

然后我们打印组件......

component.printAll(g2d);

例如......

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;
        }

    }

}

现在,这个例子只在垂直方向打印,如果你需要打印水平方向,它会变得有点复杂,但基本概念保持不变