From: Matti Tahvonen Date: Tue, 4 Mar 2008 09:26:02 +0000 (+0000) Subject: Refactored CustomComponent. Fixed possible NPE in Abstract component. Optimization... X-Git-Tag: 6.7.0.beta1~4993 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=707960f829ab10ccbb71cee04f2ee5db3177071a;p=vaadin-framework.git Refactored CustomComponent. Fixed possible NPE in Abstract component. Optimization for AbstractComponent. svn changeset:3963/svn branch:trunk --- diff --git a/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java b/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java index edf4bf3d81..968381d4a0 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java @@ -9,6 +9,7 @@ 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.ICustomComponent; import com.itmill.toolkit.terminal.gwt.client.ui.ICustomLayout; import com.itmill.toolkit.terminal.gwt.client.ui.IDateFieldCalendar; import com.itmill.toolkit.terminal.gwt.client.ui.IEmbedded; @@ -118,6 +119,9 @@ public class DefaultWidgetSet implements WidgetSet { } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ICustomLayout" .equals(className)) { return new ICustomLayout(); + } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ICustomComponent" + .equals(className)) { + return new ICustomComponent(); } else if ("com.itmill.toolkit.terminal.gwt.client.ui.ITextArea" .equals(className)) { return new ITextArea(); @@ -257,6 +261,8 @@ public class DefaultWidgetSet implements WidgetSet { return "com.itmill.toolkit.terminal.gwt.client.ui.IEmbedded"; } else if ("customlayout".equals(tag)) { return "com.itmill.toolkit.terminal.gwt.client.ui.ICustomLayout"; + } else if ("customcomponent".equals(tag)) { + return "com.itmill.toolkit.terminal.gwt.client.ui.ICustomComponent"; } else if ("textfield".equals(tag)) { if (uidl.getBooleanAttribute("richtext")) { return "com.itmill.toolkit.terminal.gwt.client.ui.richtextarea.IRichTextArea"; diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/ICustomComponent.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/ICustomComponent.java index d3305c04a5..fcd4d4796b 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/ICustomComponent.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/ICustomComponent.java @@ -7,10 +7,11 @@ package com.itmill.toolkit.terminal.gwt.client.ui; 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.Container; import com.itmill.toolkit.terminal.gwt.client.Paintable; import com.itmill.toolkit.terminal.gwt.client.UIDL; -public class ICustomComponent extends SimplePanel implements Paintable { +public class ICustomComponent extends SimplePanel implements Container { private static final String CLASSNAME = "i-customcomponent"; @@ -20,10 +21,13 @@ public class ICustomComponent extends SimplePanel implements Paintable { } public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { + if (client.updateComponent(this, uidl, false)) { + return; + } final UIDL child = uidl.getChildUIDL(0); if (child != null) { - final Paintable p = (Paintable) client.getPaintable(child); + final Paintable p = client.getPaintable(child); if (p != getWidget()) { if (getWidget() != null) { client.unregisterPaintable((Paintable) getWidget()); @@ -36,4 +40,25 @@ public class ICustomComponent extends SimplePanel implements Paintable { } + public boolean hasChildComponent(Widget component) { + if (getWidget() == component) { + return true; + } else { + return false; + } + } + + public void replaceChildComponent(Widget oldComponent, Widget newComponent) { + if (hasChildComponent(oldComponent)) { + clear(); + setWidget(newComponent); + } else { + throw new IllegalStateException(); + } + } + + public void updateCaption(Paintable component, UIDL uidl) { + // TODO custom component could handle its composition roots caption + } + } diff --git a/src/com/itmill/toolkit/tests/TestBench.java b/src/com/itmill/toolkit/tests/TestBench.java index c2e15b3b56..7245e0aece 100644 --- a/src/com/itmill/toolkit/tests/TestBench.java +++ b/src/com/itmill/toolkit/tests/TestBench.java @@ -19,6 +19,7 @@ import com.itmill.toolkit.ui.Component; import com.itmill.toolkit.ui.CustomComponent; import com.itmill.toolkit.ui.ExpandLayout; import com.itmill.toolkit.ui.Label; +import com.itmill.toolkit.ui.Layout; import com.itmill.toolkit.ui.Panel; import com.itmill.toolkit.ui.SplitPanel; import com.itmill.toolkit.ui.Tree; @@ -128,10 +129,13 @@ public class TestBench extends com.itmill.toolkit.Application implements try { final Application app = (Application) c.newInstance(); app.init(); - return app.getMainWindow().getLayout(); + Layout lo = app.getMainWindow().getLayout(); + lo.setParent(null); + return lo; } catch (final Exception e) { try { final CustomComponent cc = (CustomComponent) c.newInstance(); + cc.setSizeFull(); return cc; } catch (final Exception e1) { e1.printStackTrace(); diff --git a/src/com/itmill/toolkit/tests/featurebrowser/Feature.java b/src/com/itmill/toolkit/tests/featurebrowser/Feature.java index 80b85a5298..2f16f3fe02 100644 --- a/src/com/itmill/toolkit/tests/featurebrowser/Feature.java +++ b/src/com/itmill/toolkit/tests/featurebrowser/Feature.java @@ -186,8 +186,12 @@ public abstract class Feature extends CustomComponent { } // Fix for #512 - public Label getDescription() { - return description; + public String getDescription() { + if (description != null && description.getValue() != null) { + return description.getValue().toString(); + } else { + return null; + } } } \ No newline at end of file diff --git a/src/com/itmill/toolkit/tests/testbench/TestBench.java b/src/com/itmill/toolkit/tests/testbench/TestBench.java index 9393eba5b8..dcf41a3ca0 100644 --- a/src/com/itmill/toolkit/tests/testbench/TestBench.java +++ b/src/com/itmill/toolkit/tests/testbench/TestBench.java @@ -127,6 +127,7 @@ public class TestBench extends com.itmill.toolkit.Application implements } catch (final Exception e) { try { final CustomComponent cc = (CustomComponent) c.newInstance(); + cc.setSizeFull(); return cc; } catch (final Exception e1) { e1.printStackTrace(); diff --git a/src/com/itmill/toolkit/ui/AbstractComponent.java b/src/com/itmill/toolkit/ui/AbstractComponent.java index 8a1122c814..f4db9214ed 100644 --- a/src/com/itmill/toolkit/ui/AbstractComponent.java +++ b/src/com/itmill/toolkit/ui/AbstractComponent.java @@ -584,41 +584,39 @@ public abstract class AbstractComponent implements Component, MethodEventSource // Paint the contents of the component - if (getHeight() >= 0) { - target.addAttribute("height", "" + getHeight() - + UNIT_SYMBOLS[getHeightUnits()]); - } - if (getWidth() >= 0) { - target.addAttribute("width", "" + getWidth() - + UNIT_SYMBOLS[getWidthUnits()]); - } - - if (styles != null && styles.size() > 0) { - target.addAttribute("style", getStyle()); - } - if (isReadOnly()) { - target.addAttribute("readonly", true); - } - if (!isVisible()) { - target.addAttribute("invisible", true); - } - if (isImmediate()) { - target.addAttribute("immediate", true); - } - if (!isEnabled()) { - target.addAttribute("disabled", true); - } - if (getCaption() != null) { - target.addAttribute("caption", getCaption()); - } - if (getIcon() != null) { - target.addAttribute("icon", getIcon()); - } - // Only paint content of visible components. if (isVisible()) { - final String desc = getDescription(); - if (desc != null && description.length() > 0) { + + if (getHeight() >= 0) { + target.addAttribute("height", "" + getHeight() + + UNIT_SYMBOLS[getHeightUnits()]); + } + if (getWidth() >= 0) { + target.addAttribute("width", "" + getWidth() + + UNIT_SYMBOLS[getWidthUnits()]); + } + + if (styles != null && styles.size() > 0) { + target.addAttribute("style", getStyle()); + } + if (isReadOnly()) { + target.addAttribute("readonly", true); + } + + if (isImmediate()) { + target.addAttribute("immediate", true); + } + if (!isEnabled()) { + target.addAttribute("disabled", true); + } + if (getCaption() != null) { + target.addAttribute("caption", getCaption()); + } + if (getIcon() != null) { + target.addAttribute("icon", getIcon()); + } + + if (getDescription() != null && getDescription().length() > 0) { target.addAttribute("description", getDescription()); } @@ -628,6 +626,8 @@ public abstract class AbstractComponent implements Component, MethodEventSource if (error != null) { error.paint(target); } + } else { + target.addAttribute("invisible", true); } } else { diff --git a/src/com/itmill/toolkit/ui/CustomComponent.java b/src/com/itmill/toolkit/ui/CustomComponent.java index 7c165df687..9891b840d1 100644 --- a/src/com/itmill/toolkit/ui/CustomComponent.java +++ b/src/com/itmill/toolkit/ui/CustomComponent.java @@ -4,15 +4,10 @@ package com.itmill.toolkit.ui; -import java.util.Collection; -import java.util.LinkedList; -import java.util.Locale; -import java.util.Map; +import java.util.Iterator; -import com.itmill.toolkit.Application; import com.itmill.toolkit.terminal.PaintException; import com.itmill.toolkit.terminal.PaintTarget; -import com.itmill.toolkit.terminal.Resource; /** * Custom component provides simple implementation of Component interface for @@ -28,40 +23,26 @@ import com.itmill.toolkit.terminal.Resource; * @VERSION@ * @since 3.0 */ -public class CustomComponent implements Component { +/** + * @author mattitahvonen + * + */ +/** + * @author mattitahvonen + * + */ +public class CustomComponent extends AbstractComponentContainer { /** * The root component implementing the custom component. */ private Component root = null; - /** - * The visibility of the component. - */ - private boolean visible = true; - - /** - * The parent of the component. - */ - private Component parent = null; - /** * Type of the component. */ private String componentType = null; - /** - * List of repaint request listeners or null if not listened at all. - */ - private LinkedList repaintRequestListeners = null; - - /** - * Are all the repaint listeners notified about recent changes ? - */ - private boolean repaintRequestListenersNotified = false; - - private String testingId; - /** * Constructs a new custom component. * @@ -111,449 +92,124 @@ public class CustomComponent implements Component { */ protected final void setCompositionRoot(Component compositionRoot) { if (compositionRoot != root && root != null) { - root.setParent(null); + super.removeComponent(root); } root = compositionRoot; if (root != null) { - root.setParent(this); + super.addComponent(root); } } /* Basic component features ------------------------------------------ */ - /** - * Notifies the component that it is connected to an application. - * - * @see com.itmill.toolkit.ui.Component#attach() - */ - public void attach() { - if (root != null) { - root.attach(); - requestRepaint(); - } - } - - /** - * Notifies the component that it is detached from the application. - * - * @see com.itmill.toolkit.ui.Component#detach() - */ - public void detach() { - if (root != null) { - root.detach(); - } - } - - /** - * Gets the component's parent application - * - * @see com.itmill.toolkit.ui.Component#getApplication() - */ - public Application getApplication() { - if (parent == null) { - return null; - } - return parent.getApplication(); - } - - /** - * The caption of the custom component is by default the caption of the root - * component, or null if the root is not set. - * - * @see com.itmill.toolkit.ui.Component#getCaption() - */ - public String getCaption() { + public void paintContent(PaintTarget target) throws PaintException { if (root == null) { - return null; - } - return root.getCaption(); - } - - /** - * The icon of the custom component is by default the icon of the root - * component, or null if the root is not set. - * - * @see com.itmill.toolkit.ui.Component#getIcon() - */ - public Resource getIcon() { - if (root == null) { - return null; - } - return root.getIcon(); - } - - /** - * The icon of the custom component is by default the locale of the parent - * or null if the parent is not set. - * - * @see com.itmill.toolkit.ui.Component#getLocale() - */ - public Locale getLocale() { - if (parent == null) { - return null; + throw new IllegalStateException("Composition root must be set to" + + " non-null value before the " + getClass().getName() + + " can be painted"); } - return parent.getLocale(); - } - - /** - * Gets the visual parent of the component. - * - * @see com.itmill.toolkit.ui.Component#getParent() - */ - public Component getParent() { - return parent; - } - /** - * Custom component does not implement custom styles by default and this - * function returns null. - * - * @see com.itmill.toolkit.ui.Component#getStyle() - */ - public String getStyleName() { - return null; - } - - /** - * Gets the component's parent window. - * - * @see com.itmill.toolkit.ui.Component#getWindow() - */ - public Window getWindow() { - if (parent == null) { - return null; + if (getComponentType() != null) { + target.addAttribute("type", getComponentType()); } - return parent.getWindow(); + root.paint(target); } /** - * Custom component is always enabled by default. + * Gets the component type. * - * @see com.itmill.toolkit.ui.Component#isEnabled() - */ - public boolean isEnabled() { - return true; - } - - /** - * Custom component is by default in the non-immediate mode. The - * immediateness of the custom component is defined by the components it is - * composed of. + * The component type is textual type of the component. This is included in + * the UIDL as component tag attribute. If the component type is null + * (default), the component tag is not included in the UIDL at all. * - * @see com.itmill.toolkit.terminal.VariableOwner#isImmediate() + * @return the component type. */ - public boolean isImmediate() { - return false; + public String getComponentType() { + return componentType; } /** - * The custom components are not readonly by default. + * Sets the component type. * - * @see com.itmill.toolkit.ui.Component#isReadOnly() - */ - public boolean isReadOnly() { - return false; - } - - /** - * Tests if the component is visible or not. + * The component type is textual type of the component. This is included in + * the UIDL as component tag attribute. * - * @see com.itmill.toolkit.ui.Component#isVisible() + * @param componentType + * the componentType to set. */ - public boolean isVisible() { - return visible; + public void setComponentType(String componentType) { + this.componentType = componentType; } - /* Documentation copied from interface */ - public void requestRepaint() { - - // The effect of the repaint request is identical to case where a - // child requests repaint - childRequestedRepaint(null); + public String getTag() { + return "customcomponent"; } - /* Documentation copied from interface */ - public void childRequestedRepaint(Collection alreadyNotified) { - - // Notify listeners only once - if (!repaintRequestListenersNotified) { + public Iterator getComponentIterator() { + return new Iterator() { + boolean first = true; - // Notify the listeners - if (repaintRequestListeners != null - && !repaintRequestListeners.isEmpty()) { - final Object[] listeners = repaintRequestListeners.toArray(); - final RepaintRequestEvent event = new RepaintRequestEvent(this); - for (int i = 0; i < listeners.length; i++) { - if (alreadyNotified == null) { - alreadyNotified = new LinkedList(); - } - if (!alreadyNotified.contains(listeners[i])) { - ((RepaintRequestListener) listeners[i]) - .repaintRequested(event); - alreadyNotified.add(listeners[i]); - repaintRequestListenersNotified = true; - } - } + public boolean hasNext() { + return first; } - // Notify the parent - final Component parent = getParent(); - if (parent != null) { - parent.childRequestedRepaint(alreadyNotified); + public Object next() { + first = false; + return root; } - } - } - - /* Documentation copied from interface */ - public void addListener(RepaintRequestListener listener) { - if (repaintRequestListeners == null) { - repaintRequestListeners = new LinkedList(); - } - if (!repaintRequestListeners.contains(listener)) { - repaintRequestListeners.add(listener); - } - } - - /* Documentation copied from interface */ - public void removeListener(RepaintRequestListener listener) { - if (repaintRequestListeners != null) { - repaintRequestListeners.remove(listener); - if (repaintRequestListeners.isEmpty()) { - repaintRequestListeners = null; - } - } - } - - /** - * The custom component is allways enabled by default. - */ - public void setEnabled(boolean enabled) { - } - - /** - * Sets the component's parent component. - * - * @see com.itmill.toolkit.ui.Component#setParent(com.itmill.toolkit.ui.Component) - */ - public void setParent(Component parent) { - - // If the parent is not changed, dont do nothing - if (parent == this.parent) { - return; - } - - // Sends the detach event if the component have been connected to a - // window - if (getApplication() != null) { - detach(); - this.parent = null; - } - - // Connects to new parent - this.parent = parent; - - // Sends the attach event if connected to a window - if (getApplication() != null) { - attach(); - } - } - - /** - * Sets the component's to read-only mode to the specified state. - * - * @see com.itmill.toolkit.ui.Component#setReadOnly(boolean) - */ - public void setReadOnly(boolean readOnly) { - } - - /** - * Custom component does not implement custom styles by default. - * - * @see com.itmill.toolkit.ui.Component#setStyle(java.lang.String) - */ - public void setStyleName(String style) { - } - - /** - * Sets the components visibility status. - * - * @see com.itmill.toolkit.ui.Component#setVisible(boolean) - */ - public void setVisible(boolean visible) { - this.visible = visible; - } - - /* Documented in super interface */ - public void requestRepaintRequests() { - repaintRequestListenersNotified = false; - } - - /* Documented in super interface */ - public void paint(PaintTarget target) throws PaintException { - if (root == null) { - throw new IllegalStateException("Composition root must be set to" - + " non-null value before the " + getClass().getName() - + " can be painted"); - } - - if (isVisible()) { - final String type = getComponentType(); - if (type != null) { - if (!target.startTag(this, "component")) { - target.addAttribute("type", type); - root.paint(target); - } - target.endTag("component"); - } else { - root.paint(target); + public void remove() { + throw new UnsupportedOperationException(); } - } - repaintRequestListenersNotified = false; + }; } /** - * Called when one or more variables handled by the implementing class are - * changed. + * This method is not supported by CustomComponent. * - * @see com.itmill.toolkit.terminal.VariableOwner#changeVariables(java.lang.Object, - * java.util.Map) + * @see com.itmill.toolkit.ui.ComponentContainer#replaceComponent(com.itmill.toolkit.ui.Component, + * com.itmill.toolkit.ui.Component) */ - public void changeVariables(Object source, Map variables) { + public void replaceComponent(Component oldComponent, Component newComponent) { + throw new UnsupportedOperationException(); } - /* Event functions are not implemented by default -------------------- */ - /** - * Custom component does not implement any component events by default. - * - * @param listener - * the listener to add. - */ - public void addListener(Component.Listener listener) { - } - - /** - * Custom component does not implement any component events by default. - * - * @param listener - * the listener to remove. - */ - public void removeListener(Component.Listener listener) { - } - - /** - * Gets the component type. - * - * The component type is textual type of the component. This is included in - * the UIDL as component tag attribute. If the component type is null - * (default), the component tag is not included in the UIDL at all. + * This method is not supported by CustomComponent. Use + * {@link CustomComponent#setCompositionRoot(Component)} to set + * CustomComponents "child". * - * @return the component type. + * @see com.itmill.toolkit.ui.AbstractComponentContainer#addComponent(com.itmill.toolkit.ui.Component) */ - public String getComponentType() { - return componentType; + public void addComponent(Component c) { + throw new UnsupportedOperationException(); } /** - * Sets the component type. + * This method is not supported by CustomComponent. * - * The component type is textual type of the component. This is included in - * the UIDL as component tag attribute. If the component type is null - * (default), the component tag is not included in the UIDL at all. - * - * @param componentType - * the componentType to set. + * @see com.itmill.toolkit.ui.AbstractComponentContainer#moveComponentsFrom(com.itmill.toolkit.ui.ComponentContainer) */ - public void setComponentType(String componentType) { - this.componentType = componentType; + public void moveComponentsFrom(ComponentContainer source) { + throw new UnsupportedOperationException(); } /** - * Custom component does not implement custom styles by default. + * This method is not supported by CustomComponent. * - * @see com.itmill.toolkit.ui.Component#getStyle() + * @see com.itmill.toolkit.ui.AbstractComponentContainer#removeAllComponents() */ - public void addStyleName(String style) { + public void removeAllComponents() { + throw new UnsupportedOperationException(); } /** - * Custom component does not implement custom styles by default. + * This method is not supported by CustomComponent. * - * @see com.itmill.toolkit.ui.Component#getStyle() + * @see com.itmill.toolkit.ui.AbstractComponentContainer#removeComponent(com.itmill.toolkit.ui.Component) */ - public void removeStyleName(String style) { - - } - - public void setDebugId(String id) { - testingId = id; - } - - public String getDebugId() { - return testingId; - } - - // TODO bridge sizeable methods to composition root and documentate - - public int getHeight() { - // TODO Auto-generated method stub - return 0; - } - - public int getHeightUnits() { - // TODO Auto-generated method stub - return 0; - } - - public int getWidth() { - // TODO Auto-generated method stub - return 0; - } - - public int getWidthUnits() { - // TODO Auto-generated method stub - return 0; - } - - public void setHeight(int height) { - // TODO Auto-generated method stub - - } - - public void setHeightUnits(int units) { - // TODO Auto-generated method stub - - } - - public void setSizeFull() { - // TODO Auto-generated method stub - - } - - public void setSizeUndefined() { - // TODO Auto-generated method stub - - } - - public void setWidth(int width) { - // TODO Auto-generated method stub - - } - - public void setWidthUnits(int units) { - // TODO Auto-generated method stub - - } - - public void setHeight(String height) { - // TODO Auto-generated method stub - - } - - public void setWidth(String width) { - // TODO Auto-generated method stub - + public void removeComponent(Component c) { + throw new UnsupportedOperationException(); } }