0

Althougt I tried as hard as I can I can't cope with my problem. The problem is this: I want to print a JComponent from my frame, to be exact a JPanel, but it is too big to fit standard A4 page either in portrait or landscape. To get this work I implemented code from here Fit/Scale JComponent to page being printed so my ComponentPrintable class looks like this:

public class ComponentPrintable extends JPanel implements Printable {

private Component comp;

public ComponentPrintable(Component comp)
{
    this.comp = comp;
}

@Override
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException
{
    if (pageIndex > 0) {
        return Printable.NO_SUCH_PAGE;
    }

    Dimension componentSize = comp.getPreferredSize();
    comp.setSize(componentSize);

    Dimension printSize = new Dimension();
    printSize.setSize(pageFormat.getImageableWidth(), pageFormat.getImageableHeight());

    double scaleFactor = getScaleFactorToFit(componentSize, printSize);

    if (scaleFactor > 1d) {
        scaleFactor = 1d;
    }

    double scaleWidth = componentSize.width * scaleFactor;
    double scaleHeight = componentSize.height * scaleFactor;

    Graphics2D g2 = (Graphics2D)graphics;

    double x = ((pageFormat.getImageableWidth() - scaleWidth)/2d) + pageFormat.getImageableX();
    double y = ((pageFormat.getImageableHeight() - scaleHeight)/2d) + pageFormat.getImageableY();

    AffineTransform at = new AffineTransform();

    at.translate(x, y);
    at.scale(scaleFactor, scaleFactor);
    g2.transform(at);
    comp.printAll(g2);
    g2.dispose();
    comp.revalidate();

    return PAGE_EXISTS;
}

private double getScaleFactorToFit(Dimension original, Dimension toFit) {

    double dScale = 1d;

    if (original != null && toFit != null) {

        double dScaleWidth = getScaleFactor(original.width, toFit.width);
        double dScaleHeight = getScaleFactor(original.height, toFit.height);

        dScale = Math.min(dScaleHeight, dScaleWidth);
    }

    return dScale;
}

private double getScaleFactor(int iMasterSize, int iTargetSize) {

    double dScale = 1;
    if (iMasterSize > iTargetSize) {

        dScale = (double) iTargetSize / (double) iMasterSize;
    }

    else {
        dScale = (double) iTargetSize / (double) iMasterSize;
    }

    return dScale;
}
}

Now I've created two GUI forms in IntelliJ GUI designer: MainWindow and TmpPanel (which has been also created in designer so it is formally a JFrame).

Those two looks like this (both XML files provided in link below) https://www.dropbox.com/sh/lmg8xcj2cghgqzn/AADHgX6Esm30iS7r6GeVA4_0a?dl=0

Binded classes:

public class TmpPanel extends JFrame
{

private JPanel panel1;
private JPanel checkBoxPanel;
private JCheckBox fee;
private JCheckBox administration;
private JCheckBox water;
private JCheckBox booking;
private JCheckBox electricity;
private JCheckBox toilet;
private JPanel printPanel;
private JPanel dataPanel;
private JPanel generalTablePanel;
private JPanel summaryPanel;
private JLabel fakturaNr;
private JLabel CopyOriginal;
private JPanel SalePanel;
private JPanel SposobZaplatyPanel;
private JPanel NabywcaPanel;
private JPanel SprzedawcaPanel;
private JPanel servicesTablePanel;
private JPanel summaryTablePanel;

private JPanel[] panels = {panel1, checkBoxPanel, printPanel, dataPanel, generalTablePanel, summaryTablePanel, summaryPanel,
        SalePanel, SposobZaplatyPanel, NabywcaPanel, SprzedawcaPanel, servicesTablePanel};

public TmpPanel()
{
    for(JPanel x: panels)
    {
        x.repaint();
        x.validate();
        System.out.println(x.isValid());
    }
    setContentPane(panel1);

    System.out.println(getContentPane().isValid());
    System.out.println(printPanel.isValid());
}

public Component getPrintablePanel()
{

    return printPanel;
}
}

and

public class MainWindow extends JFrame implements ActionListener
{
private JTabbedPane tabbedPane1;
private JPanel rootPanel;
private JButton printButton;
private JButton newClientButton;
private JButton removeClientButton;

public MainWindow()
{
    super("Fakturowanie");
    setContentPane(rootPanel);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setResizable(false);

    tabbedPane1.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);

    newClientButton.addActionListener(this);
    removeClientButton.addActionListener(this);
    printButton.addActionListener(this);
    pack();
    setVisible(true);
}

