JDesktopPane not displaying components when adding JInternalFrame

155 views Asked by At

I am developing a code editor with a code completion tool. My goal is to have a small internal frame appear once it gets activated. But now I have a problem where the layer methods of the JDesktopPane don't seem to work.

Code might not make much sense because I chopped it down to a minimal reproducible example.

Main.java

package questions;

import javax.swing.*;

public class Main {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException |
                    IllegalAccessException | UnsupportedLookAndFeelException e) {
                e.printStackTrace();
            }
            JavaEditor editor = new JavaEditor(true); // "true" means it will be windowed.
            editor.display();
        });
    }
}

JavaEditor.java

package questions;

public final class JavaEditor extends CodeEditor {

    private CodeCompletion codeCompletion;

    public JavaEditor(boolean windowed) {
        super(windowed);
        this.codeCompletion = new CodeCompletion(this);
        codeCompletion.enable();

        // Loop for debugging, prints the classes found added to the JDesktopPane.
        for (int i = 0; i < this.getRootPane().getComponents().length; i++) {
            System.out.println(getRootPane().getComponent(i).getClass());
        }
    }

}

CodeEditor.java

package questions;

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

public abstract class CodeEditor {

    protected final String title = "Java Editor";

    private JFrame frame;

    private JDesktopPane rootPane;

    private JSplitPane mainSplitPane;

    private JPanel sidePanel;

    private JScrollPane editorScrollPane;

    private JScrollPane sideScrollPane;

    protected JEditorPane editorPane;

    private JToolBar toolBar;

    private LayoutManager layoutManager = new BorderLayout();

    private boolean windowed;

    protected CodeEditor(boolean windowed) {
        this.windowed = windowed;
        createComponents();
        applyComponentHierarchy();
    }

    protected void createComponents() {
        if (windowed) frame = new JFrame(title);
        rootPane = new JDesktopPane();
        sidePanel = new JPanel();
        editorPane = new JEditorPane();
        editorScrollPane = new JScrollPane();
        sideScrollPane = new JScrollPane();
        mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, sideScrollPane, editorScrollPane);
        toolBar = new JToolBar();
    }

    protected void applyComponentHierarchy() {
        if (windowed) {
            frame.setContentPane(rootPane);
        }
        editorScrollPane.setViewportView(editorPane);
        sideScrollPane.setViewportView(sidePanel);
        rootPane.setLayout(layoutManager);
        rootPane.setLayer(toolBar, 0);
        rootPane.setLayer(mainSplitPane, 0);
        rootPane.add(toolBar, BorderLayout.NORTH);
        rootPane.add(mainSplitPane, BorderLayout.CENTER);
    }

    public JDesktopPane getRootPane() {
        return rootPane;
    }

    public void display() {
        if (!windowed) throw new IllegalStateException("Editor must be in windowed mode to be displayed.");
        frame.setPreferredSize(new Dimension(1000, 600));
        frame.pack();
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.requestFocus();
        frame.setVisible(true);
    }

}

CodeCompletion.java

package questions;

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

public class CodeCompletion {

    private JInternalFrame completionFrame;

    private JScrollPane mainPanel;

    private JList<String> completionList;

    private DefaultListModel<String> listModel = new DefaultListModel<>();

    private CodeEditor editor;

    public CodeCompletion(CodeEditor editor) {
        this.editor = editor;

        // Parameters are: title, resizeable, closable, maximizable, iconifiable
        this.completionFrame = new JInternalFrame("Title", false, false, false, false);
        this.mainPanel = new JScrollPane();
        this.completionList = new JList<>();

        mainPanel.setViewportView(completionList);
        completionFrame.setContentPane(mainPanel);
    }

    public void enable() {
        completionList.setModel(listModel);
        editor.getRootPane().setLayer(completionFrame, 1);
        editor.getRootPane().add(completionFrame);
        editor.getRootPane().revalidate();
        completionFrame.setSize(new Dimension(100, 100));
        completionFrame.pack();
    }

    public void disable() {
        completionFrame.dispose();
    }

}

The debugging loop in JavaEditor says that all of the components are indeed added to the JDesktopPane, and when I comment the line editor.getRootPane().add(completionFrame);, it displays the other two components correctly. What is happening?

0

There are 0 answers