Removed CoordinateLayout from trunk. This is the first part of #2346

svn changeset:6214/svn branch:trunk
This commit is contained in:
Joonas Lehtinen 2008-12-15 14:50:34 +00:00
parent 9263b41c60
commit c8fc800596
6 changed files with 3 additions and 2420 deletions

View File

@ -1,10 +0,0 @@
/*
* CoordinateLayout
*/
.i-coordinatelayout-margin-values{
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
}

View File

@ -8,7 +8,6 @@ import com.google.gwt.user.client.ui.Widget;
import com.itmill.toolkit.terminal.gwt.client.ui.IAccordion;
import com.itmill.toolkit.terminal.gwt.client.ui.IButton;
import com.itmill.toolkit.terminal.gwt.client.ui.ICheckBox;
import com.itmill.toolkit.terminal.gwt.client.ui.ICoordinateLayout;
import com.itmill.toolkit.terminal.gwt.client.ui.ICustomComponent;
import com.itmill.toolkit.terminal.gwt.client.ui.ICustomLayout;
import com.itmill.toolkit.terminal.gwt.client.ui.IDateFieldCalendar;
@ -132,8 +131,6 @@ public class DefaultWidgetSet implements WidgetSet {
return new IMenuBar();
} else if (IPopupView.class == classType) {
return new IPopupView();
} else if (ICoordinateLayout.class == classType) {
return new ICoordinateLayout();
} else if (IUriFragmentUtility.class == classType) {
return new IUriFragmentUtility();
}
@ -240,8 +237,6 @@ public class DefaultWidgetSet implements WidgetSet {
return IMenuBar.class;
} else if ("popupview".equals(tag)) {
return IPopupView.class;
} else if ("coordinatelayout".equals(tag)) {
return ICoordinateLayout.class;
} else if ("urifragment".equals(tag)) {
return IUriFragmentUtility.class;
}

View File

