summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Koivuviita <jouni.koivuviita@itmill.com>2009-04-09 10:37:39 +0000
committerJouni Koivuviita <jouni.koivuviita@itmill.com>2009-04-09 10:37:39 +0000
commit7e676a5e38016e70021b3a48e5e6e263783a5383 (patch)
treee0fbb10d845a52b05197b173107b8697a72ee84d
parent9e5e8f677bd01d53167c4587b5e29f0a8438e7b4 (diff)
downloadvaadin-framework-7e676a5e38016e70021b3a48e5e6e263783a5383.tar.gz
vaadin-framework-7e676a5e38016e70021b3a48e5e6e263783a5383.zip
Merges from 6.0 branch.
svn changeset:7375/svn branch:theme_2009_03
-rw-r--r--WebContent/ITMILL/themes/default/absolutelayout/absolutelayout.css4
-rw-r--r--WebContent/ITMILL/themes/tests-tickets/styles.css12
-rw-r--r--src/com/itmill/toolkit/data/Validator.java3
-rw-r--r--src/com/itmill/toolkit/demo/sampler/features/commons/ValidationExample.java8
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java5
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/client/ui/IAbsoluteLayout.java320
-rw-r--r--src/com/itmill/toolkit/tests/layouts/TestAbsoluteLayout.java54
-rw-r--r--src/com/itmill/toolkit/ui/AbsoluteLayout.java210
-rw-r--r--src/com/itmill/toolkit/ui/AbstractField.java14
9 files changed, 618 insertions, 12 deletions
diff --git a/WebContent/ITMILL/themes/default/absolutelayout/absolutelayout.css b/WebContent/ITMILL/themes/default/absolutelayout/absolutelayout.css
new file mode 100644
index 0000000000..e77e380688
--- /dev/null
+++ b/WebContent/ITMILL/themes/default/absolutelayout/absolutelayout.css
@@ -0,0 +1,4 @@
+.i-absolutelayout-wrapper {
+ position: absolute;
+ overflow:hidden;
+}
diff --git a/WebContent/ITMILL/themes/tests-tickets/styles.css b/WebContent/ITMILL/themes/tests-tickets/styles.css
index 225bbd6d1d..2c2b359ed9 100644
--- a/WebContent/ITMILL/themes/tests-tickets/styles.css
+++ b/WebContent/ITMILL/themes/tests-tickets/styles.css
@@ -1276,4 +1276,16 @@ padding:2px;
.i-button-nowraplink span {
white-space: normal;
}
+
+.cyan {
+ background:cyan;
+}
+.yellow {
+ background:yellow;
+}
+
+.green {
+ background:green;
+}
+ \ No newline at end of file
diff --git a/src/com/itmill/toolkit/data/Validator.java b/src/com/itmill/toolkit/data/Validator.java
index 0e09e3de6b..d0094914ed 100644
--- a/src/com/itmill/toolkit/data/Validator.java
+++ b/src/com/itmill/toolkit/data/Validator.java
@@ -17,6 +17,9 @@ import com.itmill.toolkit.terminal.PaintTarget;
* {@link Validator.InvalidValueException} if the given value is not valid by
* its standards.
*
+ * Validators should not have side effects on other objects as they can be
+ * called from Paintable.paint().
+ *
* @author IT Mill Ltd.
* @version
* @VERSION@
diff --git a/src/com/itmill/toolkit/demo/sampler/features/commons/ValidationExample.java b/src/com/itmill/toolkit/demo/sampler/features/commons/ValidationExample.java
index 75bacd5b10..19444045a9 100644
--- a/src/com/itmill/toolkit/demo/sampler/features/commons/ValidationExample.java
+++ b/src/com/itmill/toolkit/demo/sampler/features/commons/ValidationExample.java
@@ -46,17 +46,15 @@ public class ValidationExample extends VerticalLayout {
throw new Validator.InvalidValueException("Username "
+ value + " already in use");
}
- usernames.add(value);
}
});
username.addListener(new ValueChangeListener() {
public void valueChange(ValueChangeEvent event) {
TextField tf = (TextField) event.getProperty();
tf.validate();
- if (tf.isValid()) {
- addComponent(new Label("Added " + tf.getValue()
- + " to usernames"));
- }
+ usernames.add(tf.getValue());
+ addComponent(new Label("Added " + tf.getValue()
+ + " to usernames"));
}
});
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java b/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java
index e81f5fff47..0bc849affa 100644
--- a/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java
+++ b/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java
@@ -5,6 +5,7 @@
package com.itmill.toolkit.terminal.gwt.client;
import com.google.gwt.user.client.ui.Widget;
+import com.itmill.toolkit.terminal.gwt.client.ui.IAbsoluteLayout;
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;
@@ -139,6 +140,8 @@ public class DefaultWidgetSet implements WidgetSet {
return new IPopupView();
} else if (IUriFragmentUtility.class == classType) {
return new IUriFragmentUtility();
+ } else if (IAbsoluteLayout.class == classType) {
+ return new IAbsoluteLayout();
}
return new IUnknownComponent();
@@ -249,6 +252,8 @@ public class DefaultWidgetSet implements WidgetSet {
return IPopupView.class;
} else if ("urifragment".equals(tag)) {
return IUriFragmentUtility.class;
+ } else if (IAbsoluteLayout.TAGNAME.equals(tag)) {
+ return IAbsoluteLayout.class;
}
return IUnknownComponent.class;
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IAbsoluteLayout.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IAbsoluteLayout.java
new file mode 100644
index 0000000000..fc1f14cb83
--- /dev/null
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IAbsoluteLayout.java
@@ -0,0 +1,320 @@
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import com.google.gwt.dom.client.DivElement;
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Style;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.ComplexPanel;
+import com.google.gwt.user.client.ui.SimplePanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
+import com.itmill.toolkit.terminal.gwt.client.BrowserInfo;
+import com.itmill.toolkit.terminal.gwt.client.Container;
+import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.RenderSpace;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
+
+public class IAbsoluteLayout extends ComplexPanel implements Container {
+
+ /** Tag name for widget creation */
+ public static final String TAGNAME = "absolutelayout";
+
+ /** Class name, prefix in styling */
+ public static final String CLASSNAME = "i-absolutelayout";
+
+ private DivElement marginElement;
+
+ private Element canvas;
+
+ private int excessPixelsHorizontal;
+
+ private int excessPixelsVertical;
+
+ private Object previousStyleName;
+
+ private Map<String, AbsoluteWrapper> pidToComponentWrappper = new HashMap<String, AbsoluteWrapper>();
+
+ private ApplicationConnection client;
+
+ private boolean rendering;
+
+ public IAbsoluteLayout() {
+ setElement(Document.get().createDivElement());
+ setStyleName(CLASSNAME);
+ marginElement = Document.get().createDivElement();
+ canvas = DOM.createDiv();
+ canvas.getStyle().setProperty("position", "relative");
+ marginElement.appendChild(canvas);
+ getElement().appendChild(marginElement);
+ }
+
+ public RenderSpace getAllocatedSpace(Widget child) {
+ // TODO needs some special handling for components with only on edge
+ // horizontally or vertically defined
+ AbsoluteWrapper wrapper = (AbsoluteWrapper) child.getParent();
+ int w;
+ if (wrapper.left != null && wrapper.right != null) {
+ w = wrapper.getOffsetWidth();
+ } else if (wrapper.right != null) {
+ // left == null
+ // available width == right edge == offsetleft + width
+ w = wrapper.getOffsetWidth() + wrapper.getElement().getOffsetLeft();
+ } else {
+ // left != null && right == null || left == null &&
+ // right == null
+ // available width == canvas width - offset left
+ w = canvas.getOffsetWidth() - wrapper.getElement().getOffsetLeft();
+ }
+ int h;
+ if (wrapper.top != null && wrapper.bottom != null) {
+ h = wrapper.getOffsetHeight();
+ } else if (wrapper.bottom != null) {
+ // top not defined, available space 0... bottom of wrapper
+ h = wrapper.getElement().getOffsetTop() + wrapper.getOffsetHeight();
+ } else {
+ // top defined or both undefined, available space == canvas - top
+ h = canvas.getOffsetHeight() - wrapper.getElement().getOffsetTop();
+ }
+
+ return new RenderSpace(w, h);
+ }
+
+ public boolean hasChildComponent(Widget component) {
+ for (Iterator<Entry<String, AbsoluteWrapper>> iterator = pidToComponentWrappper
+ .entrySet().iterator(); iterator.hasNext();) {
+ if (iterator.next().getValue().paintable == component) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
+ for (Widget wrapper : getChildren()) {
+ AbsoluteWrapper w = (AbsoluteWrapper) wrapper;
+ if (w.getWidget() == oldComponent) {
+ w.setWidget(newComponent);
+ return;
+ }
+ }
+ }
+
+ public boolean requestLayout(Set<Paintable> children) {
+ // component inside an absolute panel never affects parent nor the
+ // layout
+ return true;
+ }
+
+ public void updateCaption(Paintable component, UIDL uidl) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ rendering = true;
+ this.client = client;
+ // TODO margin handling
+ if (client.updateComponent(this, uidl, true)) {
+ rendering = false;
+ return;
+ }
+
+ HashSet<String> unrenderedPids = new HashSet<String>(
+ pidToComponentWrappper.keySet());
+
+ for (Iterator<UIDL> childIterator = uidl.getChildIterator(); childIterator
+ .hasNext();) {
+ UIDL cc = childIterator.next();
+ UIDL componentUIDL = cc.getChildUIDL(0);
+ unrenderedPids.remove(componentUIDL.getId());
+ getWrapper(client, componentUIDL).updateFromUIDL(cc);
+ }
+
+ for (String pid : unrenderedPids) {
+ AbsoluteWrapper absoluteWrapper = pidToComponentWrappper.get(pid);
+ pidToComponentWrappper.remove(pid);
+ absoluteWrapper.destroy();
+ }
+ rendering = false;
+ }
+
+ private AbsoluteWrapper getWrapper(ApplicationConnection client,
+ UIDL componentUIDL) {
+ AbsoluteWrapper wrapper = pidToComponentWrappper.get(componentUIDL
+ .getId());
+ if (wrapper == null) {
+ wrapper = new AbsoluteWrapper(client.getPaintable(componentUIDL));
+ pidToComponentWrappper.put(componentUIDL.getId(), wrapper);
+ add(wrapper);
+ }
+ return wrapper;
+
+ }
+
+ @Override
+ public void add(Widget child) {
+ super.add(child, canvas);
+ }
+
+ @Override
+ public void setStyleName(String style) {
+ super.setStyleName(style);
+ if (previousStyleName == null || !previousStyleName.equals(style)) {
+ excessPixelsHorizontal = -1;
+ excessPixelsVertical = -1;
+ }
+ }
+
+ @Override
+ public void setWidth(String width) {
+ super.setWidth(width);
+ // TODO do this so that canvas gets the sized properly (the area
+ // inside marginals)
+ canvas.getStyle().setProperty("width", width);
+
+ if (!rendering && BrowserInfo.get().isIE6()) {
+ relayoutWrappersForIe6();
+ }
+ }
+
+ @Override
+ public void setHeight(String height) {
+ super.setHeight(height);
+ // TODO do this so that canvas gets the sized properly (the area
+ // inside marginals)
+ canvas.getStyle().setProperty("height", height);
+
+ if (!rendering && BrowserInfo.get().isIE6()) {
+ relayoutWrappersForIe6();
+ }
+ }
+
+ private void relayoutWrappersForIe6() {
+ for (Widget wrapper : getChildren()) {
+ ((AbsoluteWrapper) wrapper).ie6Layout();
+ }
+ }
+
+ public class AbsoluteWrapper extends SimplePanel {
+ private String css;
+ private String left;
+ private String top;
+ private String right;
+ private String bottom;
+ private String zIndex;
+
+ private Paintable paintable;
+
+ public AbsoluteWrapper(Paintable paintable) {
+ this.paintable = paintable;
+ setStyleName(CLASSNAME + "-wrapper");
+ }
+
+ public void destroy() {
+ client.unregisterPaintable(paintable);
+ removeFromParent();
+ }
+
+ public void updateFromUIDL(UIDL componentUIDL) {
+ setPosition(componentUIDL.getStringAttribute("css"));
+ if (getWidget() != paintable) {
+ setWidget((Widget) paintable);
+ }
+ paintable.updateFromUIDL(componentUIDL.getChildUIDL(0), client);
+ }
+
+ public void setPosition(String stringAttribute) {
+ if (css == null || !css.equals(stringAttribute)) {
+ css = stringAttribute;
+ top = right = bottom = left = zIndex = null;
+ if (!css.equals("")) {
+ String[] properties = css.split(";");
+ for (int i = 0; i < properties.length; i++) {
+ String[] keyValue = properties[i].split(":");
+ if (keyValue[0].equals("left")) {
+ left = keyValue[1];
+ } else if (keyValue[0].equals("top")) {
+ top = keyValue[1];
+ } else if (keyValue[0].equals("right")) {
+ right = keyValue[1];
+ } else if (keyValue[0].equals("bottom")) {
+ bottom = keyValue[1];
+ } else if (keyValue[0].equals("z-index")) {
+ zIndex = keyValue[1];
+ }
+ }
+ }
+ // ensure ne values
+ Style style = getElement().getStyle();
+ style.setProperty("zIndex", zIndex);
+ style.setProperty("top", top);
+ style.setProperty("left", left);
+ style.setProperty("right", right);
+ style.setProperty("bottom", bottom);
+
+ if (BrowserInfo.get().isIE6()) {
+ ie6Layout();
+ }
+ }
+
+ }
+
+ private void ie6Layout() {
+ // special handling for IE6 is needed, it does not support
+ // setting both left/right or top/bottom
+ Style style = getElement().getStyle();
+ if (bottom != null && top != null) {
+ // define height for wrapper to simulate bottom property
+ int bottompixels = measureForIE6(bottom);
+ ApplicationConnection.getConsole().log("ALB" + bottompixels);
+ int height = canvas.getOffsetHeight() - bottompixels
+ - getElement().getOffsetTop();
+ ApplicationConnection.getConsole().log("ALB" + height);
+ if (height < 0) {
+ height = 0;
+ }
+ style.setPropertyPx("height", height);
+ } else {
+ // reset possibly existing value
+ style.setProperty("height", "");
+ }
+ if (left != null && right != null) {
+ // define width for wrapper to simulate right property
+ int rightPixels = measureForIE6(right);
+ ApplicationConnection.getConsole().log("ALR" + rightPixels);
+ int width = canvas.getOffsetWidth() - rightPixels
+ - getElement().getOffsetWidth();
+ ApplicationConnection.getConsole().log("ALR" + width);
+ if (width < 0) {
+ width = 0;
+ }
+ style.setPropertyPx("width", width);
+ } else {
+ // reset possibly existing value
+ style.setProperty("width", "");
+ }
+ }
+
+ }
+
+ private Element measureElement;
+
+ private int measureForIE6(String cssLength) {
+ if (measureElement == null) {
+ measureElement = DOM.createDiv();
+ measureElement.getStyle().setProperty("position", "absolute");
+ canvas.appendChild(measureElement);
+ }
+ measureElement.getStyle().setProperty("width", cssLength);
+ return measureElement.getOffsetWidth();
+ }
+
+}
diff --git a/src/com/itmill/toolkit/tests/layouts/TestAbsoluteLayout.java b/src/com/itmill/toolkit/tests/layouts/TestAbsoluteLayout.java
new file mode 100644
index 0000000000..6631df2963
--- /dev/null
+++ b/src/com/itmill/toolkit/tests/layouts/TestAbsoluteLayout.java
@@ -0,0 +1,54 @@
+package com.itmill.toolkit.tests.layouts;
+
+import com.itmill.toolkit.tests.components.TestBase;
+import com.itmill.toolkit.ui.AbsoluteLayout;
+import com.itmill.toolkit.ui.Button;
+import com.itmill.toolkit.ui.Label;
+
+public class TestAbsoluteLayout extends TestBase {
+
+ @Override
+ protected String getDescription() {
+ return "This is absolute layout tester.";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return null;
+ }
+
+ @Override
+ protected void setup() {
+ AbsoluteLayout layout = new AbsoluteLayout();
+ setTheme("tests-tickets");
+ layout.setStyleName("cyan");
+
+ layout.addComponent(new Label("Hello World"));
+
+ Button button = new Button("Centered button,z-index:10;");
+ button.setSizeFull();
+ layout.addComponent(button,
+ "top:40%;bottom:40%;right:20%;left:20%;z-index:10;");
+
+ Label label = new Label(
+ "Exotic positioned label. Fullsize, top:100px; left:2cm; right: 3.5in; bottom:12.12mm ");
+ label.setStyleName("yellow");
+ label.setSizeFull();
+ layout.addComponent(label,
+ "top:100px; left:2cm; right: 3.5in; bottom:12.12mm");
+
+ label = new Label("fullize, bottom:80%;left:80%;");
+ label.setStyleName("green");
+ label.setSizeFull();
+ layout.addComponent(label, "bottom:80%;left:80%;");
+
+ label = new Label("bottomright");
+ label.setSizeUndefined();
+ label.setStyleName("green");
+ layout.addComponent(label, "bottom:0px; right:0px;");
+
+ getLayout().setSizeFull();
+ getLayout().addComponent(layout);
+
+ }
+}
diff --git a/src/com/itmill/toolkit/ui/AbsoluteLayout.java b/src/com/itmill/toolkit/ui/AbsoluteLayout.java
new file mode 100644
index 0000000000..61a12bb76f
--- /dev/null
+++ b/src/com/itmill/toolkit/ui/AbsoluteLayout.java
@@ -0,0 +1,210 @@
+package com.itmill.toolkit.ui;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+
+import com.itmill.toolkit.terminal.PaintException;
+import com.itmill.toolkit.terminal.PaintTarget;
+import com.itmill.toolkit.terminal.gwt.client.ui.IAbsoluteLayout;
+
+/**
+ * AbsoluteLayout is a layout implementation that mimics html absolute
+ * positioning.
+ *
+ */
+public class AbsoluteLayout extends AbstractLayout {
+
+ private Collection<Component> components = new HashSet<Component>();
+ private Map<Component, ComponentPosition> componentToCoordinates = new HashMap<Component, ComponentPosition>();
+
+ public AbsoluteLayout() {
+ setSizeFull();
+ }
+
+ @Override
+ public String getTag() {
+ return IAbsoluteLayout.TAGNAME;
+ }
+
+ public Iterator<Component> getComponentIterator() {
+ return components.iterator();
+ }
+
+ public void replaceComponent(Component oldComponent, Component newComponent) {
+ ComponentPosition position = getPosition(oldComponent);
+ removeComponent(oldComponent);
+ addComponent(newComponent);
+ componentToCoordinates.put(newComponent, position);
+ }
+
+ @Override
+ public void addComponent(Component c) {
+ components.add(c);
+ super.addComponent(c);
+ }
+
+ @Override
+ public void removeComponent(Component c) {
+ components.remove(c);
+ super.removeComponent(c);
+ }
+
+ public void addComponent(Component c, String cssPosition) {
+ addComponent(c);
+ getPosition(c).setCSSString(cssPosition);
+ }
+
+ public ComponentPosition getPosition(Component component) {
+ if (componentToCoordinates.containsKey(component)) {
+ return componentToCoordinates.get(component);
+ } else {
+ ComponentPosition coords = new ComponentPosition();
+ componentToCoordinates.put(component, coords);
+ return coords;
+ }
+ }
+
+ /**
+ * TODO symmetric getters and setters for fields to make this simpler to use
+ * in generic java tools
+ *
+ */
+ public class ComponentPosition {
+
+ private int zIndex = -1;
+ private float top = -1;
+ private float right = -1;
+ private float bottom = -1;
+ private float left = -1;
+
+ private int topUnits;
+ private int rightUnits;
+ private int bottomUnits;
+ private int leftUnits;
+
+ /**
+ * Sets the position attributes using CSS syntax. Example usage:
+ *
+ * <code><pre>
+ * setCSSString("top:10px;left:20%;z-index:16;");
+ * </pre></code>
+ *
+ * @param css
+ */
+ public void setCSSString(String css) {
+ String[] cssProperties = css.split(";");
+ for (int i = 0; i < cssProperties.length; i++) {
+ String[] keyValuePair = cssProperties[i].split(":");
+ String key = keyValuePair[0].trim();
+ if (key.equals("z-index")) {
+ zIndex = Integer.parseInt(keyValuePair[1]);
+ } else {
+ String value = keyValuePair[1].trim();
+ String unit = value.replaceAll("[0-9\\.]+", "");
+ if (!unit.equals("")) {
+ value = value.substring(0, value.indexOf(unit)).trim();
+ }
+ float v = Float.parseFloat(value);
+ int unitInt = parseCssUnit(unit);
+ if (key.equals("top")) {
+ top = v;
+ topUnits = unitInt;
+ } else if (key.equals("right")) {
+ right = v;
+ rightUnits = unitInt;
+ } else if (key.equals("bottom")) {
+ bottom = v;
+ bottomUnits = unitInt;
+ } else if (key.equals("left")) {
+ left = v;
+ leftUnits = unitInt;
+ }
+ }
+ }
+ requestRepaint();
+ }
+
+ private int parseCssUnit(String string) {
+ for (int i = 0; i < UNIT_SYMBOLS.length; i++) {
+ if (UNIT_SYMBOLS[i].equals(string)) {
+ return i;
+ }
+ }
+ return 0; // defaults to px (eg. top:0;)
+ }
+
+ public String getCSSString() {
+ String s = "";
+ if (top >= 0) {
+ s += "top:" + top + UNIT_SYMBOLS[topUnits] + ";";
+ }
+ if (right >= 0) {
+ s += "right:" + right + UNIT_SYMBOLS[rightUnits] + ";";
+ }
+ if (bottom >= 0) {
+ s += "bottom:" + bottom + UNIT_SYMBOLS[bottomUnits] + ";";
+ }
+ if (left >= 0) {
+ s += "left:" + left + UNIT_SYMBOLS[leftUnits] + ";";
+ }
+ if (zIndex >= 0) {
+ s += "z-index:" + zIndex + ";";
+ }
+ return s;
+ }
+
+ public void setTop(float topValue, int topUnits) {
+ validateLength(topValue, topUnits);
+ top = topValue;
+ this.topUnits = topUnits;
+ requestRepaint();
+ }
+
+ public void setRight(float rightValue, int rightUnits) {
+ validateLength(rightValue, rightUnits);
+ right = rightValue;
+ this.rightUnits = rightUnits;
+ requestRepaint();
+ }
+
+ public void setBottom(float bottomValue, int units) {
+ validateLength(bottomValue, units);
+ bottom = bottomValue;
+ bottomUnits = units;
+ requestRepaint();
+ }
+
+ public void setLeft(float leftValue, int units) {
+ validateLength(leftValue, units);
+ left = leftValue;
+ leftUnits = units;
+ requestRepaint();
+ }
+
+ public void setZIndex(int zIndex) {
+ this.zIndex = zIndex;
+ requestRepaint();
+ }
+
+ }
+
+ @Override
+ public void paintContent(PaintTarget target) throws PaintException {
+ super.paintContent(target);
+ for (Component component : components) {
+ target.startTag("cc");
+ target.addAttribute("css", getPosition(component).getCSSString());
+ component.paint(target);
+ target.endTag("cc");
+ }
+ }
+
+ private static void validateLength(float topValue, int topUnits2) {
+ // TODO throw on invalid value
+
+ }
+
+}
diff --git a/src/com/itmill/toolkit/ui/AbstractField.java b/src/com/itmill/toolkit/ui/AbstractField.java
index c998236f32..4d717826e6 100644
--- a/src/com/itmill/toolkit/ui/AbstractField.java
+++ b/src/com/itmill/toolkit/ui/AbstractField.java
@@ -639,12 +639,10 @@ public abstract class AbstractField extends AbstractComponent implements Field,
*/
public boolean isValid() {
- if (isRequired()) {
- if (isEmpty()) {
+ if (isEmpty()) {
+ if (isRequired()) {
return false;
- }
- } else {
- if (isEmpty()) {
+ } else {
return true;
}
}
@@ -675,9 +673,11 @@ public abstract class AbstractField extends AbstractComponent implements Field,
*/
public void validate() throws Validator.InvalidValueException {
- if (isRequired()) {
- if (isEmpty()) {
+ if (isEmpty()) {
+ if (isRequired()) {
throw new Validator.EmptyValueException(requiredError);
+ } else {
+ return;
}
}