/*
* 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
*/