@ -1,469 +0,0 @@
package com.itmill.toolkit.tests.tickets;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import com.itmill.toolkit.Application;
import com.itmill.toolkit.data.Property.ValueChangeEvent;
import com.itmill.toolkit.data.Property.ValueChangeListener;
import com.itmill.toolkit.data.util.HierarchicalContainer;
import com.itmill.toolkit.data.util.IndexedContainer;
import com.itmill.toolkit.data.validator.StringLengthValidator;
import com.itmill.toolkit.terminal.ThemeResource;
import com.itmill.toolkit.ui.Button;
import com.itmill.toolkit.ui.CheckBox;
import com.itmill.toolkit.ui.Component;
import com.itmill.toolkit.ui.CoordinateLayout;
import com.itmill.toolkit.ui.ExpandLayout;
import com.itmill.toolkit.ui.GridLayout;
import com.itmill.toolkit.ui.Label;
import com.itmill.toolkit.ui.MenuBar;
import com.itmill.toolkit.ui.OrderedLayout;
import com.itmill.toolkit.ui.Panel;
import com.itmill.toolkit.ui.Slider;
import com.itmill.toolkit.ui.Table;
import com.itmill.toolkit.ui.TextField;
import com.itmill.toolkit.ui.Tree;
import com.itmill.toolkit.ui.Window;
import com.itmill.toolkit.ui.CoordinateLayout.Coordinates;
import com.itmill.toolkit.ui.MenuBar.Command;
import com.itmill.toolkit.ui.MenuBar.MenuItem;
import com.itmill.toolkit.ui.Window.CloseEvent;
import com.itmill.toolkit.ui.Window.CloseListener;
public class Ticket1267 extends Application {
ArrayList<Component> componentList;
CoordinateLayout coordinateLayout = new CoordinateLayout();
Window main = new Window("Coordinatelayout demo");
HashMap<Component, Panel> control = new HashMap<Component, Panel>();
ExpandLayout mainLayout = new ExpandLayout();
// Components
MenuBar mainMenu;
Window controlPanel = new Window("Control panel for components");
OrderedLayout ol = new OrderedLayout();
boolean defaultmargins = false;
Application hostApp = this;
Class<Ticket1267> hostClass = Ticket1267.class;
private int numberOfTables;
private IndexedContainer emptyContainer = new IndexedContainer();
private HierarchicalContainer emptyHierarchy = new HierarchicalContainer();
private int numberOfPanels;
private int numberOfTextFields;
private int numberOfTrees;
public void init() {
// Setup container
emptyContainer.addContainerProperty("First Name", String.class, null);
emptyContainer.addContainerProperty("Last Name", String.class, null);
emptyContainer.addContainerProperty("Year", Integer.class, null);
// Setup menubar
mainMenu = getMainMenuBar();
// Setup control panel window
controlPanel.addListener(new CloseListener() {
public void windowClose(CloseEvent e) {
main.removeWindow(e.getWindow());
}
});
// TestField
TextField testField = new TextField("Pixel values");
testField.setImmediate(true);
final Coordinates xy = new Coordinates("0,0");
testField.addListener(new ValueChangeListener() {
public void valueChange(ValueChangeEvent event) {
String str = (String) event.getProperty().getValue();
try {
xy.setCoordinates(str);
} catch (Exception e) {
main.showNotification("Wrong string format", e.toString(),
Window.Notification.TYPE_WARNING_MESSAGE);
return;
}
main.showNotification("Component added to " + xy.toString(),
Window.Notification.TYPE_TRAY_NOTIFICATION);
}
});
coordinateLayout.addComponent(testField, xy);
// Setup coordinatelayout
coordinateLayout.setMargin(defaultmargins);
mainLayout.addComponent(mainMenu);
mainLayout.addComponent(coordinateLayout);
mainLayout.expand(coordinateLayout);
main.setLayout(mainLayout);
setMainWindow(main);
}
private MenuBar getMainMenuBar() {
MenuBar menu = new MenuBar();
MenuItem add = menu.addItem("Add component", null);
MenuItem remove = menu.addItem("Remove component", null);
MenuItem modify = menu.addItem("Modify component", null);
MenuItem cPanel = menu.addItem("Show / hide control panel", null);
cPanel.setCommand(new Command() {
public void menuSelected(MenuItem selectedItem) {
if (main.getChildWindows().contains(controlPanel)) {
main.removeWindow(controlPanel);
} else {
main.addWindow(controlPanel);
}
}
});
final MenuItem margins = menu.addItem("Toggle margins", null);
margins.setCommand(new Command() {
boolean marginsEnabled = defaultmargins;
public void menuSelected(MenuItem selectedItem) {
if (marginsEnabled) {
margins.setIcon(null);
marginsEnabled = false;
coordinateLayout.setMargin(false);
} else {
margins.setIcon(new ThemeResource("icons/16/ok.png"));
marginsEnabled = true;
coordinateLayout.setMargin(true);
}
}
});
try {
add.addItem("Table", new AddCommand(hostClass
.getMethod("getNewTable"), remove, modify));
add.addItem("Panel", new AddCommand(hostClass
.getMethod("getNewPanel"), remove, modify));
add.addItem("TextField", new AddCommand(hostClass
.getMethod("getNewTextField"), remove, modify));
add.addItem("Tree", new AddCommand(hostClass
.getMethod("getNewTree"), remove, modify));
} catch (Exception e) {
e.printStackTrace();
}
return menu;
}
public Table getNewTable() {
Table table = new Table("Table " + numberOfTables++);
table.setContainerDataSource(emptyContainer);
table.setImmediate(true);
table.setIcon(new ThemeResource("icons/16/globe.png"));
return table;
}
public Panel getNewPanel() {
final Panel panel = new Panel("Panel " + numberOfPanels++);
Button addButton = new Button("Add component");
addButton.addListener(new Button.ClickListener() {
int count = 0;
public void buttonClick(Button.ClickEvent event) {
panel.addComponent(new Label("Component nro. " + count++));
}
});
panel.addComponent(addButton);
return panel;
}
public TextField getNewTextField() {
TextField textField = new TextField(
"TextField " + numberOfTextFields++,
"This textfield has a validator");
textField.setImmediate(true);
textField.setIcon(new ThemeResource("icons/16/document-image.png"));
textField.setRequired(true);
textField.addValidator(new StringLengthValidator(
"5 < String.length() < 10", 5, 10, false));
return textField;
}
public Tree getNewTree() {
Tree tree = new Tree("Tree " + numberOfTrees++);
return tree;
}
private class AddCommand implements Command {
private Method addMethod;
private MenuItem removeMenu;
private MenuItem modifyMenu;
public void menuSelected(MenuItem selectedItem) {
Component toAdd = null;
try {
toAdd = (Component) addMethod.invoke(hostApp);
} catch (Exception e) {
e.printStackTrace();
}
String caption = toAdd.getCaption();
Coordinates xy = coordinateLayout.addComponent(toAdd, "50%,50%");
getMainWindow().showNotification(
"Component added to " + xy.toString(),
Window.Notification.TYPE_TRAY_NOTIFICATION);
MenuItem modItem = getModMenuItem(modifyMenu, caption, toAdd);
removeMenu.addItem(caption, new RemoveCommand(toAdd, modItem,
modifyMenu));
controlPanel.addComponent(getControlPanel(toAdd));
}
AddCommand(Method addMethod, MenuItem removeMenu, MenuItem modifyMenu) {
this.addMethod = addMethod;
this.removeMenu = removeMenu;
this.modifyMenu = modifyMenu;
}
}
private class RemoveCommand implements Command {
private Component toRemove;
private MenuItem modifyItem;
private MenuItem modifyMenu;
public RemoveCommand(Component toRemove, MenuBar.MenuItem modifyItem,
MenuItem modifyMenu) {
this.toRemove = toRemove;
this.modifyItem = modifyItem;
this.modifyMenu = modifyMenu;
}
public void menuSelected(MenuItem selectedItem) {
if (coordinateLayout.contains(toRemove)) {
coordinateLayout.removeComponent(toRemove);
MenuItem parent = selectedItem.getParent();
parent.removeChild(selectedItem);
if (modifyItem != null) {
modifyMenu.removeChild(modifyItem);
}
controlPanel.removeComponent(getControlPanel(toRemove));
control.remove(toRemove);
}
}
}
public Panel getControlPanel(final Component c) {
if (control.get(c) == null) {
Panel newPanel = new Panel("Controls for " + c.getCaption());
newPanel.setLayout(new GridLayout(3, 6));
final int[] values = new int[6];
Arrays.fill(values, -1);
final CheckBox[] checkBoxArray = new CheckBox[6];
final Slider[] sliderArray = new Slider[6];
String[] directions = { "Left", "Top", "Width", "Height", "Right",
"Bottom" };
final Label[] labelArray = new Label[6];
for (int i = 0; i < checkBoxArray.length; i++) {
final int j = i;
checkBoxArray[i] = new CheckBox(directions[i]);
sliderArray[i] = new Slider(-1, 100, 1);
labelArray[j] = new Label("-1");
labelArray[j].setEnabled(false);
checkBoxArray[j].setImmediate(true);
sliderArray[j].setImmediate(true);
sliderArray[j].setEnabled(false);
sliderArray[j].setWidth("300px");
checkBoxArray[j].addListener(new ValueChangeListener() {
public void valueChange(ValueChangeEvent event) {
Boolean isChecked = (Boolean) checkBoxArray[j]
.getValue();
if (isChecked.booleanValue()) {
sliderArray[j].setEnabled(true);
labelArray[j].setEnabled(true);
} else {
values[j] = -1;
labelArray[j].setValue(new Integer(values[j]));
sliderArray[j].setEnabled(false);
labelArray[j].setEnabled(false);
CoordinateLayout.Coordinates coords = coordinateLayout
.getCoordinates(c);
coords.setCoordinates(values[0], values[1],
values[2], values[3], values[4], values[5]);
coords.setUnitsPercent(true, true, true, true,
true, true);
}
}
});
sliderArray[j].addListener(new ValueChangeListener() {
public void valueChange(ValueChangeEvent event) {
Double newValue = (Double) event.getProperty()
.getValue();
values[j] = (int) newValue.doubleValue();
CoordinateLayout.Coordinates coords = coordinateLayout
.getCoordinates(c);
coords.setCoordinates(values[0], values[1], values[2],
values[3], values[4], values[5]);
coords.setUnitsPercent(true, true, true, true, true,
true);
labelArray[j].setValue(new Integer(values[j]));
}
});
}
for (int i = 0; i < sliderArray.length; i++) {
newPanel.addComponent(checkBoxArray[i]);
newPanel.addComponent(sliderArray[i]);
newPanel.addComponent(labelArray[i]);
}
control.put(c, newPanel);
return newPanel;
} else {
return control.get(c);
}
}
public MenuBar.MenuItem getModMenuItem(MenuItem parent, String id,
Component c) {
MenuBar.MenuItem item = null;
if (c instanceof Table) {
final Table table = (Table) c;
item = parent.addItem(id, null);
MenuBar.Command addContent = new MenuBar.Command() {
public void menuSelected(MenuItem selectedItem) {
table
.addContainerProperty("First Name", String.class,
null);
table.addContainerProperty("Last Name", String.class, null);
table.addContainerProperty("Year", Integer.class, null);
table.addItem(new Object[] { "Nicolaus", "Copernicus",
new Integer(1473) }, Integer.valueOf(1));
table.addItem(new Object[] { "Tycho", "Brahe",
new Integer(1546) }, Integer.valueOf(2));
table.addItem(new Object[] { "Giordano", "Bruno",
new Integer(1548) }, Integer.valueOf(3));
table.addItem(new Object[] { "Galileo", "Galilei",
new Integer(1564) }, Integer.valueOf(4));
table.addItem(new Object[] { "Johannes", "Kepler",
new Integer(1571) }, Integer.valueOf(5));
table.addItem(new Object[] { "Isaac", "Newton",
new Integer(1643) }, Integer.valueOf(6));
}
};
MenuBar.Command removeContent = new MenuBar.Command() {
public void menuSelected(MenuItem selectedItem) {
table.setContainerDataSource(emptyContainer);
}
};
item.addItem("Add content", addContent);
item.addItem("Remove content", removeContent);
} else if (c instanceof Tree) {
final Tree tree = (Tree) c;
item = parent.addItem(id, null);
MenuBar.Command addContent = new MenuBar.Command() {
public void menuSelected(MenuBar.MenuItem selectedItem) {
final Object[][] planets = new Object[][] {
new Object[] { "Mercury" },
new Object[] { "Venus" },
new Object[] { "Earth", "The Moon" },
new Object[] { "Mars", "Phobos", "Deimos" },
new Object[] { "Jupiter", "Io", "Europa",
"Ganymedes", "Callisto" },
new Object[] { "Saturn", "Titan", "Tethys",
"Dione", "Rhea", "Iapetus" },
new Object[] { "Uranus", "Miranda", "Ariel",
"Umbriel", "Titania", "Oberon" },
new Object[] { "Neptune", "Triton", "Proteus",
"Nereid", "Larissa" } };
/* Add planets as root items in the tree. */
for (int i = 0; i < planets.length; i++) {
String planet = (String) (planets[i][0]);
tree.addItem(planet);
if (planets[i].length == 1) {
/* The planet has no moons so make it a leaf. */
tree.setChildrenAllowed(planet, false);
} else {
/* Add children (moons) under the planets. */
for (int j = 1; j < planets[i].length; j++) {
String moon = (String) planets[i][j];
/* Add the item as a regular item. */
tree.addItem(moon);
/* Set it to be a child. */
tree.setParent(moon, planet);
/* Make the moons look like leaves. */
tree.setChildrenAllowed(moon, false);
}
/* Expand the subtree. */
tree.expandItemsRecursively(planet);
}
}
}
};
MenuBar.Command removeContent = new MenuBar.Command() {
public void menuSelected(MenuBar.MenuItem selectedItem) {
tree.setContainerDataSource(emptyHierarchy);
}
};
item.addItem("Add content", addContent);
item.addItem("Remove content", removeContent);
}
return item;
}
}