@Override
public void actionPerformed(ActionEvent e)
{
    Object button = e.getSource();

    TmpPanel tmp = new TmpPanel();

    if(button == newClientButton)
    {
        String name = JOptionPane.showInputDialog(this, "Nazwa sprzedawcy:\n", "Nowy sprzedawca",
                JOptionPane.PLAIN_MESSAGE);

        if((name != null) && (name.length() > 0))
        {
            tabbedPane1.addTab(name, tmp.getContentPane());
            pack();
        }
    }

    if(button == removeClientButton)
    {
        tabbedPane1.remove(tabbedPane1.getSelectedComponent());
    }

    if(button == printButton)
    {
        System.out.println(tabbedPane1.isValid());
        printComponent(tmp.getPrintablePanel());
    }
}

public void printComponent(Component comp)
{
    PrinterJob printerJob = PrinterJob.getPrinterJob();
    PageFormat pf = printerJob.pageDialog(printerJob.defaultPage());
    printerJob.setPrintable(new ComponentPrintable(comp), pf);

    if(printerJob.printDialog())
    {
        try
        {
            printerJob.print();
        }

        catch (PrinterException e1)
        {
            JOptionPane.showMessageDialog(this, "Błąd drukowania", "Błąd", JOptionPane.OK_OPTION);
        }
    }
}
}

Now my problem is as follows: I want to print printPanel from TmpPanel so that it fits the page. Previously in printButton listener I had

printComponent(tabbedPane1.getSelectedComponent());

and it worked perfectly. But when I type

printComponent(tmp.getPrintablePanel());

I only get a background color of printPanel (I made it black to make it visible on a blank page). I tried all the combinations with extend JPanel, extend JFrame, add, setContentPane, getContentPane etc but nothing works. I only managed to find out this little thing: When I type

System.out.println(tabbedPane1.getSelectedComponent().isValid());

it returns true. When I try to validate or repaint each component in TmpPanel the isValid method return false for each of them.

I guess that's why I can only see a black rectangle of printPanels background after pressing Print button.

Why is that even though both forms were created in designer and how get this to work?

Community
  • 1
  • 1
Colonder
  • 1,556
  • 3
  • 20
  • 40
  • So, after a bit of testing with some other code, it would seem that a lot of components won't actually render properly until they are realised (displayed on a window which is visible), so you have two choices. Either use the "life" component is displayed on the screen, which presents some small issues, or create an offscreen window onto which the component can be added before it's printed – MadProgrammer Mar 02 '16 at 23:08
  • I think I don't get the second option. Like creating new `JFrame` then adding `printPanel` to it and ten printing that panel from this new `JFrame`? – Colonder Mar 02 '16 at 23:14
  • Pretty much, but the frame needs to be made visible, so you want to position it off screen somewhere – MadProgrammer Mar 02 '16 at 23:16
  • A huge workaround it is. But it's better than nothing. I'm curious: if I typed all the `JPanel` manually and then add it to `MainWindow` that's visible would it work? – Colonder Mar 02 '16 at 23:21
  • Maybe there is a way to access it via `tabbedPane1.getSelectedComponent()` comehow? – Colonder Mar 02 '16 at 23:25
  • Yes, you could do that, but the `ComponentPrintable` will change the size of the component, which will affect the life component on the screen, which might not look all that good – MadProgrammer Mar 02 '16 at 23:29
  • Shouldn't `revalidate` deal with that? – Colonder Mar 02 '16 at 23:31
  • No, not always, much of the functionality is based around the need for the components to be realised on the screen (attached to a native peer), the code is optimised in such away that if it's not, that kind of functionality won't do anything – MadProgrammer Mar 02 '16 at 23:37

2 Answers2

1

So, part of the problem, as I see it, is some the components don't want to render until they are attached to a native peer (or realised window).

There are two choices, you could simply print the live component which is already on the screen. This is a problem, because the ComponentPrintable will change the size of the component, which will affect the live component, making it somewhat unpleasant to the user.

The second option is to create a new instance of the component and place it on another JFrame. The tricky part is getting the frame to realise it self and create a native peer.

Luckily, there are a couple of methods which we know can do this, pack been one of them.

The following example is taken from the Using Text Components example, as it's a realitvly complex component.

When you click print, it makes a new instance of this component, add's it to a JFrame, packs the frame and then prints the component.

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import static java.awt.print.Printable.PAGE_EXISTS;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.IOException;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;

public class Main {

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

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


                JButton print = new JButton("Print");
                print.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        TextSamplerDemo demo = new TextSamplerDemo();
                        JFrame test = new JFrame();
                        test.add(demo);
                        test.pack();
                        ComponentPrintable printable = new ComponentPrintable(demo);
                        PrinterJob printerJob = PrinterJob.getPrinterJob();
                        PageFormat pf = printerJob.pageDialog(printerJob.defaultPage());
                        printerJob.setPrintable(printable, pf);

                        if (printerJob.printDialog()) {
                            try {
                                printerJob.print();
                            } catch (PrinterException e1) {
                                JOptionPane.showMessageDialog(null, "Printing failed", "Print", JOptionPane.OK_OPTION);
                            }
                        }
                    }
                });

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                TextSamplerDemo demo = new TextSamplerDemo();
                frame.add(demo);
                frame.add(print, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class ComponentPrintable extends JPanel implements Printable {

        private Component comp;

        public ComponentPrintable(Component comp) {
            this.comp = comp;
        }

        @Override
        public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
            if (pageIndex > 0) {
                return Printable.NO_SUCH_PAGE;
            }

            Dimension componentSize = comp.getPreferredSize();
            comp.setSize(componentSize);

            Dimension printSize = new Dimension();
            printSize.setSize(pageFormat.getImageableWidth(), pageFormat.getImageableHeight());

            double scaleFactor = getScaleFactorToFit(componentSize, printSize);

            if (scaleFactor > 1d) {
                scaleFactor = 1d;
            }

            double scaleWidth = componentSize.width * scaleFactor;
            double scaleHeight = componentSize.height * scaleFactor;

            Graphics2D g2 = (Graphics2D) graphics;

            double x = ((pageFormat.getImageableWidth() - scaleWidth) / 2d) + pageFormat.getImageableX();
            double y = ((pageFormat.getImageableHeight() - scaleHeight) / 2d) + pageFormat.getImageableY();

            AffineTransform at = new AffineTransform();

            at.translate(x, y);
            at.scale(scaleFactor, scaleFactor);
            g2.transform(at);
            comp.printAll(g2);
            g2.dispose();
            comp.revalidate();

            return PAGE_EXISTS;
        }

        private double getScaleFactorToFit(Dimension original, Dimension toFit) {

            double dScale = 1d;

            if (original != null && toFit != null) {

                double dScaleWidth = getScaleFactor(original.width, toFit.width);
                double dScaleHeight = getScaleFactor(original.height, toFit.height);

                dScale = Math.min(dScaleHeight, dScaleWidth);
            }

            return dScale;
        }

        private double getScaleFactor(int iMasterSize, int iTargetSize) {

            double dScale = 1;
            if (iMasterSize > iTargetSize) {

                dScale = (double) iTargetSize / (double) iMasterSize;
            } else {
                dScale = (double) iTargetSize / (double) iMasterSize;
            }

            return dScale;
        }
    }

    public class TextSamplerDemo extends JPanel
            implements ActionListener {

        private String newline = "\n";
        protected static final String textFieldString = "JTextField";
        protected static final String passwordFieldString = "JPasswordField";
        protected static final String ftfString = "JFormattedTextField";
        protected static final String buttonString = "JButton";

        protected JLabel actionLabel;

        public TextSamplerDemo() {
            setLayout(new BorderLayout());

            //Create a regular text field.
            JTextField textField = new JTextField(10);
            textField.setActionCommand(textFieldString);
            textField.addActionListener(this);

            //Create a password field.
            JPasswordField passwordField = new JPasswordField(10);
            passwordField.setActionCommand(passwordFieldString);
            passwordField.addActionListener(this);

            //Create a formatted text field.
            JFormattedTextField ftf = new JFormattedTextField(
                    java.util.Calendar.getInstance().getTime());
            ftf.setActionCommand(textFieldString);
            ftf.addActionListener(this);

            //Create some labels for the fields.
            JLabel textFieldLabel = new JLabel(textFieldString + ": ");
            textFieldLabel.setLabelFor(textField);
            JLabel passwordFieldLabel = new JLabel(passwordFieldString + ": ");
            passwordFieldLabel.setLabelFor(passwordField);
            JLabel ftfLabel = new JLabel(ftfString + ": ");
            ftfLabel.setLabelFor(ftf);

            //Create a label to put messages during an action event.
            actionLabel = new JLabel("Type text in a field and press Enter.");
            actionLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));

            //Lay out the text controls and the labels.
            JPanel textControlsPane = new JPanel();
            GridBagLayout gridbag = new GridBagLayout();
            GridBagConstraints c = new GridBagConstraints();

            textControlsPane.setLayout(gridbag);

            JLabel[] labels = {textFieldLabel, passwordFieldLabel, ftfLabel};
            JTextField[] textFields = {textField, passwordField, ftf};
            addLabelTextRows(labels, textFields, gridbag, textControlsPane);

            c.gridwidth = GridBagConstraints.REMAINDER; //last
            c.anchor = GridBagConstraints.WEST;
            c.weightx = 1.0;
            textControlsPane.add(actionLabel, c);
            textControlsPane.setBorder(
                    BorderFactory.createCompoundBorder(
                            BorderFactory.createTitledBorder("Text Fields"),
                            BorderFactory.createEmptyBorder(5, 5, 5, 5)));

            //Create a text area.
            JTextArea textArea = new JTextArea(
                    "This is an editable JTextArea. "
                    + "A text area is a \"plain\" text component, "
                    + "which means that although it can display text "
                    + "in any font, all of the text is in the same font."
            );
            textArea.setFont(new Font("Serif", Font.ITALIC, 16));
            textArea.setLineWrap(true);
            textArea.setWrapStyleWord(true);
            JScrollPane areaScrollPane = new JScrollPane(textArea);
            areaScrollPane.setVerticalScrollBarPolicy(
                    JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
            areaScrollPane.setPreferredSize(new Dimension(250, 250));
            areaScrollPane.setBorder(
                    BorderFactory.createCompoundBorder(
                            BorderFactory.createCompoundBorder(
                                    BorderFactory.createTitledBorder("Plain Text"),
                                    BorderFactory.createEmptyBorder(5, 5, 5, 5)),
                            areaScrollPane.getBorder()));

            //Create an editor pane.
            JEditorPane editorPane = createEditorPane();
            JScrollPane editorScrollPane = new JScrollPane(editorPane);
            editorScrollPane.setVerticalScrollBarPolicy(
                    JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
            editorScrollPane.setPreferredSize(new Dimension(250, 145));
            editorScrollPane.setMinimumSize(new Dimension(10, 10));

            //Create a text pane.
            JTextPane textPane = createTextPane();
            JScrollPane paneScrollPane = new JScrollPane(textPane);
            paneScrollPane.setVerticalScrollBarPolicy(
                    JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
            paneScrollPane.setPreferredSize(new Dimension(250, 155));
            paneScrollPane.setMinimumSize(new Dimension(10, 10));

            //Put the editor pane and the text pane in a split pane.
            JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
                    editorScrollPane,
                    paneScrollPane);
            splitPane.setOneTouchExpandable(true);
            splitPane.setResizeWeight(0.5);
            JPanel rightPane = new JPanel(new GridLayout(1, 0));
            rightPane.add(splitPane);
            rightPane.setBorder(BorderFactory.createCompoundBorder(
                    BorderFactory.createTitledBorder("Styled Text"),
                    BorderFactory.createEmptyBorder(5, 5, 5, 5)));

            //Put everything together.
            JPanel leftPane = new JPanel(new BorderLayout());
            leftPane.add(textControlsPane,
                    BorderLayout.PAGE_START);
            leftPane.add(areaScrollPane,
                    BorderLayout.CENTER);

            add(leftPane, BorderLayout.LINE_START);
            add(rightPane, BorderLayout.LINE_END);
        }

        private void addLabelTextRows(JLabel[] labels,
                JTextField[] textFields,
                GridBagLayout gridbag,
                Container container) {
            GridBagConstraints c = new GridBagConstraints();
            c.anchor = GridBagConstraints.EAST;
            int numLabels = labels.length;

            for (int i = 0; i < numLabels; i++) {
                c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last
                c.fill = GridBagConstraints.NONE;      //reset to default
                c.weightx = 0.0;                       //reset to default
                container.add(labels[i], c);

                c.gridwidth = GridBagConstraints.REMAINDER;     //end row
                c.fill = GridBagConstraints.HORIZONTAL;
                c.weightx = 1.0;
                container.add(textFields[i], c);
            }
        }

        public void actionPerformed(ActionEvent e) {
            String prefix = "You typed \"";
            if (textFieldString.equals(e.getActionCommand())) {
                JTextField source = (JTextField) e.getSource();
                actionLabel.setText(prefix + source.getText() + "\"");
            } else if (passwordFieldString.equals(e.getActionCommand())) {
                JPasswordField source = (JPasswordField) e.getSource();
                actionLabel.setText(prefix + new String(source.getPassword())
                        + "\"");
            } else if (buttonString.equals(e.getActionCommand())) {
                Toolkit.getDefaultToolkit().beep();
            }
        }

        private JEditorPane createEditorPane() {
            JEditorPane editorPane = new JEditorPane();
            editorPane.setEditable(false);
            java.net.URL helpURL = TextSamplerDemo.class.getResource(
                    "TextSamplerDemoHelp.html");
            if (helpURL != null) {
                try {
                    editorPane.setPage(helpURL);
                } catch (IOException e) {
                    System.err.println("Attempted to read a bad URL: " + helpURL);
                }
            } else {
                System.err.println("Couldn't find file: TextSampleDemoHelp.html");
            }

            return editorPane;
        }

        private JTextPane createTextPane() {
            String[] initString
                    = {"This is an editable JTextPane, ", //regular
                        "another ", //italic
                        "styled ", //bold
                        "text ", //small
                        "component, ", //large
                        "which supports embedded components..." + newline,//regular
                        " " + newline, //button
                        "...and embedded icons..." + newline, //regular
                        " ", //icon
                        newline + "JTextPane is a subclass of JEditorPane that "
                        + "uses a StyledEditorKit and StyledDocument, and provides "
                        + "cover methods for interacting with those objects."
                    };

            String[] initStyles
                    = {"regular", "italic", "bold", "small", "large",
                        "regular", "button", "regular", "icon",
                        "regular"
                    };

            JTextPane textPane = new JTextPane();
            StyledDocument doc = textPane.getStyledDocument();
            addStylesToDocument(doc);

            try {
                for (int i = 0; i < initString.length; i++) {
                    doc.insertString(doc.getLength(), initString[i],
                            doc.getStyle(initStyles[i]));
                }
            } catch (BadLocationException ble) {
                System.err.println("Couldn't insert initial text into text pane.");
            }

            return textPane;
        }

        protected void addStylesToDocument(StyledDocument doc) {
            //Initialize some styles.
            Style def = StyleContext.getDefaultStyleContext().
                    getStyle(StyleContext.DEFAULT_STYLE);

            Style regular = doc.addStyle("regular", def);
            StyleConstants.setFontFamily(def, "SansSerif");

            Style s = doc.addStyle("italic", regular);
            StyleConstants.setItalic(s, true);

            s = doc.addStyle("bold", regular);
            StyleConstants.setBold(s, true);

            s = doc.addStyle("small", regular);
            StyleConstants.setFontSize(s, 10);

            s = doc.addStyle("large", regular);
            StyleConstants.setFontSize(s, 16);

            s = doc.addStyle("icon", regular);
            StyleConstants.setAlignment(s, StyleConstants.ALIGN_CENTER);
            ImageIcon pigIcon = createImageIcon("images/Pig.gif",
                    "a cute pig");
            if (pigIcon != null) {
                StyleConstants.setIcon(s, pigIcon);
            }

            s = doc.addStyle("button", regular);
            StyleConstants.setAlignment(s, StyleConstants.ALIGN_CENTER);
            ImageIcon soundIcon = createImageIcon("images/sound.gif",
                    "sound icon");
            JButton button = new JButton();
            if (soundIcon != null) {
                button.setIcon(soundIcon);
            } else {
                button.setText("BEEP");
            }
            button.setCursor(Cursor.getDefaultCursor());
            button.setMargin(new Insets(0, 0, 0, 0));
            button.setActionCommand(buttonString);
            button.addActionListener(this);
            StyleConstants.setComponent(s, button);
        }

        protected ImageIcon createImageIcon(String path,
                String description) {
            java.net.URL imgURL = TextSamplerDemo.class.getResource(path);
            if (imgURL != null) {
                return new ImageIcon(imgURL, description);
            } else {
                System.err.println("Couldn't find file: " + path);
                return null;
            }
        }
    }
}

For this to work realistically, you would need to make a copy of all the data which the panel contained originally, otherwise it's kind of pointless

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • You are a truly mad programmer, you wrote all of that code in less than 20 minutes, that's insane! Ho do you do that? Anyway thanks a lot for advice, gonna tinker a little bit more in it before completely redesigning program. – Colonder Mar 02 '16 at 23:43
  • A copy and pasted most of it ;). It would worth building your UI by hand and testing it, just to make sure that the form editor isn't doing something weird – MadProgrammer Mar 02 '16 at 23:45
  • Hmm I guess you're right with diagnosis, because I just wrote in constructor `super("Test"); setContentPane(panel1); pack();` and `isValid` returned true for all components – Colonder Mar 02 '16 at 23:50
0

I managed to solve it somehow by modyfying TmpPanel constructor with

public TmpPanel()
{
    setContentPane(panel1);
    pack();
    dispose();
}

now isValid returned true for all components. Each time printButton is pressed a new invisible JFrame with the printPanel is created but I dispose it immidiately so no desktop space neither extra memory is used. I can now print easily with

printComponent(tmp.getPrintablePanel());
Colonder
  • 1,556
  • 3
  • 20
  • 40