Search code examples
javaswingjpaneljdesktoppane

Displaying JDesktopPane in a JPanel


I am having some difficulty getting a JDesktopPane (that contains a JInternalFrame) to add to a JPanel. What is the proper way to do this? What am I doing wrong?

Here is my bare bones example:

import javax.swing.*;
import java.awt.*;

public class MainPanel extends JPanel {

    JDesktopPane jDesktopPane = new JDesktopPane();
    JInternalFrame jInternalFrame = new JInternalFrame();

    public MainPanel() {

        jDesktopPane.add(jInternalFrame);
        add(jDesktopPane);
        setSize(400,400);
        setVisible(true);
    }

    private static void createAndShowGui() {

        JFrame frame = new JFrame("This isn't working...");
        MainPanel mainPanel = new MainPanel();
        frame.setLayout(new BorderLayout());

        frame.add(mainPanel, BorderLayout.CENTER);
        frame.setContentPane(mainPanel);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setLocationByPlatform(false);
        frame.setSize(500, 500);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

Solution

    • JDesktop doesn't use a layout manager, so it's default/preferred size is 0x0
    • JPanel uses FlowLayout by default, which honours the preferredSize of it's child components when it lays them out

    So, in your constructor, you could try changing the default layout manager to BorderLayout instead...

    public MainPanel() {
        setLayout(new BorderLayout());
        jDesktopPane.add(jInternalFrame);
        add(jDesktopPane); 
        // pointless
        //setSize(400,400);
        // pointless
        //setVisible(true);
    }
    

    Now, you because nothing is actually defining a preferred size for anything, you should provide your own...

    public Dimension getPreferredSize() {
        return new Dimension(400, 400);
    }
    

    Then when you create the UI you can simply pack the frame...

    private static void createAndShowGui() {
    
        JFrame frame = new JFrame("This should be working now...");
        MainPanel mainPanel = new MainPanel();
        frame.setLayout(new BorderLayout());
    
        // pointless considering the setContentPane call
        //frame.add(mainPanel, BorderLayout.CENTER);
        frame.setContentPane(mainPanel);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.pack();
        frame.setLocationByPlatform(false);
        //frame.setSize(500, 500);
        frame.setVisible(true);
    }
    

    Now because JDesktopPane doesn't use any layout manager, you become responsible for ensuring that anything your add to it is positioned and size

    jInternalFrame.setBounds(10, 10, 200, 200);
    // Just like any frame, it's not visible when it's first created
    jInternalFrame.setVisible(true);