How to paint an invisible JFrame elsewhere?

2019-03-02 15:25发布

问题:

I want to paint the contents of a JFrame onto another frame. Currently, I only get it to work if the JFrame is visible.
Is there a way to paint a hidden JFrame?

Additional info:
In my project I need to be able to rotate and scale windows. I do not want to write my own window-api, so I thought I might be able to just paint JFrames or similar container classes in a rotated way (which the Graphics2D-API supports perfectly well). It would be awesome to be able to use standard JFrames for that, but a custom frame extending a JFrame would also be OK..

public class JFTest extends JFrame {
    private JFrame frameToPaint = null;

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

    public JFTest () {
        // some basic initialization
        super ("Container");
        setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
        setExtendedState (JFrame.MAXIMIZED_BOTH);
        add (new JPanel () {
            @Override public void paintComponent (Graphics g) {
                super.paintComponent (g);
                // painting the child frame's contents onto this frame
                if (frameToPaint != null) frameToPaint.getRootPane().paintAll (g);
            }
        });
        setVisible (true);

        // initializing some test-frame that will get painted onto the container
        frameToPaint = new JFrame ("child");
        frameToPaint.setSize (200, 100);
        frameToPaint.add (new JLabel ("test"));
        frameToPaint.addComponentListener (new ComponentAdapter() {
            @Override public void componentResized (ComponentEvent e) { repaint (); }
            @Override public void componentHidden  (ComponentEvent e) { repaint (); }
        });

        // magic line. an invisible frame will not get painted! why??
        frameToPaint.setVisible (true);
    }
}

回答1:

Hint 1: JFrame's setDefaultLookAndFeelDecorated(false)/setUndecorated(true) might be of use for a window without caption and borders;

Hint 2: as setGlassPane/setLayeredPane/setOpaque(false) might be of use for a second "layer".



回答2:

I want to get the graphical contents of a frame without having to make the frame visible for the user

The Screen Image class should help. Although I think it will only work for the "content pane" of the frame and not the entire frame (with the title bar and borders) unless you use a decorated frame.



回答3:

1) you have to use proper LayoutManager, not setSize() or setBounds()

2) if is there null LayoutManager used then Container returns any size after setVisible(true);

3) if is there used proper LayoutManager, then Container return its Size after call pack();, in other hands this container couldn't be visible on the screen ( meaning setVisible(true); )

4) JComponents must to returns PrefferedSize for example