InternalFrameTest.java Source code

Java tutorial

Introduction

Here is the source code for InternalFrameTest.java

Source

/*
   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;
}