All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.javagl.common.ui.utils.desktop.JDesktopPaneLayout Maven / Gradle / Ivy

/*
 * www.javagl.de - Common - UI
 *
 * Copyright (c) 2013-2015 Marco Hutter - http://www.javagl.de
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */
package de.javagl.common.ui.utils.desktop;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JDesktopPane;
import javax.swing.JInternalFrame;
import javax.swing.JInternalFrame.JDesktopIcon;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;

/**
 * A layout manager for {@link JDesktopPane}s.
*
* This class is even more preliminary than all other classes in * this library! */ public class JDesktopPaneLayout { /** * A container that is associated with a desktop pane layout. * It is used internally for computing the actual layout. */ private static class LayoutContainer extends Container { /** * Serial UID */ private static final long serialVersionUID = 6455895807345631762L; /** * The owner of this container */ private final JDesktopPaneLayout owner; /** * Creates a new layout container with the given owner * * @param owner The owner */ LayoutContainer(JDesktopPaneLayout owner) { this.owner = owner; } } /** * The class for the dummy components that are added to the container * to determine the size of the internal frames */ private class FrameComponent extends JPanel { /** * Serial UID */ private static final long serialVersionUID = 7397992807282457681L; /** * The internal frame for which this component was created */ private final JInternalFrame internalFrame; /** * Creates a new dummy component for the given internal frame, * which was added with the given layout information * * @param internalFrame The internal frame * @param constraints The constraints * @param index The index */ FrameComponent( JInternalFrame internalFrame, final Object constraints, final int index) { this.internalFrame = internalFrame; internalFrame.addInternalFrameListener(new InternalFrameAdapter() { @Override public void internalFrameIconified(InternalFrameEvent e) { container.remove(FrameComponent.this); } @Override public void internalFrameDeiconified(InternalFrameEvent e) { container.add(FrameComponent.this, constraints, index); } @Override public void internalFrameClosed(InternalFrameEvent e) { container.remove(FrameComponent.this); } }); } /** * Returns the internal frame for which this component was created * * @return The internal frame */ JInternalFrame getInternalFrame() { return internalFrame; } @Override public Dimension getPreferredSize() { return internalFrame.getPreferredSize(); } @Override public Dimension getMaximumSize() { return internalFrame.getMaximumSize(); } @Override public Dimension getMinimumSize() { return internalFrame.getMinimumSize(); } } /** * The parent layout */ private final JDesktopPaneLayout parent; /** * The desktop pane that this layout manager is applied to */ private final JDesktopPane desktopPane; /** * The dummy container that will be used for computing the layout */ private final LayoutContainer container; /** * The root container. This is the layout container of the root * of the hierarchy of desktop pane layouts. */ private final LayoutContainer rootContainer; /** * A map from internal frames to {@link FrameComponent}s * that are placed into the dummy container */ private final Map frameToComponent; /** * Creates a new desktop pane layout for the given desktop pane * * @param desktopPane The desktop pane */ public JDesktopPaneLayout(JDesktopPane desktopPane) { this(null, desktopPane, null); } /** * Constructor for a child layout that was created with * {@link #createChild()} * * @param parent The parent layout * @param desktopPane The desktop pane of the parent * @param rootContainer The root container of the parent */ private JDesktopPaneLayout( JDesktopPaneLayout parent, JDesktopPane desktopPane, LayoutContainer rootContainer) { this.parent = parent; this.desktopPane = desktopPane; this.container = new LayoutContainer(this); if (rootContainer == null) { this.rootContainer = container; } else { this.rootContainer = rootContainer; } this.frameToComponent = new HashMap(); } /** * Create a new desktop pane layout that may be added as a child * to this layout * * @return The new child layout */ public JDesktopPaneLayout createChild() { return new JDesktopPaneLayout(this, desktopPane, rootContainer); } /** * Add the given desktop pane layout as a child to this one * * @param child The child to add * @throws IllegalArgumentException If the given child was not * created by calling {@link #createChild()} on this layout */ public void add(JDesktopPaneLayout child) { add(child, null); } /** * Add the given desktop pane layout as a child to this one * * @param child The child to add * @param constraints The constraints. * See {@link Container#add(Component, Object)} * @throws IllegalArgumentException If the given child was not * created by calling {@link #createChild()} on this layout */ public void add(JDesktopPaneLayout child, Object constraints) { add(child, constraints, -1); } /** * Add the given desktop pane layout as a child to this one * * @param child The child to add * @param constraints The constraints. * See {@link Container#add(Component, Object)} * @param index The index. * See {@link Container#add(Component, Object, int)} * @throws IllegalArgumentException If the given child was not * created by calling {@link #createChild()} on this layout */ public void add(JDesktopPaneLayout child, Object constraints, int index) { if (child.parent != this) { throw new IllegalArgumentException( "Layout is not a child of this layout"); } container.add(child.container, constraints, index); } /** * Remove the given child layout * * @param child The child to remove * @throws IllegalArgumentException If the given child was not * created by calling {@link #createChild()} on this layout */ public void remove(JDesktopPaneLayout child) { if (child.parent != this) { throw new IllegalArgumentException( "Layout is not a child of this layout"); } container.remove(child.container); } /** * Set the delegate layout manager for this layout * * @param layoutManager The delegate layout manager */ public void setLayout(LayoutManager layoutManager) { container.setLayout(layoutManager); } /** * Add the given internal frame to this layout manager.
*
* Note that this will not add the internal frame to the * desktop pane that this layout belongs to! * * @param internalFrame The internal frame to add */ public void add(JInternalFrame internalFrame) { add(internalFrame, null); } /** * Add the given internal frame to this layout manager.
*
* Note that this will not add the internal frame to the * desktop pane that this layout belongs to! * * @param internalFrame The internal frame to add * @param constraints The constraints. * See {@link Container#add(Component, Object)} */ public void add( JInternalFrame internalFrame, Object constraints) { add(internalFrame, constraints, -1); } /** * Add the given internal frame to this layout manager.
*
* Note that this will not add the internal frame to the * desktop pane that this layout belongs to! * * @param internalFrame The internal frame to add * @param constraints The constraints. * See {@link Container#add(Component, Object)} * @param index The index. * See {@link Container#add(Component, Object, int)} */ public void add( JInternalFrame internalFrame, Object constraints, int index) { FrameComponent frameComponent = new FrameComponent(internalFrame, constraints, index); frameToComponent.put(internalFrame, frameComponent); if (!internalFrame.isIcon()) { container.add(frameComponent, constraints, index); } } /** * Remove the given internal frame from this layout.
*
* Note that this will not remove the internal frame from the * desktop pane that this layout belongs to! * * @param internalFrame The internal frame to remove */ void remove(JInternalFrame internalFrame) { Component component = frameToComponent.get(internalFrame); container.remove(component); } /** * Validate the layout after internal frames have been added * or removed */ public void validate() { Dimension size = desktopPane.getSize(); size.height -= computeDesktopIconsSpace(); layoutInternalFrames(size); } /** * Compute the space for iconified desktop icons * * @return The space */ private int computeDesktopIconsSpace() { for (JInternalFrame f : frameToComponent.keySet()) { if (f.isIcon()) { JDesktopIcon desktopIcon = f.getDesktopIcon(); return desktopIcon.getPreferredSize().height; } } return 0; } /** * Layout the internal frames for the given size * * @param size The size */ private void layoutInternalFrames(Dimension size) { container.setSize(size); callDoLayout(container); applyLayout(); } /** * Recursively call doLayout on the container and all its * sub-containers * * @param container The container */ private void callDoLayout(Container container) { container.doLayout(); int n = container.getComponentCount(); for (int i=0; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy