Java 使用setVisible打印JFrame(错误)

Java 使用setVisible打印JFrame(错误),java,swing,printing,jframe,Java,Swing,Printing,Jframe,我用2个JFrame窗口创建了一个Swing应用程序,我想将第一个框架作为主页面。我将第一帧中的打印按钮设置为打印第二帧 如何使用frame.setVisible(false)打印第二帧?我怎样才能解决它 我把代码放在下面: package printuiwindow; /** * * @author Saravanan Ponnusamy */ import java.awt.*; import java.awt.event.*;

我用2个
JFrame
窗口创建了一个Swing应用程序,我想将第一个框架作为主页面。我将第一帧中的打印按钮设置为打印第二帧

如何使用
frame.setVisible(false)打印第二帧?我怎样才能解决它

我把代码放在下面:

package printuiwindow;

    /**
     *
     * @author Saravanan Ponnusamy
     */
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.awt.print.*;

     class PrintUIWindow implements Printable, ActionListener {


    JFrame frameToPrint;

    public int print(Graphics g, PageFormat pf, int page) throws
                                                        PrinterException {

        if (page > 0) {
            return NO_SUCH_PAGE;
        }

        Graphics2D g2d = (Graphics2D)g;
        g2d.translate(pf.getImageableX(), pf.getImageableY()-55);

        frameToPrint.print(g);

        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(JFrame f) {
        frameToPrint = f;
    }

    public static void main(String args[]) {
        UIManager.put("swing.boldMetal", Boolean.FALSE);
        JFrame f = new JFrame("Print UI Example");
        f.addWindowListener(new WindowAdapter() {
           public void windowClosing(WindowEvent e) {System.exit(0);}
        });
 //Printing frame design start


        JFrame frame = new JFrame("Print UI Example");
         JLabel label11=new JLabel("Selling Bill",JLabel.CENTER);
        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);
        frame.setSize(300,300);
        frame.setLocationRelativeTo(null);
        frame.add(panel1,BorderLayout.CENTER);  
        panel1.setBackground(Color.WHITE);
        frame.setResizable(false);
        frame.setVisible(true);
    //printing frame design end    

//first frame design start
        JLabel label1=new JLabel("Selling Bill",JLabel.CENTER);
        JLabel label2=new JLabel("Customer Name :",JLabel.LEFT);
        JLabel label3=new JLabel("Buying Date :",JLabel.LEFT);
        JLabel label4=new JLabel("Book Buyed :",JLabel.LEFT);
        JLabel label5=new JLabel("Number :",JLabel.LEFT);
        JLabel label6=new JLabel("Total Price :",JLabel.LEFT);

        label1.setFont(new Font("Courier New", Font.BOLD, 13));
        label2.setFont(new Font("Courier New", Font.BOLD, 13));
        label3.setFont(new Font("Courier New", Font.BOLD, 13));
        label4.setFont(new Font("Courier New", Font.BOLD, 13));
        label5.setFont(new Font("Courier New", Font.BOLD, 13));
        label6.setFont(new Font("Courier New", Font.BOLD, 13));

        JButton printButton = new JButton("Print This Window");

        //print button code
        printButton.addActionListener(new PrintUIWindow(frame));
        JPanel panel=new JPanel();

        panel.setLayout(new GridLayout(6,1));
        panel.add(label1);
        panel.add(label2);
        panel.add(label3);
        panel.add(label4);
        panel.add(label5);
        panel.add(label6);
        f.setSize(300,300);
        f.setLocationRelativeTo(null);
        f.add(panel,BorderLayout.CENTER);
        f.add(printButton,BorderLayout.SOUTH);
        panel.setBackground(Color.WHITE);
        f.setResizable(false);
        f.setVisible(true);
    }
}

我是多么讨厌打印组件,说真的,要么学会手工打印,要么使用类似Jasper Reports的东西

你有一系列的问题

  • 组件只能有一个父窗口,因此当您创建第二个窗口并向其中添加组件时,您将从第一个窗口中删除它们
  • 不能绘制不可见的组件
  • 无论如何,你真的不应该打印框架,最好是打印面板
  • 除非在屏幕上实现,否则您将负责确保组件在打印前正确布局
  • 你真的不想打印框架,你实际上想打印面板,它只是简单得多,你没有得到框架。如果还要打印边框,则需要使边框可见

    那么基于

    因此,基本上,这添加了一个简单的工厂方法来创建基础面板。这将创建此面板的两个实例,一个用于打印,另一个用于显示(从技术上讲,您可以使用一个,但您可以理解)

    打印过程将在打印时更新面板的布局,以确保其内容正确放置,以便实际渲染

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

    看到了吗,根据你现有的代码,你有两个框架,都是可见的……这是故意的吗?你的代码没有透露你在问题中描述的内容。但是,如果要通过单击按钮来显示帧,请在按钮处理程序中使用2ndframe.setvisibile(true)。1-组件只能有一个父窗口,因此当您创建第二个窗口并向其中添加组件时,您将从第一个窗口中删除它们;2-不能绘制不可见的组件;3-无论如何,你真的不应该打印框架,最好是打印面板;4-除非在屏幕上实现,否则您将负责确保组件在作为一般建议打印之前正确布局,而不是以这种方式打印,打印是一项复杂的工作,与在屏幕上处理图形完全不同。谢谢朋友们,我现在明白了,我们不能绘制一个看不见的组件。因此,我必须打印Jpanel,并将该面板添加到第一个面板中。非常感谢各位,如果它有助于解决问题,请放心。