/* * Open Source Physics software is free software as described near the bottom of this code file. * * For additional information and documentation on Open Source Physics please see: * <http://www.opensourcephysics.org/> */ package org.opensourcephysics.display; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.Rectangle; import java.util.ArrayList; /** * A OSP layout lays out a container, arranging and resizing its components to fit * in the corners or in one of the border layout regions. * * @author W. Christian * @version 1.0 */ public class OSPLayout extends BorderLayout { public static int macOffset; ArrayList<Component> list = new ArrayList<Component>(); /** * The top left corner layout constraint. */ public static final String TOP_LEFT_CORNER = "TopLeftCorner"; //$NON-NLS-1$ /** * The top right corner layout constraint. */ public static final String TOP_RIGHT_CORNER = "TopRightCorner"; //$NON-NLS-1$ /** * The bottom left corner layout constraint. */ public static final String BOTTOM_LEFT_CORNER = "BottomLeftCorner"; //$NON-NLS-1$ /** * The bottom right layout constraint. */ public static final String BOTTOM_RIGHT_CORNER = "BottomRightCorner"; //$NON-NLS-1$ /** * The bottom right layout constraint. */ public static final String CENTERED = "Centered"; //$NON-NLS-1$ /** * Constant to specify components location to be the top left corner portion of the layout. */ Component topLeftCorner; /** * Constant to specify components location to be the top right corner portion of the layout. */ Component topRightCorner; /** * Constant to specify components location to be the bottom left corner portion of the layout. */ Component bottomLeftCorner; /** * Constant to specify components location to be the bottom right corner portion of the layout. */ Component bottomRightCorner; /** * Constant to specify components location to be centered in the layout. */ Component centeredComp; Rectangle layoutRect = new Rectangle(0, 0, 0, 0); Component[] components = new Component[0]; static { try { // system properties may not be readable in some environments macOffset = ("Mac OS X".equals(System.getProperty("os.name"))) ? 16 : 0; //$NON-NLS-1$ //$NON-NLS-2$ } catch(SecurityException ex) {} } /** * Constructs a new OSP layout with no gaps between components. */ public OSPLayout() { this(0, 0); } /** * Constructs a new OSP layout with the specified gaps between components. * The horizontal gap is specified by <code>hgap</code> * and the vertical gap is specified by <code>vgap</code>. * @param hgap the horizontal gap. * @param vgap the vertical gap. */ public OSPLayout(int hgap, int vgap) { super(hgap, vgap); } public void addLayoutComponent(Component comp, Object constraints) { if(!list.contains(comp)) { list.add(comp); components = list.toArray(new Component[0]); } synchronized(comp.getTreeLock()) { if((constraints instanceof String)&&"TopLeftCorner".equals(constraints)) { //$NON-NLS-1$ list.remove(topLeftCorner); topLeftCorner = comp; } else if((constraints instanceof String)&&"TopRightCorner".equals(constraints)) { //$NON-NLS-1$ list.remove(topRightCorner); topRightCorner = comp; } else if((constraints instanceof String)&&"BottomLeftCorner".equals(constraints)) { //$NON-NLS-1$ list.remove(bottomLeftCorner); bottomLeftCorner = comp; } else if((constraints instanceof String)&&"BottomRightCorner".equals(constraints)) { //$NON-NLS-1$ list.remove(bottomRightCorner); bottomRightCorner = comp; } else if((constraints instanceof String)&&"Centered".equals(constraints)) { //$NON-NLS-1$ list.remove(centeredComp); centeredComp = comp; } else { super.addLayoutComponent(comp, constraints); } } } /** * Removes the specified component from this border layout. This * method is called when a container calls its <code>remove</code> or * <code>removeAll</code> methods. Most applications do not call this * method directly. * @param comp the component to be removed. * @see java.awt.Container#remove(java.awt.Component) * @see java.awt.Container#removeAll() */ public void removeLayoutComponent(Component comp) { if(list.contains(comp)) { list.remove(comp); components = list.toArray(new Component[0]); } synchronized(comp.getTreeLock()) { if(comp==topLeftCorner) { topLeftCorner = null; } else if(comp==topRightCorner) { topRightCorner = null; } else if(comp==bottomLeftCorner) { bottomLeftCorner = null; } else if(comp==bottomRightCorner) { bottomRightCorner = null; } else if(comp==centeredComp) { centeredComp = null; } else { super.removeLayoutComponent(comp); } } } /** * Lays out the container argument using this layout. * @param target Container */ public void layoutContainer(Container target) { super.layoutContainer(target); doMyLayout(target); } /** * Lays out a single component by setting the component's bounds. * @param target Container */ public boolean quickLayout(Container target, Component c) { if((target==null)||(c==null)) { return false; } Insets insets = target.getInsets(); int top = insets.top; int bottom = target.getHeight()-insets.bottom; int left = insets.left; int right = target.getWidth()-insets.right; if(topLeftCorner==c) { Dimension d = c.getPreferredSize(); c.setSize(d.width, d.height); c.setBounds(left, top, d.width, d.height); } else if(topRightCorner==c) { Dimension d = c.getPreferredSize(); c.setSize(d.width, d.height); c.setBounds(right-d.width, top, d.width, d.height); } else if(bottomLeftCorner==c) { Dimension d = c.getPreferredSize(); c.setSize(d.width, d.height); c.setBounds(left, bottom-d.height, d.width, d.height); } else if(bottomRightCorner==c) { Dimension d = c.getPreferredSize(); c.setSize(d.width, d.height); c.setBounds(right-d.width-macOffset, bottom-d.height, d.width, d.height); } else if(centeredComp==c) { Dimension d = c.getPreferredSize(); c.setSize(d.width, d.height); c.setBounds((right-left-d.width)/2, (bottom-top-d.height)/2, d.width, d.height); } else { return false; } return true; } public void checkLayoutRect(Container c, Rectangle viewRect) { if(layoutRect.equals(viewRect)) { return; } // doMyLayout(c); layoutContainer(c); } public Component[] getComponents() { return components; } void doMyLayout(Container target) { Insets insets = target.getInsets(); int top = insets.top; int bottom = target.getHeight()-insets.bottom; int left = insets.left; int right = target.getWidth()-insets.right; Component c = null; if(topLeftCorner!=null) { c = topLeftCorner; Dimension d = c.getPreferredSize(); c.setSize(d.width, d.height); c.setBounds(left, top, d.width, d.height); } if(topRightCorner!=null) { c = topRightCorner; Dimension d = c.getPreferredSize(); c.setSize(d.width, d.height); c.setBounds(right-d.width, top, d.width, d.height); } if(bottomLeftCorner!=null) { c = bottomLeftCorner; Dimension d = c.getPreferredSize(); c.setSize(d.width, d.height); c.setBounds(left, bottom-d.height, d.width, d.height); } if(bottomRightCorner!=null) { c = bottomRightCorner; Dimension d = c.getPreferredSize(); c.setSize(d.width+macOffset, d.height); c.setBounds(right-d.width-macOffset, bottom-d.height, d.width, d.height); } if(centeredComp!=null) { c = centeredComp; Dimension d = c.getPreferredSize(); c.setSize(d.width, d.height); c.setBounds((right-left-d.width)/2, (bottom-top-d.height)/2, d.width, d.height); } } } /* * Open Source Physics software is free software; you can redistribute * it and/or modify it under the terms of the GNU General Public License (GPL) as * published by the Free Software Foundation; either version 2 of the License, * or(at your option) any later version. * Code that uses any portion of the code in the org.opensourcephysics package * or any subpackage (subdirectory) of this package must must also be be released * under the GNU GPL license. * * This software 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; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307 USA * or view the license online at http://www.gnu.org/copyleft/gpl.html * * Copyright (c) 2007 The Open Source Physics project * http://www.opensourcephysics.org */