/*
* Copyright (c) 2004-2007 by Michael Connor. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* o Neither the name of FormLayoutBuilder or Michael Connor nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.mlc.swing.layout;
import java.awt.Component;
import java.awt.LayoutManager2;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
/**
* This class acts as a surogate layout manager for the JGoodies
* (www.jgoodies.com) FormLayout manager. This layout manager enables us to
* associate names with components and then define the constraints for the
* component elsewhere (like xml)
*
* @author Michael Connor
@version $Id$
@since Ptolemy II 7.1
*/
public class ContainerLayout implements LayoutManager2 {
java.util.List<String> rowSpecs = new ArrayList<String>();
java.util.List<String> columnSpecs = new ArrayList<String>();
LinkedHashMap<String, CellConstraints> componentConstraints = new LinkedHashMap<String, CellConstraints>();
Map<Component, String> componentsToNames = new HashMap<Component, String>();
Map<String, Map<String, Object>> componentNameToCustomProps = new HashMap<String, Map<String, Object>>();
Map<String, ComponentDef> componentNameToComponentDef = new HashMap<String, ComponentDef>();
FormLayout formLayout;
String name;
public ContainerLayout(String name, String columnSpecs, String rowSpecs) {
this.name = name;
StringTokenizer cols = new StringTokenizer(columnSpecs, ",", false);
StringTokenizer rows = new StringTokenizer(rowSpecs, ",", false);
while (cols.hasMoreTokens()) {
this.columnSpecs.add(cols.nextToken());
}
while (rows.hasMoreTokens()) {
this.rowSpecs.add(rows.nextToken());
}
formLayout = new FormLayout(columnSpecs, rowSpecs);
}
private void buildLayout() throws IllegalArgumentException {
formLayout = new FormLayout(delimit(columnSpecs), delimit(rowSpecs));
// now we have to add all of the compenents to the new form
for (Iterator i = componentsToNames.keySet().iterator(); i.hasNext();) {
Component component = (Component) i.next();
String componentName = componentsToNames.get(component);
CellConstraints constraints = componentConstraints
.get(componentName);
formLayout.addLayoutComponent(component, constraints);
}
}
private String delimit(List<String> values) {
StringBuffer buffer = new StringBuffer();
for (int index = 0; index < values.size(); index++) {
buffer.append(values.get(index));
if (index < values.size() - 1) {
buffer.append(",");
}
}
return buffer.toString();
}
protected Map<Component, String> getComponentsToNames() {
return Collections.unmodifiableMap(componentsToNames);
}
/**
* Registers the value of the name property
*
* @param name
* The value of the property
*/
public void setName(String name) {
this.name = name;
}
/**
* Returns the value of the name property
*
* @return The value
*/
public String getName() {
return this.name;
}
/**
* Returns custom properties for the component. If no custom props exist then
* an empty map will be returned.
*/
public Map<String, Object> getCustomProperties(String componentName) {
return componentNameToCustomProps.containsKey(componentName) ? componentNameToCustomProps
.get(componentName)
: new HashMap<String, Object>();
}
/**
* Set a user defined property for this component so that the tool can manage
* the properties of the component thus reducing the burden on the user
*/
public void setProperty(String componentName, String property, Object value) {
Map customProps = componentNameToCustomProps.get(componentName);
if (customProps == null) {
customProps = new HashMap<String, Object>();
componentNameToCustomProps.put(componentName, customProps);
}
customProps.put(property, value);
}
public void setCellConstraints(String componentName,
CellConstraints constraints) {
componentConstraints.put(name, constraints);
for (Iterator i = componentsToNames.keySet().iterator(); i.hasNext();) {
Component component = (Component) i.next();
String thisName = componentsToNames.get(component);
if (thisName.equals(componentName)) {
formLayout.setConstraints(component, constraints);
break;
}
}
}
public LinkedHashMap<String, CellConstraints> getCellConstraints() {
return componentConstraints;
}
public void addComponent(String componentName, ComponentDef componentDef,
CellConstraints constraints) {
componentConstraints.put(componentName, constraints);
componentNameToComponentDef.put(componentName, componentDef);
}
public ComponentDef getComponentDef(String componentName) {
return componentNameToComponentDef.get(componentName);
}
public String getColumnSpecsString() {
StringBuffer buffer = new StringBuffer();
for (Iterator i = columnSpecs.iterator(); i.hasNext();) {
buffer.append(i.next());
if (i.hasNext()) {
buffer.append(",");
}
}
return buffer.toString();
}
public String getRowSpecsString() {
StringBuffer buffer = new StringBuffer();
for (Iterator i = rowSpecs.iterator(); i.hasNext();) {
buffer.append(i.next());
if (i.hasNext()) {
buffer.append(",");
}
}
return buffer.toString();
}
public int getRowCount() {
return rowSpecs.size();
}
public int getColumnCount() {
return columnSpecs.size();
}
public List<String> getRowSpecs() {
return this.rowSpecs;
}
public List<String> getColumnSpecs() {
return this.columnSpecs;
}
public void constraintsChanged(String name, CellConstraints constraints) {
componentConstraints.put(name, constraints);
}
public CellConstraints getCellConstraints(String name) {
return componentConstraints.get(name);
}
public void addCellConstraints(String name, CellConstraints constraints) {
componentConstraints.put(name, constraints);
}
public CellConstraints removeCellConstraints(String name) {
CellConstraints constraints = componentConstraints.remove(name);
return constraints;
}
public void addColumnSpec(String columnSpec)
throws IllegalArgumentException {
columnSpecs.add(columnSpec);
buildLayout();
}
public String getRowSpec(int index) {
return rowSpecs.get(index);
}
public String getColumnSpec(int index) {
return columnSpecs.get(index);
}
public void setRowSpec(int index, String rowSpec)
throws IllegalArgumentException {
rowSpecs.set(index, rowSpec);
buildLayout();
}
public void setColumnSpec(int index, String columnSpec)
throws IllegalArgumentException {
columnSpecs.set(index, columnSpec);
buildLayout();
}
public void addRowSpec(String rowSpec) throws IllegalArgumentException {
rowSpecs.add(rowSpec);
buildLayout();
}
public String removeRowSpec(int index) {
String rowSpec = rowSpecs.remove(index);
try {
buildLayout();
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
}
return rowSpec;
}
public String removeColumnSpec(int index) {
String spec = columnSpecs.remove(index);
try {
buildLayout();
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
}
return spec;
}
public void addRowSpec(int index, String rowSpec)
throws IllegalArgumentException {
rowSpecs.add(index, rowSpec);
buildLayout();
}
public void addColumnSpec(int index, String columnSpec)
throws IllegalArgumentException {
columnSpecs.add(index, columnSpec);
buildLayout();
}
/* the following methods realize the LayoutManager interface */
public String getComponentName(Component component) {
return componentsToNames.get(component);
}
/**
* Returns the component with the given name or null if not found
*/
public Component getComponentByName(String name) {
for (Component component : componentsToNames.keySet()) {
String testName = componentsToNames.get(component);
if (testName.equals(name)) {
return component;
}
}
return null;
}
public CellConstraints getComponentConstraints(Component component) {
String name = componentsToNames.get(component);
if (name == null) {
throw new RuntimeException("Unable to find name for component "
+ component);
}
return componentConstraints.get(name);
}
// interface for LayoutManager2
public void addLayoutComponent(String name, java.awt.Component comp) {
throw new RuntimeException(
"This method should not be called. Call addLayoutComponent (Component, Object) instead");
}
public float getLayoutAlignmentX(java.awt.Container target) {
return formLayout.getLayoutAlignmentX(target);
}
public float getLayoutAlignmentY(java.awt.Container target) {
return formLayout.getLayoutAlignmentY(target);
}
public FormLayout.LayoutInfo getLayoutInfo(java.awt.Container container) {
// KBR added to allow FormDebugPanel to work with ContainerLayout
return this.formLayout.getLayoutInfo(container);
}
public void invalidateLayout(java.awt.Container target) {
formLayout.invalidateLayout(target);
}
public void layoutContainer(java.awt.Container parent) {
formLayout.layoutContainer(parent);
}
public java.awt.Dimension maximumLayoutSize(java.awt.Container target) {
return formLayout.maximumLayoutSize(target);
}
public java.awt.Dimension minimumLayoutSize(java.awt.Container parent) {
return formLayout.minimumLayoutSize(parent);
}
public java.awt.Dimension preferredLayoutSize(java.awt.Container parent) {
return formLayout.preferredLayoutSize(parent);
}
public void removeLayoutComponent(java.awt.Component comp) {
String componentName = componentsToNames.get(comp);
componentsToNames.remove(comp);
componentConstraints.remove(componentName);
formLayout.removeLayoutComponent(comp);
}
public void addLayoutComponent(java.awt.Component comp, Object constraints) {
if (!(constraints instanceof String)) {
throw new RuntimeException(
"The constraints must be a String name which should reference a CellConstraints entry in the xml file");
}
String componentName = (String) constraints;
CellConstraints cellConstraints = componentConstraints
.get(componentName);
if (cellConstraints == null) {
System.out.println("Warning : " + componentName
+ " was added without constraints");
cellConstraints = new CellConstraints();
componentConstraints.put(componentName, cellConstraints);
comp.setVisible(false);
} else {
Map<String, Object> customProps = componentNameToCustomProps
.get(componentName);
if (customProps != null) {
for (String prop : customProps.keySet()) {
Object value = customProps.get(prop);
// KBR Class compClass = comp.getClass();
try {
BeanInfo beanInfo = Introspector.getBeanInfo(comp
.getClass());
PropertyDescriptor[] props = beanInfo
.getPropertyDescriptors();
for (int index = 0; index < props.length; index++) {
PropertyDescriptor propertyDescriptor = props[index];
if (propertyDescriptor.getName().equals(prop)) {
Method writeMethod = propertyDescriptor
.getWriteMethod();
writeMethod
.invoke(comp, new Object[] { value });
break;
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
componentsToNames.put(comp, componentName);
formLayout.addLayoutComponent(comp, cellConstraints);
}
// private class LocationScore implements Comparable<LocationScore>
// {
// public int score;
//
// public int row;
//
// public int col;
//
// public int width;
//
// public LocationScore(int score, int row, int col, int width)
// {
// this.score = score;
// this.row = row;
// this.col = col;
// this.width = width;
// }
//
// public int compareTo(LocationScore testScore)
// {
// return this.score < testScore.score ? -1
// : this.score > testScore.score ? 1 : 0;
// }
// }
public static void main(String[] args) {
}
}