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?