View File

@ -10,12 +10,10 @@ import com.itmill.toolkit.data.Container;
import com.itmill.toolkit.data.Item;
import com.itmill.toolkit.data.Property;
import com.itmill.toolkit.data.util.BeanItem;
import com.itmill.toolkit.terminal.Sizeable;
import com.itmill.toolkit.ui.Accordion;
import com.itmill.toolkit.ui.Button;
import com.itmill.toolkit.ui.Component;
import com.itmill.toolkit.ui.ComponentContainer;
import com.itmill.toolkit.ui.CoordinateLayout;
import com.itmill.toolkit.ui.Field;
import com.itmill.toolkit.ui.FieldFactory;
import com.itmill.toolkit.ui.Form;
@ -33,11 +31,11 @@ import com.itmill.toolkit.ui.Button.ClickListener;
public class Ticket2204 extends Application {
private List<RichTextArea> textAreas = new ArrayList<RichTextArea>();
private final List<RichTextArea> textAreas = new ArrayList<RichTextArea>();
private TabSheet ts;
private Map<Component, Component> containerToComponent = new HashMap<Component, Component>();
private final Map<Component, Component> containerToComponent = new HashMap<Component, Component>();
private RichTextArea rta;
private List<Class<? extends Component>> classes = new ArrayList<Class<? extends Component>>();
private final List<Class<? extends Component>> classes = new ArrayList<Class<? extends Component>>();
protected RichTextArea formTextArea;
public void init() {
@ -46,7 +44,6 @@ public class Ticket2204 extends Application {
classes.add(Accordion.class);
classes.add(TabSheet.class);
classes.add(Panel.class);
classes.add(CoordinateLayout.class);
classes.add(SplitPanel.class);
classes.add(Form.class);
@ -121,9 +118,6 @@ public class Ticket2204 extends Application {
// l.setCaption("Filler label");
// cc.addComponent(l);
}
if (c == CoordinateLayout.class) {
((Sizeable) cc).setHeight("100px");
}
if (c == Form.class) {
Form f = (Form) cc;

View File

@ -1,768 +0,0 @@
package com.itmill.toolkit.ui;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.itmill.toolkit.terminal.PaintException;
import com.itmill.toolkit.terminal.PaintTarget;
/**
*
* A layout that enables absolute positioning for its children.
*
*
*/
public class CoordinateLayout extends AbstractLayout {
protected final ArrayList<Component> componentList;
protected final HashMap<Component, Coordinates> componentToCoord;
public static final int LEFT = 0;
public static final int TOP = 1;
public static final int WIDTH = 2;
public static final int HEIGHT = 3;
public static final int RIGHT = 4;
public static final int BOTTOM = 5;
/**
* Creates an empty coordinatelayout. The coordinateLayout is full size by
* default.
*/
public CoordinateLayout() {
super();
componentList = new ArrayList<Component>();
componentToCoord = new HashMap<Component, Coordinates>();
this.setSizeFull();
}
/**
*
* <p>
* Adds a component to the layout at the specified coordinates. The values
* are treated as pixel values by default and for example
* {@link com.itmill.toolkit.ui.CoordinateLayout.Coordinates#setUnitPercent(int, boolean)}
* can be used to set the values as percentage.
* </p>
*
* <p>
* If the value is negative, it is interpreted as automatic (terminal
* decides). Null argument is not permitted and will throw an
* IllegalArgumentException.
* </p>
* <dl>
* <dt><b>Examples:</b></dt>
*
* <dd>
* <code>addComponent(c, 0, 0, -1, -1, -1, -1)</code> to attach to
* upper-left corner and let terminal decide size</dd>
*
* <dd><code>Coordinates c = addComponent(c, 5, 5, 200, 200, -1, -1)</dd>
* <dd>c.setUnitPercent(CoordinateLayout.LEFT, true)</dd>
* <dd>c.setUnitPercent(CoordinateLayout.TOP, true) </code> to attach 5%
* from upper-left corner and define size to 200 x 200 pixels</dd>
*
* <dd>
* <code>addComponent(c, 0, 0, -1, -1, 0, 0)</code> to stretch component to
* cover layout area (attached to all four corners)</dd>
* </dl>
*
*
* @param c
* component to be added
* @param left
* distance of component left from layout left
* @param top
* distance of component top from layout top
* @param width
* component width
* @param height
* component height
* @param right
* distance of component right from layout right
* @param bottom
* distance of component bottom from layout bottom
* @return the coordinates object for the component
*
* @throws IllegalArgumentException
*/
public Coordinates addComponent(Component c, int left, int top, int width,
int height, int right, int bottom) throws IllegalArgumentException {
if (c == null) {
throw new IllegalArgumentException();
}
Coordinates newCoords = new Coordinates(left, top, width, height,
right, bottom);
componentToCoord.put(c, newCoords);
addComponent(c);
return newCoords;
}
/**
* <p>
* Add a component to the specified coordinates. The string format is
* <i>"left[%], top[%] [,width[%], height[%] [,right[%], bottom[%]]]"</i>.
* Null arguments will throw an IllegalArgumentException.
* </p>
*
* <dl>
* <dt><b>Examples for string format:</b></dt>
*
* <dd>
* <code>addComponent(c, "0, 0")</code> to attach to upper-left corner and
* let terminal decide size</dd>
*
* <dd>
* <code>addComponent(c, "5%, 5%, 200, 200")</code> to attach 5% from
* upper-left corner and define size to 200 x 200 pixels</dd>
*
* <dd>
* <code>addComponent(c,"0, 0, -1, -1,0, 0")</code> to stretch component to
* cover coordinateLayout area (attached to all four corners)</dd>
*
* </dl>
*
* @param c
* the component to be added
* @param coordString
* coordinates in the specified string format
* @return the created Coordinates object for the component
*
* @throws IllegalArgumentException
*/
public Coordinates addComponent(Component c, String coordString)
throws IllegalArgumentException {
if (c == null) {
throw new IllegalArgumentException();
}
Coordinates newCoords = new Coordinates(coordString);
componentToCoord.put(c, newCoords);
addComponent(c);
return newCoords;
}
/**
* Adds a component to the layout at the specified coordinates. Null
* arguments are not permitted and will throw an IllegalArgumentException.
*
* @param c
* the component to be added
* @param coord
* the coordinates of the component as a Coordinates object
* @throws IllegalArgument
* Exception
*/
public void addComponent(Component c, CoordinateLayout.Coordinates coord)
throws IllegalArgumentException {
if (c == null || coord == null) {
throw new IllegalArgumentException();
}
componentToCoord.put(c, coord);
addComponent(c);
}
/**
* Sets the coordinates of a child component. Null arguments are not
* permitted and will throw an IllegalArgumentException. In addition, the
* user of this method must make sure that the given component is a child of
* this layout.
*
* @param c
* the target component
* @param left
* distance of component left from layout left
* @param top
* distance of component top from layout top
* @param width
* component width
* @param height
* component height
* @param right
* distance of component right from layout right
* @param bottom
* distance of component bottom from layout bottom
* @throws IllegalArgumentException
*/
public void setCoordinates(Component c, int left, int top, int width,
int height, int right, int bottom) throws IllegalArgumentException {
if (c == null || !componentList.contains(c)) {
throw new IllegalArgumentException();
}
Coordinates coords = (Coordinates) componentToCoord.get(c);
coords.setCoordinates(left, top, width, height, right, bottom);
}
/**
* Sets the coordinates of a child component. Null arguments are not
* permitted and will throw an IllegalArgumentException. In addition, the
* user of this method must make sure that the given component is a child of
* this coordinateLayout.
*
* @param c
* the component thats position is changed
* @param newCoord
* the new coordinates as a Coordinates object
* @throws IllegalArgumentException
*/
public void setCoordinates(Component c,
CoordinateLayout.Coordinates newCoord)
throws IllegalArgumentException {
if (c == null || newCoord == null || !componentList.contains(c)) {
throw new IllegalArgumentException();
}
// Detach old coordinate object from this layout
Coordinates oldCoord = (Coordinates) componentToCoord.remove(c);
oldCoord.removeParentLayout(this);
// Attach new
newCoord.addParentLayout(this);
componentToCoord.put(c, newCoord);
requestRepaint();
}
/**
* This will put the given component at the top of the list.
*
* @param c
* the component to be put to the top
*/
public void sendToTop(Component c) {
componentList.remove(c);
componentList.add(c);
requestRepaint();
}
/**
* This will put the given component at the bottom of the list.
*
* @param c
* the component to be put to the bottom
*/
public void sendToBottom(Component c) {
componentList.remove(c);
componentList.add(0, c);
requestRepaint();
}
/**
* If a component is added with this method the component is added to the
* top-left corner of the layout. The coordinates can later be accessed via
* {@link CoordinateLayout#getCoordinates(Component)}
*
* @param c
* the component to be added
* @throws IllegalArgument
* Exception
*
* @see com.itmill.toolkit.ui.AbstractComponentContainer#addComponent(com.itmill.toolkit.ui.Component)
*/
public void addComponent(Component c) throws IllegalArgumentException {
if (c == null) {
throw new IllegalArgumentException();
}
componentList.add(c);
// Someone might call this outside this object
if (componentToCoord.get(c) == null) {
componentToCoord.put(c, new Coordinates(0, 0, -1, -1, -1, -1));
}
super.addComponent(c);
requestRepaint();
((Coordinates) componentToCoord.get(c)).addParentLayout(this);
}
/**
* Removes the component from the coordinateLayout. Method will throw
* IllegalArgumentException if the given component is not a child of this
* layout.
*
* @param c
* the component to be removed
* @throws IllegalArgumentException
*
* @see com.itmill.toolkit.ui.AbstractComponentContainer#removeComponent(com.itmill.toolkit.ui.Component)
*/
public void removeComponent(Component c) throws IllegalArgumentException {
if (c == null || !componentList.contains(c)) {
throw new IllegalArgumentException();
}
((Coordinates) componentToCoord.get(c)).removeParentLayout(this);
super.removeComponent(c);
componentList.remove(c);
componentToCoord.remove(c);
requestRepaint();
}
/**
* Replaces a child component with a new one. The new component uses the
* same coordinates as the previous component. If the arguments are null or
* the component is not a child of this layout IllegalArgumentException is
* thrown.
*
* @param c1
* the existing child component
* @param c2
* the new component
*
* @throws IllegalArgumentException
*
* @see com.itmill.toolkit.ui.ComponentContainer#replaceComponent(com.itmill.toolkit.ui.Component,
* com.itmill.toolkit.ui.Component)
*/
public void replaceComponent(Component c1, Component c2) {
if (c1 == null || c2 == null || !componentList.contains(c1)) {
throw new IllegalArgumentException();
}
componentList.set(componentList.indexOf(c1), c2);
requestRepaint();
}
/**
* Get the coordinates for a given component in this layout
*
* @param c
* @return the Coordinates object for the given component
* @throws IllegalArgumentException
* thrown if component is not in this coordinateLayout
*/
public Coordinates getCoordinates(Component c)
throws IllegalArgumentException {
if (c == null || componentToCoord.get(c) == null) {
throw new IllegalArgumentException();
}
return (Coordinates) componentToCoord.get(c);
}
/**
* @see com.itmill.toolkit.ui.ComponentContainer#getComponentIterator()
*/
public Iterator<Component> getComponentIterator() {
return componentList.iterator();
}
/**
* Returns the iterator for the coordinates of the child components in this
* layout.
*
* @return the iterator for the coordinate list
*/
public Iterator<Coordinates> getComponentCoordinateIterator() {
return componentToCoord.values().iterator();
}
/**
* Check if this layout has components.
*
* @return true if this coordinateLayout has children, false otherwise
*/
public boolean hasComponents() {
return componentList.isEmpty();
}
/**
* Check if a given component is in this layout
*
* @param c
* @return true if the component is in this layout, false otherwise
*/
public boolean contains(Component c) {
return componentList.contains(c);
}
/**
* Get child component by index.
*
* @param index
* must be index >= 0 and index < size() -1
* @return the child component
* @throws IllegalArgumentException
* if given index is illegal
*/
public Component getComponentByIndex(int index)
throws IllegalArgumentException {
if (index < 0 || index > componentList.size() - 1) {
throw new IllegalArgumentException("Illegal index");
}
return (Component) componentList.get(index);
}
/**
* Returns the number of child components.
*
* @return number of children
*/
public int size() {
return componentList.size();
}
/*
* (non-Javadoc)
*
* @see com.itmill.toolkit.ui.AbstractLayout#getTag()
*/
public String getTag() {
return "coordinatelayout";
}
/*
* (non-Javadoc)
*
* @see
* com.itmill.toolkit.ui.AbstractLayout#paintContent(com.itmill.toolkit.
* terminal.PaintTarget)
*/
public void paintContent(PaintTarget target) throws PaintException {
// Superclass writes any common attributes in the paint target.
super.paintContent(target);
for (Iterator<Component> componentIterator = getComponentIterator(); componentIterator
.hasNext();) {
Component component = (Component) componentIterator.next();
Coordinates coords = (Coordinates) componentToCoord.get(component);
target.startTag("component");
target.addAttribute("position", coords.toString());
component.paint(target);
target.endTag("component");
}// for
}// paintContent
/**
*
* This class is used as a container for the coordinates used by
* CoordinateLayout. When attached to a CoordinateLayout object, changes to
* this object are reflected on the layout.
*
*/
public static class Coordinates {
// Length of the property arrays
protected static final int NUMBEROFPROPERTIES = 6;
// The actual coordinates
protected final int[] properties;
// These help to decipher the coordinates
protected final boolean[] isUnitPercent;
// Host layout(s)
protected final ArrayList<CoordinateLayout> listeners = new ArrayList<CoordinateLayout>(
1);
/**
* Creates a new Coordinates object with the specified values. If the
* user does not wish to specify a value, -1 can be used to let the
* terminal decide the value.
*
* The values are treated as absolute. You can change them to be
* relative with setUnitsPercent or setAllUnitsPercent.
*
* @param top
* distance of component top from coordinateLayout top
* @param right
* distance of component right from coordinateLayout right
* @param bottom
* distance of component bottom from coordinateLayout bottom
* @param left
* distance of component left from coordinateLayout left
* @param width
* component width
* @param height
* component height
*
* @throws NumberFormatException
*/
public Coordinates(int left, int top, int width, int height, int right,
int bottom) throws IllegalArgumentException {
properties = new int[NUMBEROFPROPERTIES];
isUnitPercent = new boolean[NUMBEROFPROPERTIES];
properties[LEFT] = left;
properties[TOP] = top;
properties[WIDTH] = width;
properties[HEIGHT] = height;
properties[RIGHT] = right;
properties[BOTTOM] = bottom;
for (int i = 0; i < NUMBEROFPROPERTIES; i++) {
if (properties[i] < -1) {
throw new IllegalArgumentException(
"Illegal coordinate value " + properties[i]);
}
}
}
/**
* Create a new Coordinates object with the given value string.
*
* @param coordinateString
* @throws IllegalArgumentException
* @see com.itmill.toolkit.ui.CoordinateLayout#addComponent(Component,
* String)
*/
public Coordinates(String coordinateString)
throws IllegalArgumentException {
properties = new int[NUMBEROFPROPERTIES];
isUnitPercent = new boolean[NUMBEROFPROPERTIES];
Arrays.fill(properties, -1);
setValuesFromString(coordinateString);
}
/**
* Set unit of the given argument to be percentage. Initially all are
* false.
*
* @param top
* @param right
* @param bottom
* @param left
* @param width
* @param height
*/
public void setUnitsPercent(boolean left, boolean top, boolean width,
boolean height, boolean right, boolean bottom) {
isUnitPercent[TOP] = top;
isUnitPercent[LEFT] = left;
isUnitPercent[WIDTH] = width;
isUnitPercent[HEIGHT] = height;
isUnitPercent[RIGHT] = right;
isUnitPercent[BOTTOM] = bottom;
notifyParents();
}
/**
* Set if a property should be treated as a percentage value.
*
* @param valueId
* either CoordinateLayout.TOP, CoordinateLayout.RIGHT,
* CoordinateLayout.BOTTOM, CoordinateLayout.LEFT,
* CoordinateLayout.WIDTH or CoordinateLayout.HEIGHT
* @param isPercent
* true if the value should be treated as a percentage, false
* otherwise
*/
public void setUnitPercent(int valueId, boolean isPercent) {
isUnitPercent[valueId] = isPercent;
notifyParents();
}
/**
* Set if the values should be treated as percentage.
*
* @param value
* true if all the values should be treated as percentage,
* false if all the values should in treated as abslute pixel
* values
*/
public void setAllUnitsPercent(boolean value) {
java.util.Arrays.fill(isUnitPercent, value);
notifyParents();
}
/**
* Set a value for a direction.
*
* @param direction
* either CoordinateLayout.TOP, CoordinateLayout.RIGHT,
* CoordinateLayout.BOTTOM, CoordinateLayout.LEFT,
* CoordinateLayout.WIDTH or CoordinateLayout.HEIGHT
* @value the value to be set
*/
public void setCoordinate(int direction, int value) {
properties[direction] = value;
notifyParents();
}
/**
* Set coordinates for this object.
*
* @param top
* @param right
* @param bottom
* @param left
*/
public void setCoordinates(int left, int top, int width, int height,
int right, int bottom) {
properties[LEFT] = left;
properties[TOP] = top;
properties[WIDTH] = width;
properties[HEIGHT] = height;
properties[RIGHT] = right;
properties[BOTTOM] = bottom;
for (int i = 0; i < NUMBEROFPROPERTIES; i++) {
if (properties[i] < -1) {
throw new IllegalArgumentException(
"Illegal coordinate value " + properties[i]);
}
}
notifyParents();
}
/**
* Set the values in string format. For reference, see
* {@link CoordinateLayout#addComponent(Component, String)}
*
* @param coordinateString
* @throws IllegalArgumentException
*/
public void setCoordinates(String coordinateString)
throws IllegalArgumentException {
setValuesFromString(coordinateString);
notifyParents();
}
/**
* Returns the coordinates for this object.
*
* @param direction
* either CoordinateLayout.TOP, CoordinateLayout.RIGHT,
* CoordinateLayout.BOTTOM, CoordinateLayout.LEFT,
* CoordinateLayout.WIDTH or CoordinateLayout.HEIGHT
* @return coordinates for the given direction
*/
public int getCoordinate(int direction) {
return properties[direction];
}
/**
* Check if a given value is a percentage value. The default is false.
*
* @param value
* either CoordinateLayout.TOP, CoordinateLayout.RIGHT,
* CoordinateLayout.BOTTOM, CoordinateLayout.LEFT,
* CoordinateLayout.WIDTH or CoordinateLayout.HEIGHT
*
* @return true if the given value has percentages as its unit, false
* otherwise
*/
public boolean isValuePercent(int value) {
return isUnitPercent[value];
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
public String toString() {
StringBuffer returnString = new StringBuffer();
for (int i = 0; i < properties.length; i++) {
returnString.append(properties[i]);
if (isUnitPercent[i]) {
returnString.append("%");
}
if (i != properties.length - 1) {
returnString.append(",");
}
}
return returnString.toString();
}
/*
* Parses the string to integer values
*/
protected void setValuesFromString(String coordinateString) {
int[] newProperties = new int[6];
boolean[] newPercent = new boolean[6];
resetContents(newProperties, newPercent);
String coordStringArray[] = coordinateString.split(",");
if (coordStringArray.length > 6) {
throw new IllegalArgumentException(
"Incorrect string syntax: too many arguments");
}
Pattern numberPattern = Pattern.compile("[-]??\\d+");
String percentRegex = ".*%.*";
Matcher matcher = null;
try {
for (int i = 0; i < coordStringArray.length; i++) {
matcher = numberPattern.matcher(coordStringArray[i].trim());
if (matcher.find()) {
newProperties[i] = Integer.parseInt(matcher.group());
newPercent[i] = coordStringArray[i]
.matches(percentRegex);
} else {
throw new IllegalArgumentException(
"Error parsing number: " + coordStringArray[i]);
}
}
} catch (IllegalArgumentException e) {
throw e;
} catch (Exception e) {
throw new IllegalArgumentException("Error parsing string: "
+ e.toString());
}
// Only set new values if there were no parsing errors
resetContents(properties, isUnitPercent);
System.arraycopy(newProperties, 0, properties, 0,
NUMBEROFPROPERTIES);
System.arraycopy(newPercent, 0, isUnitPercent, 0,
NUMBEROFPROPERTIES);
}
/*
* Reset coordinate properties. Does not notify listeners
*/
protected void resetContents(int[] prop, boolean[] perc) {
Arrays.fill(prop, -1);
Arrays.fill(perc, false);
}
/*
* These methods ensure that changes to the coordinate objects are
* reflected to the host layout
*/
protected void addParentLayout(CoordinateLayout listener) {
listeners.add(listener);
}
protected void removeParentLayout(CoordinateLayout listener) {
listeners.remove(listener);
}
protected void notifyParents() {
for (int i = 0; i < listeners.size(); i++) {
((CoordinateLayout) listeners.get(i)).requestRepaint();
}
}
}// class Coordinates
}// class CoordinateLayout