SampleDesktop.java Source code

Java tutorial

Introduction

Here is the source code for SampleDesktop.java

Source

/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O'Reilly 
*/

// SampleDesktop.java
//Another example that shows how to do a few interesting things using
//JInternalFrames, JDesktopPane, and DesktopManager.
//

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;

import javax.swing.AbstractAction;
import javax.swing.DefaultDesktopManager;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;

public class SampleDesktop extends JFrame {

    private JDesktopPane desk;

    private IconPolice iconPolice = new IconPolice();

    public SampleDesktop(String title) {
        super(title);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        // Create a desktop and set it as the content pane. Don't set the
        // layered
        // pane, since it needs to hold the menu bar too.
        desk = new JDesktopPane();
        setContentPane(desk);

        // Install our custom desktop manager.
        desk.setDesktopManager(new SampleDesktopMgr());

        createMenuBar();
        loadBackgroundImage();
    }

    // Create a menu bar to show off a few things.
    protected void createMenuBar() {
        JMenuBar mb = new JMenuBar();
        JMenu menu = new JMenu("Frames");

        menu.add(new AddFrameAction(true)); // add "upper" frame
        menu.add(new AddFrameAction(false)); // add "lower" frame
        menu.add(new TileAction(desk)); // add tiling capability

        setJMenuBar(mb);
        mb.add(menu);
    }

    // Here we load a background image for our desktop.
    protected void loadBackgroundImage() {
        ImageIcon icon = new ImageIcon("images/matterhorn.gif");
        JLabel l = new JLabel(icon);
        l.setBounds(0, 0, icon.getIconWidth(), icon.getIconHeight());

        // Place the image in the lowest possible layer so nothing
        // can ever be painted under it.
        desk.add(l, new Integer(Integer.MIN_VALUE));
    }

    // This class adds a new JInternalFrame when requested.
    class AddFrameAction extends AbstractAction {
        public AddFrameAction(boolean upper) {
            super(upper ? "Add Upper Frame" : "Add Lower Frame");
            if (upper) {
                this.layer = new Integer(2);
                this.name = "Up";
            } else {
                this.layer = new Integer(1);
                this.name = "Lo";
            }
        }

        public void actionPerformed(ActionEvent ev) {
            JInternalFrame f = new JInternalFrame(name, true, true, true, true);
            f.addVetoableChangeListener(iconPolice);

            f.setBounds(0, 0, 120, 60);
            desk.add(f, layer);
            f.setVisible(true); // Needed since 1.3
        }

        private Integer layer;

        private String name;
    }

    // A simple vetoable change listener that insists that there is always at
    // least one noniconified frame (just as an example of the vetoable
    // properties).
    class IconPolice implements VetoableChangeListener {
        public void vetoableChange(PropertyChangeEvent ev) throws PropertyVetoException {
            String name = ev.getPropertyName();
            if (name.equals(JInternalFrame.IS_ICON_PROPERTY) && (ev.getNewValue() == Boolean.TRUE)) {
                JInternalFrame[] frames = desk.getAllFrames();
                int count = frames.length;
                int nonicons = 0; // how many are not icons?
                for (int i = 0; i < count; i++) {
                    if (!frames[i].isIcon()) {
                        nonicons++;
                    }
                }
                if (nonicons <= 1) {
                    throw new PropertyVetoException("Invalid Iconification!", ev);
                }
            }
        }
    }

    // A simple test program.
    public static void main(String[] args) {
        SampleDesktop td = new SampleDesktop("Sample Desktop");

        td.setSize(300, 220);
        td.setVisible(true);
    }
}

//TileAction.java
//An action that tiles all internal frames when requested.
//

class TileAction extends AbstractAction {
    private JDesktopPane desk; // the desktop to work with

    public TileAction(JDesktopPane desk) {
        super("Tile Frames");
        this.desk = desk;
    }

    public void actionPerformed(ActionEvent ev) {

        // How many frames do we have?
        JInternalFrame[] allframes = desk.getAllFrames();
        int count = allframes.length;
        if (count == 0)
            return;

        // Determine the necessary grid size
        int sqrt = (int) Math.sqrt(count);
        int rows = sqrt;
        int cols = sqrt;
        if (rows * cols < count) {
            cols++;
            if (rows * cols < count) {
                rows++;
            }
        }

        // Define some initial values for size & location.
        Dimension size = desk.getSize();

        int w = size.width / cols;
        int h = size.height / rows;
        int x = 0;
        int y = 0;

        // Iterate over the frames, deiconifying any iconified frames and then
        // relocating & resizing each.
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols && ((i * cols) + j < count); j++) {
                JInternalFrame f = allframes[(i * cols) + j];

                if (!f.isClosed() && f.isIcon()) {
                    try {
                        f.setIcon(false);
                    } catch (PropertyVetoException ignored) {
                    }
                }

                desk.getDesktopManager().resizeFrame(f, x, y, w, h);
                x += w;
            }
            y += h; // start the next row
            x = 0;
        }
    }
}

//SampleDesktopMgr.java
//A DesktopManager that keeps its frames inside the desktop.

class SampleDesktopMgr extends DefaultDesktopManager {

    // This is called anytime a frame is moved. This
    // implementation keeps the frame from leaving the desktop.
    public void dragFrame(JComponent f, int x, int y) {
        if (f instanceof JInternalFrame) { // Deal only w/internal frames
            JInternalFrame frame = (JInternalFrame) f;
            JDesktopPane desk = frame.getDesktopPane();
            Dimension d = desk.getSize();

            // Nothing all that fancy below, just figuring out how to adjust
            // to keep the frame on the desktop.
            if (x < 0) { // too far left?
                x = 0; // flush against the left side
            } else {
                if (x + frame.getWidth() > d.width) { // too far right?
                    x = d.width - frame.getWidth(); // flush against right side
                }
            }
            if (y < 0) { // too high?
                y = 0; // flush against the top
            } else {
                if (y + frame.getHeight() > d.height) { // too low?
                    y = d.height - frame.getHeight(); // flush against the
                    // bottom
                }
            }
        }

        // Pass along the (possibly cropped) values to the normal drag handler.
        super.dragFrame(f, x, y);
    }
}