Print JFrame with setVisible(false)

前端 未结 1 1171
忘掉有多难
忘掉有多难 2021-01-25 13:52

I create a Swing application with 2 JFrame windows and I want to 1st frame as main page. I set print button in 1st frame to print 2nd frame.

How can I print

1条回答
  •  野趣味
    野趣味 (楼主)
    2021-01-25 14:36

    How I hate printing components, seriously, either learn to do it by hand or use something like Jasper Reports.

    You have a series of issues...

    1. Components can only have one parent, so when you create your second window and add the components to it, you're removing them from the first window;
    2. You can't paint an invisible component;
    3. You really shouldn't be printing the frame anyway, better to print the panel instead;
    4. Unless it's been realised on the screen, you'll be responsible for ensure that the component is properly laid out before it's printed

    You really don't want to print the frame, you actually want to print the panel instead, it's just a lot simpler and you don't get the frame. If you want to print the frame as well, you will need to make the frame visible.

    So, based on this previous answer

    So, basically, this adds a simple factory method to create the base panel. This will make two instances of this panel, one to print and one to display (technically you could use one, but you get the idea).

    The printing process will update the layout of the panel while it's printing to make sure that it's contents are properly laid, so that they are actually rendered.

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.print.PageFormat;
    import java.awt.print.Printable;
    import static java.awt.print.Printable.NO_SUCH_PAGE;
    import static java.awt.print.Printable.PAGE_EXISTS;
    import java.awt.print.PrinterException;
    import java.awt.print.PrinterJob;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    
    class PrintUIWindow implements Printable, ActionListener {
    
        JPanel frameToPrint;
        boolean fill = false;
    
        public int print(Graphics g, PageFormat pf, int page) throws
                        PrinterException {
    
            if (page > 0) {
                return NO_SUCH_PAGE;
            }
            double width = (int) Math.floor(pf.getImageableWidth());
            double height = (int) Math.floor(pf.getImageableHeight());
    
            if (!fill) {
    
                width = Math.min(width, frameToPrint.getPreferredSize().width);
                height = Math.min(height, frameToPrint.getPreferredSize().height);
    
            }
    
            System.out.println(width + "x" + height);
            Graphics2D g2d = (Graphics2D) g;
            g2d.translate(pf.getImageableX(), pf.getImageableY());
            System.out.println(width + "x" + height);
            frameToPrint.setBounds(0, 0, (int) Math.floor(width), (int) Math.floor(height));
            if (frameToPrint.getParent() == null) {
                frameToPrint.addNotify();
            }
            frameToPrint.validate();
            frameToPrint.doLayout();
            frameToPrint.printAll(g2d);
            if (frameToPrint.getParent() != null) {
                frameToPrint.removeNotify();
            }
    
            return PAGE_EXISTS;
        }
    
        public void actionPerformed(ActionEvent e) {
            PrinterJob job = PrinterJob.getPrinterJob();
            job.setPrintable(this);
            boolean ok = job.printDialog();
            if (ok) {
                try {
                    job.print();
                } catch (PrinterException ex) {
                    System.out.println(ex);
                }
            }
        }
    
        public PrintUIWindow(JPanel f) {
            frameToPrint = f;
        }
    
        public static void forceLayout(JPanel panel) {
            if (panel.getParent() == null) {
                panel.addNotify();
            }
            panel.validate();
            panel.doLayout();
            if (panel.getParent() != null) {
                panel.removeNotify();
            }
        }
    
        public static JPanel makePanel() {
            JLabel label11 = new JLabel("Selling Bill", JLabel.LEFT);
            JLabel label21 = new JLabel("Customer Name :", JLabel.LEFT);
            JLabel label31 = new JLabel("Buying Date :", JLabel.LEFT);
            JLabel label41 = new JLabel("Book Buyed :", JLabel.LEFT);
            JLabel label51 = new JLabel("Number :", JLabel.LEFT);
            JLabel label61 = new JLabel("Total Price :", JLabel.LEFT);
            label11.setFont(new Font("Courier New", Font.BOLD, 13));
            label21.setFont(new Font("Courier New", Font.BOLD, 13));
            label31.setFont(new Font("Courier New", Font.BOLD, 13));
            label41.setFont(new Font("Courier New", Font.BOLD, 13));
            label51.setFont(new Font("Courier New", Font.BOLD, 13));
            label61.setFont(new Font("Courier New", Font.BOLD, 13));
            JPanel panel1 = new JPanel();
            panel1.setLayout(new GridLayout(6, 1));
            panel1.add(label11);
            panel1.add(label21);
            panel1.add(label31);
            panel1.add(label41);
            panel1.add(label51);
            panel1.add(label61);
            panel1.setBackground(Color.WHITE);
            return panel1;
        }
    
        public static void main(String args[]) {
            UIManager.put("swing.boldMetal", Boolean.FALSE);
            JFrame f = new JFrame("Print UI Example");
    
            JButton printButton = new JButton("Print This Window");
    
            JPanel toPrint = makePanel();
            System.out.println(toPrint.getPreferredSize());
            forceLayout(toPrint);
            System.out.println(toPrint.getPreferredSize());
    
            printButton.addActionListener(new PrintUIWindow(toPrint));
            JPanel panel = makePanel();
            f.add(panel, BorderLayout.CENTER);
            f.add(printButton, BorderLayout.SOUTH);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
    
            System.out.println(panel.getPreferredSize());
            System.out.println(panel.getSize());
        }
    }
    

    0 讨论(0)
提交回复
热议问题