javaswingjdesktoppane

JDesktopPane not displaying any component


I'm experimenting with desktop panes so I can use them in my work projects. The problem here is that I want to use an JInternalFrame within a JDesktopPane, in a normal JPanel it shows normally but cannot move it, using the desktop pane doesn't display any component added.

Here is the code of the last try, is simple just for learning how it works:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Internal_FrameShowtst extends JFrame{

    Internal_FrameShowtst(){
        BorderLayout bl = new BorderLayout();
        JDesktopPane p = new JDesktopPane();
        JPanel p1 = new JPanel();
        JButton b = new JButton("click");
        JInternalFrame in = new JInternalFrame("Test");
        Internal_Frametst ift = new Internal_Frametst();
        b.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                //p1.add(new JLabel("hola"));
                //in.add(p1);
                //in.setVisible(true);
                ift.setVisible(true);
            }
        });
        p1.add(b);
        bl.addLayoutComponent(p,BorderLayout.CENTER);
        //p.add(in);
        p.add(ift);
        p.repaint();
        setLayout(bl);
        add(p);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Internal_FrameShowtst().setVisible(true);
            }
        });
    }
}

custom internal frame class:

import javax.swing.*;

public class Internal_Frametst extends JInternalFrame {

    Internal_Frametst(){
        JPanel p = new JPanel();
        JLabel label = new JLabel("Halo");
        setIconifiable(true);
        //setIcon(true);
        setClosable(true);
        p.add(label);
        p.setSize(300,300);
        add(p);
        //setVisible(true);
    }
}

I've read and tried the following: Components inside JDesktopPane not showing JDesktopPane not displaying components when adding JInternalFrame

I've tried adding the components directly, adding a JPanel, adding the internal frame, trying without it, creating the internal frame in the main class, creating my own internal frame in its own class, using layout managers with both panels (normal and desktop), all with the same result.


Solution

  • Your code creates several components that are never added to the visible UI at all. In the version you have posted, the internal frame is invisible and the button to make it visible is not part of the frame. But there are also problems with the initial sizes of the components.

    I strongly recommend to keep the creation of a component, the setting of its initial properties, and the code to add it to a parent component close together in your source code.

    Further, consider the points discussed in Prefer composition over inheritance? Your subclasses are entirely unnecessary.

    Here is a revised version of your code that will open the internal frame when the button is clicked:

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    
    import javax.swing.*;
    
    public class UiExample {
        public static void main(String[] args) {
            EventQueue.invokeLater(UiExample::initializeUI);
        }
    
        static void initializeUI() {
            JPanel p1 = new JPanel();
            JButton b = new JButton("Show Internal Frame");
            p1.add(b);
    
            JInternalFrame ift = initializeInternalFrame();
            b.addActionListener(e -> {
                ift.pack();
                ift.setVisible(true);
            });
            JDesktopPane p = new JDesktopPane();
            p.add(ift);
    
            JFrame mainFrame = new JFrame();
            mainFrame.setSize(300, 200);
            mainFrame.getContentPane().add(p, BorderLayout.CENTER);
            mainFrame.getContentPane().add(p1, BorderLayout.PAGE_START);
            mainFrame.setVisible(true);
        }
    
        static JInternalFrame initializeInternalFrame() {
            JInternalFrame iFrame = new JInternalFrame();
            iFrame.setIconifiable(true);
            // setIcon(true);
            iFrame.setClosable(true);
            iFrame.setDefaultCloseOperation(JInternalFrame.HIDE_ON_CLOSE);
            JPanel p = new JPanel();
            p.add(new JLabel("Hello"));
            iFrame.add(p);
            return iFrame;
        }
    }
    

    Note that setDefaultCloseOperation(JInternalFrame.HIDE_ON_CLOSE) is necessary for being able to show the frame again via setVisible(true) after the internal frame has been closed.