/* *************************************************************************
IT Mill Toolkit
Development of Browser User Interfaces Made Easy
Copyright (C) 2000-2006 IT Mill Ltd
*************************************************************************
This product is distributed under commercial license that can be found
from the product package on license.pdf. Use of this product might
require purchasing a commercial license from IT Mill Ltd. For guidelines
on usage, see licensing-guidelines.html
*************************************************************************
For more information, contact:
IT Mill Ltd phone: +358 2 4802 7180
Ruukinkatu 2-4 fax: +358 2 4802 7181
20540, Turku email: info@itmill.com
Finland company www: www.itmill.com
Primary source for information and releases: www.itmill.com
********************************************************************** */
package com.itmill.toolkit.ui;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import com.itmill.toolkit.terminal.PaintException;
import com.itmill.toolkit.terminal.PaintTarget;
import com.itmill.toolkit.terminal.gwt.client.ui.AlignmentInfo;
/**
* Ordered layout.
*
* OrderedLayout
is a component container, which shows the
* subcomponents in the order of their addition in specified orientation.
*
* @author IT Mill Ltd.
* @version
* @VERSION@
* @since 3.0
*/
public class OrderedLayout extends AbstractLayout {
/* Predefined orientations ***************************************** */
/**
* Components are to be laid out vertically.
*/
public static int ORIENTATION_VERTICAL = 0;
/**
* Components are to be laid out horizontally.
*/
public static int ORIENTATION_HORIZONTAL = 1;
/**
* Custom layout slots containing the components.
*/
protected LinkedList components = new LinkedList();
/* Child component alignments ************************************** */
/**
* Mapping from components to alignments (horizontal + vertical).
*/
private Map componentToAlignment = new HashMap();
/**
* Contained component should be aligned horizontally to the left.
*/
public static final int ALIGNMENT_LEFT = AlignmentInfo.ALIGNMENT_LEFT;
/**
* Contained component should be aligned horizontally to the right.
*/
public static final int ALIGNMENT_RIGHT = AlignmentInfo.ALIGNMENT_RIGHT;
/**
* Contained component should be aligned vertically to the top.
*/
public static final int ALIGNMENT_TOP = AlignmentInfo.ALIGNMENT_TOP;
/**
* Contained component should be aligned vertically to the bottom.
*/
public static final int ALIGNMENT_BOTTOM = AlignmentInfo.ALIGNMENT_BOTTOM;
/**
* Contained component should be horizontally aligned to center.
*/
public static final int ALIGNMENT_HORIZONTAL_CENTER = AlignmentInfo.ALIGNMENT_HORIZONTAL_CENTER;
/**
* Contained component should be vertically aligned to center.
*/
public static final int ALIGNMENT_VERTICAL_CENTER = AlignmentInfo.ALIGNMENT_VERTICAL_CENTER;
private static final int ALIGNMENT_DEFAULT = ALIGNMENT_TOP + ALIGNMENT_LEFT;
/**
* Orientation of the layout.
*/
private int orientation;
/**
* Is spacing between contained components enabled. Defaults to false.
*/
private boolean spacing = false;
/**
* Creates a new ordered layout. The order of the layout is
* ORIENTATION_VERTICAL
.
*/
public OrderedLayout() {
orientation = ORIENTATION_VERTICAL;
}
/**
* Create a new ordered layout. The orientation of the layout is given as
* parameters.
*
* @param orientation
* the Orientation of the layout.
*/
public OrderedLayout(int orientation) {
this.orientation = orientation;
}
/**
* Gets the component UIDL tag.
*
* @return the Component UIDL tag as string.
*/
public String getTag() {
return "orderedlayout";
}
/**
* Add a component into this container. The component is added to the right
* or under the previous component.
*
* @param c
* the component to be added.
*/
public void addComponent(Component c) {
components.add(c);
super.addComponent(c);
requestRepaint();
}
/**
* Adds a component into this container. The component is added to the left
* or on top of the other components.
*
* @param c
* the component to be added.
*/
public void addComponentAsFirst(Component c) {
components.addFirst(c);
super.addComponent(c);
requestRepaint();
}
/**
* Adds a component into indexed position in this container.
*
* @param c
* the component to be added.
* @param index
* the Index of the component position. The components
* currently in and after the position are shifted forwards.
*/
public void addComponent(Component c, int index) {
components.add(index, c);
super.addComponent(c);
requestRepaint();
}
/**
* Removes the component from this container.
*
* @param c
* the component to be removed.
*/
public void removeComponent(Component c) {
super.removeComponent(c);
components.remove(c);
componentToAlignment.remove(c);
requestRepaint();
}
/**
* Gets the component container iterator for going trough all the components
* in the container.
*
* @return the Iterator of the components inside the container.
*/
public Iterator getComponentIterator() {
return components.iterator();
}
/**
* Paints the content of this component.
*
* @param target
* the Paint Event.
* @throws PaintException
* if the paint operation failed.
*/
public void paintContent(PaintTarget target) throws PaintException {
super.paintContent(target);
// Adds the attributes: orientation
// note that the default values (b/vertical) are omitted
if (orientation == ORIENTATION_HORIZONTAL) {
target.addAttribute("orientation", "horizontal");
}
// Add spacing attribute (omitted if false)
if (spacing) {
target.addAttribute("spacing", spacing);
}
String[] alignmentsArray = new String[components.size()];
// Adds all items in all the locations
int index = 0;
for (Iterator i = components.iterator(); i.hasNext();) {
Component c = (Component) i.next();
if (c != null) {
// Paint child component UIDL
c.paint(target);
alignmentsArray[index++] = String
.valueOf(getComponentAlignment(c));
}
}
// Add child component alignment info to layout tag
target.addAttribute("alignments", alignmentsArray);
}
/**
* Gets the orientation of the container.
*
* @return the Value of property orientation.
*/
public int getOrientation() {
return orientation;
}
/**
* Set the orientation of the container.
*
* @param orientation
* the New value of property orientation.
*/
public void setOrientation(int orientation) {
// Checks the validity of the argument
if (orientation < ORIENTATION_VERTICAL
|| orientation > ORIENTATION_HORIZONTAL) {
throw new IllegalArgumentException();
}
this.orientation = orientation;
// requestRepaint()
// FIXME remove lines below and uncomment above
// Workaround to bypass IOrderedLayouts limitations (separate classes
// for different orientation + subtreecacing)
Iterator it = getComponentIterator();
while (it.hasNext()) {
Component c = (Component) it.next();
c.requestRepaint();
}
}
/* Documented in superclass */
public void replaceComponent(Component oldComponent, Component newComponent) {
// Gets the locations
int oldLocation = -1;
int newLocation = -1;
int location = 0;
for (Iterator i = components.iterator(); i.hasNext();) {
Component component = (Component) i.next();
if (component == oldComponent) {
oldLocation = location;
}
if (component == newComponent) {
newLocation = location;
}
location++;
}
if (oldLocation == -1) {
addComponent(newComponent);
} else if (newLocation == -1) {
removeComponent(oldComponent);
addComponent(newComponent, oldLocation);
} else {
if (oldLocation > newLocation) {
components.remove(oldComponent);
components.add(newLocation, oldComponent);
components.remove(newComponent);
componentToAlignment.remove(newComponent);
components.add(oldLocation, newComponent);
} else {
components.remove(newComponent);
components.add(oldLocation, newComponent);
components.remove(oldComponent);
componentToAlignment.remove(oldComponent);
components.add(newLocation, oldComponent);
}
requestRepaint();
}
}
/**
* Set alignment for one contained component in this layout. Alignment is
* calculated as a bit mask of the two passed values.
*
* @param childComponent
* the component to align within it's layout cell.
* @param horizontalAlignment
* the horizontal alignment for the child component (left,
* center, right).
* @param verticalAlignment
* the vertical alignment for the child component (top,
* center, bottom).
*/
public void setComponentAlignment(Component childComponent,
int horizontalAlignment, int verticalAlignment) {
componentToAlignment.put(childComponent, new Integer(
horizontalAlignment + verticalAlignment));
}
public int getComponentAlignment(Component childComponent) {
Integer bitMask = (Integer) componentToAlignment.get(childComponent);
if (bitMask != null) {
return bitMask.intValue();
} else {
return ALIGNMENT_DEFAULT;
}
}
/**
* Enable spacing between child components within this layout.
*
*
* NOTE: This will only affect spaces between components, * not also all around spacing of the layout (i.e. do not mix this with HTML * Table elements cellspacing-attribute). Use {@link #setMargin(boolean)} to * add extra space around the layout. *
* * @param enabled */ public void setSpacing(boolean enabled) { spacing = enabled; } /** * * @return true if spacing layout leaves space between components */ public boolean isSpacingEnabled() { return spacing; } }