JDesktopPane - minimising JInternalFrames

1.3k views Asked by At

I working with JDesktopPane and creating multiple JInternalFrame objects. When I minimize all and maximize any one of them, the opened frame covers all minimized frames.

How to make all minimized frames visible?

1

There are 1 answers

0
camickr On

By default the internal frame is maximized to take all the space of the desktop. This behaviour is relatively easy by change by customizing the DesktopManager. For example:

import java.awt.*;
import javax.swing.*;
import java.beans.PropertyVetoException;

class MaximizeDesktopManager extends DefaultDesktopManager
{
    @Override
    public void maximizeFrame(JInternalFrame f)
    {
        if (f.isIcon())
        {
            try
            {
                // In turn calls deiconifyFrame in the desktop manager.
                // That method will handle the maximization of the frame.
                f.setIcon(false);
            }
            catch (PropertyVetoException e2) {}
        }
        else
        {
            f.setNormalBounds(f.getBounds());
//          Rectangle desktopBounds = f.getParent().getBounds();
            Rectangle desktopBounds = getDesktopBounds(f);
            setBoundsForFrame(f, 0, 0, desktopBounds.width, desktopBounds.height);
        }

          // Set the maximized frame as selected.
        try
        {
           f.setSelected(true);
        }
        catch (PropertyVetoException e2) {}
    }

    private Rectangle getDesktopBounds(JInternalFrame frame)
    {
        Rectangle desktopBounds = frame.getParent().getBounds();

        for (Component c: frame.getParent().getComponents())
        {
            if (c instanceof JInternalFrame.JDesktopIcon)
            {
                desktopBounds.height = Math.min(desktopBounds.height, c.getLocation().y);
            }
        }

        return desktopBounds;
    }

    private static void createAndShowUI()
    {
        JDesktopPane desktop = new JDesktopPane();
        desktop.setDesktopManager( new MaximizeDesktopManager() );

        desktop.add( createInternalFrame(1, Color.RED) );
        desktop.add( createInternalFrame(2, Color.GREEN) );
        desktop.add( createInternalFrame(3, Color.BLUE) );

        JFrame frame = new JFrame("Maximize Desktop Manager");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( desktop );
        frame.setSize(600, 600);
        frame.setLocationRelativeTo( null );
        frame.setVisible( true );

        //  Activate first internal frame

        try
        {
            JInternalFrame[] frames = desktop.getAllFrames();
            frames[0].setSelected(true);
        }
        catch (java.beans.PropertyVetoException e) {}
    }

    private static JInternalFrame createInternalFrame(int number, Color background)
    {
        JInternalFrame internal =
            new JInternalFrame( "Frame" + number, true, true, true, true );
        internal.setBackground( background );
        internal.setVisible( true );
        int location = 50 * number;
        internal.setBounds(location, location, 300, 300);
        return internal;
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }

}

Unfortunately if you resize the frame, then the bounds of the internal frame are readjusted to match the bounds of the desktop pane again. The logic that does this is in the BasicInternalFrameUI:

/** Invoked when a JInternalFrame's parent's size changes. */
public void componentResized(ComponentEvent e) {
    // Get the JInternalFrame's parent container size
    Rectangle parentNewBounds = ((Component) e.getSource()).getBounds();
    JInternalFrame.JDesktopIcon icon = null;

    if (frame != null) {
        icon = frame.getDesktopIcon();
        // Resize the internal frame if it is maximized and relocate
        // the associated icon as well.
        if (frame.isMaximum()) {
            frame.setBounds(0, 0, parentNewBounds.width,
                parentNewBounds.height);
        }
    }

This logic is found in a private internal class of the UI so it will not be easy to change. At least I don't know how to do it.