Java tutorial
/* This program is a part of the companion code for Core Java 8th ed. (http://horstmann.com/corejava) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ import java.awt.BorderLayout; import java.awt.Component; import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyVetoException; import java.beans.VetoableChangeListener; import javax.swing.ImageIcon; import javax.swing.JCheckBoxMenuItem; import javax.swing.JDesktopPane; import javax.swing.JFrame; import javax.swing.JInternalFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; /** * This program demonstrates the use of internal frames. * @version 1.11 2007-08-01 * @author Cay Horstmann */ public class InternalFrameTest { public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { JFrame frame = new DesktopFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }); } } /** * This desktop frame contains editor panes that show HTML documents. */ class DesktopFrame extends JFrame { public DesktopFrame() { setTitle("InternalFrameTest"); setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); desktop = new JDesktopPane(); add(desktop, BorderLayout.CENTER); // set up menus JMenuBar menuBar = new JMenuBar(); setJMenuBar(menuBar); JMenu fileMenu = new JMenu("File"); menuBar.add(fileMenu); JMenuItem openItem = new JMenuItem("New"); openItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { createInternalFrame(new JLabel(new ImageIcon(planets[counter] + ".gif")), planets[counter]); counter = (counter + 1) % planets.length; } }); fileMenu.add(openItem); JMenuItem exitItem = new JMenuItem("Exit"); exitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { System.exit(0); } }); fileMenu.add(exitItem); JMenu windowMenu = new JMenu("Window"); menuBar.add(windowMenu); JMenuItem nextItem = new JMenuItem("Next"); nextItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { selectNextWindow(); } }); windowMenu.add(nextItem); JMenuItem cascadeItem = new JMenuItem("Cascade"); cascadeItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { cascadeWindows(); } }); windowMenu.add(cascadeItem); JMenuItem tileItem = new JMenuItem("Tile"); tileItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { tileWindows(); } }); windowMenu.add(tileItem); final JCheckBoxMenuItem dragOutlineItem = new JCheckBoxMenuItem("Drag Outline"); dragOutlineItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { desktop.setDragMode(dragOutlineItem.isSelected() ? JDesktopPane.OUTLINE_DRAG_MODE : JDesktopPane.LIVE_DRAG_MODE); } }); windowMenu.add(dragOutlineItem); } /** * Creates an internal frame on the desktop. * @param c the component to display in the internal frame * @param t the title of the internal frame. */ public void createInternalFrame(Component c, String t) { final JInternalFrame iframe = new JInternalFrame(t, true, // resizable true, // closable true, // maximizable true); // iconifiable iframe.add(c, BorderLayout.CENTER); desktop.add(iframe); iframe.setFrameIcon(new ImageIcon("document.gif")); // add listener to confirm frame closing iframe.addVetoableChangeListener(new VetoableChangeListener() { public void vetoableChange(PropertyChangeEvent event) throws PropertyVetoException { String name = event.getPropertyName(); Object value = event.getNewValue(); // we only want to check attempts to close a frame if (name.equals("closed") && value.equals(true)) { // ask user if it is ok to close int result = JOptionPane.showInternalConfirmDialog(iframe, "OK to close?", "Select an Option", JOptionPane.YES_NO_OPTION); // if the user doesn't agree, veto the close if (result != JOptionPane.YES_OPTION) throw new PropertyVetoException("User canceled close", event); } } }); // position frame int width = desktop.getWidth() / 2; int height = desktop.getHeight() / 2; iframe.reshape(nextFrameX, nextFrameY, width, height); iframe.show(); // select the frame--might be vetoed try { iframe.setSelected(true); } catch (PropertyVetoException e) { } frameDistance = iframe.getHeight() - iframe.getContentPane().getHeight(); // compute placement for next frame nextFrameX += frameDistance; nextFrameY += frameDistance; if (nextFrameX + width > desktop.getWidth()) nextFrameX = 0; if (nextFrameY + height > desktop.getHeight()) nextFrameY = 0; } /** * Cascades the non-iconified internal frames of the desktop. */ public void cascadeWindows() { int x = 0; int y = 0; int width = desktop.getWidth() / 2; int height = desktop.getHeight() / 2; for (JInternalFrame frame : desktop.getAllFrames()) { if (!frame.isIcon()) { try { // try to make maximized frames resizable; this might be vetoed frame.setMaximum(false); frame.reshape(x, y, width, height); x += frameDistance; y += frameDistance; // wrap around at the desktop edge if (x + width > desktop.getWidth()) x = 0; if (y + height > desktop.getHeight()) y = 0; } catch (PropertyVetoException e) { } } } } /** * Tiles the non-iconified internal frames of the desktop. */ public void tileWindows() { // count frames that aren't iconized int frameCount = 0; for (JInternalFrame frame : desktop.getAllFrames()) if (!frame.isIcon()) frameCount++; if (frameCount == 0) return; int rows = (int) Math.sqrt(frameCount); int cols = frameCount / rows; int extra = frameCount % rows; // number of columns with an extra row int width = desktop.getWidth() / cols; int height = desktop.getHeight() / rows; int r = 0; int c = 0; for (JInternalFrame frame : desktop.getAllFrames()) { if (!frame.isIcon()) { try { frame.setMaximum(false); frame.reshape(c * width, r * height, width, height); r++; if (r == rows) { r = 0; c++; if (c == cols - extra) { // start adding an extra row rows++; height = desktop.getHeight() / rows; } } } catch (PropertyVetoException e) { } } } } /** * Brings the next non-iconified internal frame to the front. */ public void selectNextWindow() { JInternalFrame[] frames = desktop.getAllFrames(); for (int i = 0; i < frames.length; i++) { if (frames[i].isSelected()) { // find next frame that isn't an icon and can be selected int next = (i + 1) % frames.length; while (next != i) { if (!frames[next].isIcon()) { try { // all other frames are icons or veto selection frames[next].setSelected(true); frames[next].toFront(); frames[i].toBack(); return; } catch (PropertyVetoException e) { } } next = (next + 1) % frames.length; } } } } private JDesktopPane desktop; private int nextFrameX; private int nextFrameY; private int frameDistance; private int counter; private static final String[] planets = { "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto", }; private static final int DEFAULT_WIDTH = 600; private static final int DEFAULT_HEIGHT = 400; }