Java tutorial
// This is example is from Kjell Dirdal. // Referenced from http://www.javaworld.com/javaworld/jw-05-2001/jw-0525-mdi.html import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.awt.Insets; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.beans.PropertyVetoException; import javax.swing.DefaultDesktopManager; import javax.swing.JCheckBoxMenuItem; import javax.swing.JComponent; import javax.swing.JDesktopPane; import javax.swing.JFrame; import javax.swing.JInternalFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JViewport; import javax.swing.event.MenuEvent; import javax.swing.event.MenuListener; public class KjellDirdalNotepad extends JFrame { private MDIDesktopPane desktop = new MDIDesktopPane(); private JMenuBar menuBar = new JMenuBar(); private JMenu fileMenu = new JMenu("File"); private JMenuItem newMenu = new JMenuItem("New"); private JScrollPane scrollPane = new JScrollPane(); public KjellDirdalNotepad() { menuBar.add(fileMenu); menuBar.add(new WindowMenu(desktop)); fileMenu.add(newMenu); setJMenuBar(menuBar); setTitle("MDI Test"); scrollPane.getViewport().add(desktop); getContentPane().setLayout(new BorderLayout()); getContentPane().add(scrollPane, BorderLayout.CENTER); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); newMenu.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { desktop.add(new TextFrame()); } }); } public static void main(String[] args) { KjellDirdalNotepad notepad = new KjellDirdalNotepad(); notepad.setSize(600, 400); notepad.setVisible(true); } } class TextFrame extends JInternalFrame { private JTextArea textArea = new JTextArea(); private JScrollPane scrollPane = new JScrollPane(); public TextFrame() { setSize(200, 300); setTitle("Edit Text"); setMaximizable(true); setIconifiable(true); setClosable(true); setResizable(true); scrollPane.getViewport().add(textArea); getContentPane().setLayout(new BorderLayout()); getContentPane().add(scrollPane, BorderLayout.CENTER); } } /** * An extension of WDesktopPane that supports often used MDI functionality. This * class also handles setting scroll bars for when windows move too far to the * left or bottom, providing the MDIDesktopPane is in a ScrollPane. */ class MDIDesktopPane extends JDesktopPane { private static int FRAME_OFFSET = 20; private MDIDesktopManager manager; public MDIDesktopPane() { manager = new MDIDesktopManager(this); setDesktopManager(manager); setDragMode(JDesktopPane.OUTLINE_DRAG_MODE); } public void setBounds(int x, int y, int w, int h) { super.setBounds(x, y, w, h); checkDesktopSize(); } public Component add(JInternalFrame frame) { JInternalFrame[] array = getAllFrames(); Point p; int w; int h; Component retval = super.add(frame); checkDesktopSize(); if (array.length > 0) { p = array[0].getLocation(); p.x = p.x + FRAME_OFFSET; p.y = p.y + FRAME_OFFSET; } else { p = new Point(0, 0); } frame.setLocation(p.x, p.y); if (frame.isResizable()) { w = getWidth() - (getWidth() / 3); h = getHeight() - (getHeight() / 3); if (w < frame.getMinimumSize().getWidth()) w = (int) frame.getMinimumSize().getWidth(); if (h < frame.getMinimumSize().getHeight()) h = (int) frame.getMinimumSize().getHeight(); frame.setSize(w, h); } moveToFront(frame); frame.setVisible(true); try { frame.setSelected(true); } catch (PropertyVetoException e) { frame.toBack(); } return retval; } public void remove(Component c) { super.remove(c); checkDesktopSize(); } /** * Cascade all internal frames */ public void cascadeFrames() { int x = 0; int y = 0; JInternalFrame allFrames[] = getAllFrames(); manager.setNormalSize(); int frameHeight = (getBounds().height - 5) - allFrames.length * FRAME_OFFSET; int frameWidth = (getBounds().width - 5) - allFrames.length * FRAME_OFFSET; for (int i = allFrames.length - 1; i >= 0; i--) { allFrames[i].setSize(frameWidth, frameHeight); allFrames[i].setLocation(x, y); x = x + FRAME_OFFSET; y = y + FRAME_OFFSET; } } /** * Tile all internal frames */ public void tileFrames() { java.awt.Component allFrames[] = getAllFrames(); manager.setNormalSize(); int frameHeight = getBounds().height / allFrames.length; int y = 0; for (int i = 0; i < allFrames.length; i++) { allFrames[i].setSize(getBounds().width, frameHeight); allFrames[i].setLocation(0, y); y = y + frameHeight; } } /** * Sets all component size properties ( maximum, minimum, preferred) to the * given dimension. */ public void setAllSize(Dimension d) { setMinimumSize(d); setMaximumSize(d); setPreferredSize(d); } /** * Sets all component size properties ( maximum, minimum, preferred) to the * given width and height. */ public void setAllSize(int width, int height) { setAllSize(new Dimension(width, height)); } private void checkDesktopSize() { if (getParent() != null && isVisible()) manager.resizeDesktop(); } } /** * Private class used to replace the standard DesktopManager for JDesktopPane. * Used to provide scrollbar functionality. */ class MDIDesktopManager extends DefaultDesktopManager { private MDIDesktopPane desktop; public MDIDesktopManager(MDIDesktopPane desktop) { this.desktop = desktop; } public void endResizingFrame(JComponent f) { super.endResizingFrame(f); resizeDesktop(); } public void endDraggingFrame(JComponent f) { super.endDraggingFrame(f); resizeDesktop(); } public void setNormalSize() { JScrollPane scrollPane = getScrollPane(); int x = 0; int y = 0; Insets scrollInsets = getScrollPaneInsets(); if (scrollPane != null) { Dimension d = scrollPane.getVisibleRect().getSize(); if (scrollPane.getBorder() != null) { d.setSize(d.getWidth() - scrollInsets.left - scrollInsets.right, d.getHeight() - scrollInsets.top - scrollInsets.bottom); } d.setSize(d.getWidth() - 20, d.getHeight() - 20); desktop.setAllSize(x, y); scrollPane.invalidate(); scrollPane.validate(); } } private Insets getScrollPaneInsets() { JScrollPane scrollPane = getScrollPane(); if (scrollPane == null) return new Insets(0, 0, 0, 0); else return getScrollPane().getBorder().getBorderInsets(scrollPane); } private JScrollPane getScrollPane() { if (desktop.getParent() instanceof JViewport) { JViewport viewPort = (JViewport) desktop.getParent(); if (viewPort.getParent() instanceof JScrollPane) return (JScrollPane) viewPort.getParent(); } return null; } protected void resizeDesktop() { int x = 0; int y = 0; JScrollPane scrollPane = getScrollPane(); Insets scrollInsets = getScrollPaneInsets(); if (scrollPane != null) { JInternalFrame allFrames[] = desktop.getAllFrames(); for (int i = 0; i < allFrames.length; i++) { if (allFrames[i].getX() + allFrames[i].getWidth() > x) { x = allFrames[i].getX() + allFrames[i].getWidth(); } if (allFrames[i].getY() + allFrames[i].getHeight() > y) { y = allFrames[i].getY() + allFrames[i].getHeight(); } } Dimension d = scrollPane.getVisibleRect().getSize(); if (scrollPane.getBorder() != null) { d.setSize(d.getWidth() - scrollInsets.left - scrollInsets.right, d.getHeight() - scrollInsets.top - scrollInsets.bottom); } if (x <= d.getWidth()) x = ((int) d.getWidth()) - 20; if (y <= d.getHeight()) y = ((int) d.getHeight()) - 20; desktop.setAllSize(x, y); scrollPane.invalidate(); scrollPane.validate(); } } } /** * Menu component that handles the functionality expected of a standard * "Windows" menu for MDI applications. */ class WindowMenu extends JMenu { private MDIDesktopPane desktop; private JMenuItem cascade = new JMenuItem("Cascade"); private JMenuItem tile = new JMenuItem("Tile"); public WindowMenu(MDIDesktopPane desktop) { this.desktop = desktop; setText("Window"); cascade.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { WindowMenu.this.desktop.cascadeFrames(); } }); tile.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { WindowMenu.this.desktop.tileFrames(); } }); addMenuListener(new MenuListener() { public void menuCanceled(MenuEvent e) { } public void menuDeselected(MenuEvent e) { removeAll(); } public void menuSelected(MenuEvent e) { buildChildMenus(); } }); } /* Sets up the children menus depending on the current desktop state */ private void buildChildMenus() { int i; ChildMenuItem menu; JInternalFrame[] array = desktop.getAllFrames(); add(cascade); add(tile); if (array.length > 0) addSeparator(); cascade.setEnabled(array.length > 0); tile.setEnabled(array.length > 0); for (i = 0; i < array.length; i++) { menu = new ChildMenuItem(array[i]); menu.setState(i == 0); menu.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { JInternalFrame frame = ((ChildMenuItem) ae.getSource()).getFrame(); frame.moveToFront(); try { frame.setSelected(true); } catch (PropertyVetoException e) { e.printStackTrace(); } } }); menu.setIcon(array[i].getFrameIcon()); add(menu); } } /* * This JCheckBoxMenuItem descendant is used to track the child frame that * corresponds to a give menu. */ class ChildMenuItem extends JCheckBoxMenuItem { private JInternalFrame frame; public ChildMenuItem(JInternalFrame frame) { super(frame.getTitle()); this.frame = frame; } public JInternalFrame getFrame() { return frame; } } }