/*******************************************************************************
* Mission Control Technologies, Copyright (c) 2009-2012, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* The MCT platform is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
* MCT includes source code licensed under additional open source licenses. See
* the MCT Open Source Licenses file included with this distribution or the About
* MCT Licenses dialog available at runtime from the MCT Help menu for additional
* information.
*******************************************************************************/
package gov.nasa.arc.mct.gui.layout;
import java.awt.Component;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.Point;
/**
* An extended version of FlowLayout, that supports different types of vertical
* alignment.
*
* Adapted from a workaround in http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4295966.
*
* @author mrose
*
*/
public class EnhancedFlowLayout extends FlowLayout {
public final static long serialVersionUID = 1;
/**
* Items in the layout should be top-aligned.
*/
public final static int TOP = 2;
/**
* Items in the layout should be bottom-aligned.
*/
public final static int BOTTOM = 3;
private int verticalAlignment = TOP;
/**
* Create a new layout with the given horizontal and vertical alignment. The vertical gap,
* as in FlowLayout, is set to zero if this constructor is used.
*
* @param horizontalAlignment the desired horizontal alignment, as in FlowLayout
* @param verticalAlignment the desired vertical alignment
*/
public EnhancedFlowLayout(int horizontalAlignment, int verticalAlignment) {
this(horizontalAlignment, verticalAlignment, 0, 0);
}
/**
* Create a new layout with given horizonal and vertical alignment, and horizontal
* and vertical gaps to place between items in the layout.
*
* @param horizontalAlignment the desired horizontal alignment, as in FlowLayout
* @param verticalAlignment the desired vertical alignment
* @param hGap the desired horizontal gap between adjacent items in the layout
* @param vGap the desired vertical gap between adjacent items in the layout
*/
public EnhancedFlowLayout(int horizontalAlignment, int verticalAlignment, int hGap, int vGap) {
super(horizontalAlignment, hGap, vGap);
setVerticalAlignment(verticalAlignment);
}
/**
* Return the current vertical alignment. Will be one of TOP, BOTTOM, or CENTER.
*
* @return the vertical alignment setting
*/
public int getVerticalAlignment() {
return verticalAlignment;
}
/**
* Change the vertical alignment. Should be one of TOP, BOTTOM, or CENTER.
*
* @param verticalAlignment the new vertical alignment value.
*/
public void setVerticalAlignment(int verticalAlignment) {
this.verticalAlignment = verticalAlignment;
}
@Override
public void layoutContainer(Container target)
{
synchronized (target.getTreeLock())
{
super.layoutContainer(target);
if (verticalAlignment != TOP)
{
// first, find the highest and lowest points
int minY=Integer.MAX_VALUE;
int maxY=0;
int nMembers = target.getComponentCount();
for (int i=0; i<nMembers; ++i)
{
Component comp = target.getComponent(i);
int compMinY = comp.getLocation().y;
int compMaxY = compMinY + comp.getHeight();
maxY = Math.max(compMaxY, maxY);
minY = Math.min(compMinY, minY);
}
// Now, calculate how far to drop each component.
Insets insets = target.getInsets();
int availableHeight = target.getHeight() - (insets.bottom + insets.top + getVgap()*2);
// delta is the amount to move each component
int delta = availableHeight - (maxY - minY); // bottom alignment
if (verticalAlignment == CENTER)
delta /= 2; // center alignment
// Now, move each component down.
for (int i=0; i<nMembers; ++i)
{
Component comp = target.getComponent(i);
Point newLoc = comp.getLocation();
newLoc.y += delta;
comp.setLocation(newLoc);
}
}
}
}
}