0

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?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 1
    My understanding of your question is "how to make all minimized internal frames visible" but I feel as if this isn't what you are trying to do. Could you elaborate more and possibly include images to show your issue? – FThompson Aug 25 '13 at 20:43
  • 1
    Besides the images suggested by @Vulcan, consider posting an [SSCCE](http://sscce.org/) that displays the problem. Put just 2 internal frames in it. – Andrew Thompson Aug 25 '13 at 21:01
  • 1
    For [example](http://stackoverflow.com/a/9422246/230513). – trashgod Aug 25 '13 at 22:45

1 Answers1

1

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.

camickr
  • 321,443
  • 19
  • 166
  • 288