Question

I am writing a program that attempts to simulate the evolution of a species, and it has a window that looks like this: enter image description here

Originally the empty area in the bottom right was a Panel, and it is intended to draw a visual representation of the specimens, locations, and travel paths(doesn't really matter). However, you will be able to open some sort of window that allows you to create/edit different items(like species, locations, and travel paths). Originally I planned for those to simply be popup windows. But, I was thinking I would perhaps use JInternal panes for the popups, and the visual representation screen.

So in my JFrames constructor:

JDesktopPane pane = new JDesktopPane();
this.setContentPane(pane);
setLayout(new BorderLayout());//To layout the menubar, and the items on the left

panel = new GraphicsPanel(manager);
panel.setVisible(true);

And in Graphics Panel constructor:super("Graphic Project View",true,false,true,true);

This locks the Panel to BorderLayout.CENTER, and it fills up the entire space, not allowing for anything else. My guess this is because JDesktopPanes use an OverlayLayout, and when I set the layout to BorderLayout that overrides the OverlayLayout, and so my InternalFrame just gets added to the center.

So the question is: How do I layout the things like the JMenuBar, and the left ward Panel as they are now, whilst still maintaining the capability to have JInternalFrames?

For now I am going to add the JMenuBar via JFrame.setJMenuBar(JMenuBar) instead of JFrame.add(menuBar,BorderLayout.NORTH), and then change the panel on the left into a JInternal frame, but if possible I'd rather have it as is. I would like it if I could just have the DesktopPane be added to the JFrame at BorderLayout.CENTER, and then just add the frame to the Desktop pane. If the InternalFrame were limited to that region I wouldn't care, as long as it's still mobile, ect.

EDIT: How I add JInternalFrame(Sorry it still says panel, but it has been converted to a JInternalFrame):

panel = new GraphicsPanel(manager);
panel.setSize(desktop.getSize());
panel.setLocation(0,0);
panel.setVisible(true);
desktop.add(panel);
Was it helpful?

Solution

I would start with a single JPanel (lets all it the base pane), which will house the other containers.

Using a border layout, I would add a "controls" panel to the WEST position of the base pane. Onto the CENTER position I would add the JDesktopPane.

I would set the main windows layout to BorderLayout and add the base pane to it. This will allow you to use JFrame#setJMenuBar to manage the menu bar while maintaining the result of the layout.

This will allow you to contain to use the JInternalFrames on the desktop without effecting the rest of the layout...

Simple Example

This is an overly simplified example used to demonstrate the basic concept described above...

enter image description here

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class SimpleLayout {

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

    public SimpleLayout() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JMenuBar mb = new JMenuBar();
                mb.add(new JMenu("File"));
                mb.add(new JMenu("Add"));
                mb.add(new JMenu("Edit"));
                mb.add(new JMenu("Analize"));
                mb.add(new JMenu("About"));

                JFrame frame = new JFrame("Testing");
                frame.setJMenuBar(mb);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new BasePane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class BasePane extends JPanel {

        private JTextArea species;
        private JTextArea locations;
        private JTextArea travelPaths;

        private JDesktopPane desktopPane;

        public BasePane() {                
            setLayout(new BorderLayout());

            desktopPane = new JDesktopPane();

            species = new JTextArea("Species");
            locations = new JTextArea("Locations");
            travelPaths = new JTextArea("TravelPaths");

            JPanel controls = new JPanel(new GridLayout(3, 0));
            controls.add(new JScrollPane(species));
            controls.add(new JScrollPane(locations));
            controls.add(new JScrollPane(travelPaths));

            add(controls, BorderLayout.WEST);
            add(desktopPane);

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }            
    }        
}

Your requirements might be slightly difference, but the basic concept should get you moving.

Depending on the structure of your application, I might be tempted to separate the Controls pane into a separate class as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top