]> source.dussan.org Git - vaadin-framework.git/commitdiff
Split test case into Layout click test and textfield focus/blur test + auto test...
authorArtur Signell <artur.signell@itmill.com>
Thu, 26 Nov 2009 08:20:13 +0000 (08:20 +0000)
committerArtur Signell <artur.signell@itmill.com>
Thu, 26 Nov 2009 08:20:13 +0000 (08:20 +0000)
Simplified ClickEventHandler/LayoutClickEventHandler and made them public so they are available to other components.

svn changeset:10054/svn branch:event-framework-3234

14 files changed:
src/TestListeners.java [deleted file]
src/com/vaadin/terminal/gwt/client/MouseEventDetails.java
src/com/vaadin/terminal/gwt/client/ui/ClickEventHandler.java
src/com/vaadin/terminal/gwt/client/ui/LayoutClickEventHandler.java
src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java
src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java
src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java
src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java
src/com/vaadin/terminal/gwt/client/ui/VPanel.java
src/com/vaadin/terminal/gwt/client/ui/VTextField.java
src/com/vaadin/ui/TextField.java
tests/src/com/vaadin/tests/components/textfield/TextFieldFocusAndBlurListeners.java [new file with mode: 0644]
tests/src/com/vaadin/tests/layouts/TestLayoutClickListeners.html [new file with mode: 0644]
tests/src/com/vaadin/tests/layouts/TestLayoutClickListeners.java [new file with mode: 0644]

diff --git a/src/TestListeners.java b/src/TestListeners.java
deleted file mode 100644 (file)
index 87255b4..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-import com.vaadin.Application;
-import com.vaadin.event.FieldEvents.BlurEvent;
-import com.vaadin.event.FieldEvents.BlurListener;
-import com.vaadin.event.FieldEvents.FocusEvent;
-import com.vaadin.event.FieldEvents.FocusListener;
-import com.vaadin.event.LayoutEvents.LayoutClickEvent;
-import com.vaadin.event.LayoutEvents.LayoutClickListener;
-import com.vaadin.event.MouseEvents.ClickEvent;
-import com.vaadin.event.MouseEvents.ClickListener;
-import com.vaadin.terminal.ExternalResource;
-import com.vaadin.terminal.gwt.client.MouseEventDetails;
-import com.vaadin.ui.AbsoluteLayout;
-import com.vaadin.ui.Component;
-import com.vaadin.ui.Embedded;
-import com.vaadin.ui.GridLayout;
-import com.vaadin.ui.HorizontalLayout;
-import com.vaadin.ui.Label;
-import com.vaadin.ui.Layout;
-import com.vaadin.ui.TextField;
-import com.vaadin.ui.VerticalLayout;
-import com.vaadin.ui.Window;
-
-public class TestListeners extends Application implements LayoutClickListener,
-        ClickListener, FocusListener {
-
-    @Override
-    public void init() {
-        Window w = new Window("main window");
-        setMainWindow(w);
-        HorizontalLayout hl = new HorizontalLayout();
-        w.setContent(hl);
-
-        final AbsoluteLayout al = new AbsoluteLayout();
-        al.setWidth("200px");
-        al.setHeight("200px");
-        al.addComponent(new TextField("This is its caption",
-                "This is a textfield"), "top: 20px; left: 0px; width: 100px;");
-        al.addComponent(new TextField("Antoerh caption",
-                "This is another textfield"),
-                "top: 120px; left: 0px; width: 100px;");
-
-        final LayoutClickListener lcl = new LayoutClickListener() {
-
-            public void layoutClick(LayoutClickEvent event) {
-                System.out.println("AL: Click on " + event.getChildComponent());
-                // al.removeListener(this);
-
-            }
-        };
-        al.addListener(lcl);
-
-        final GridLayout vl = new GridLayout();
-        vl.addComponent(al);
-        vl.setSpacing(true);
-        for (int i = 0; i < 10; i++) {
-            vl.addComponent(new Label("Component " + i));
-            ExternalResource res = new ExternalResource(
-                    "http://vaadin.com/image/image_gallery?uuid=07c1f6d5-2e94-4f4d-a707-b548bf22279d&groupId=10919&t=1241012632062");
-            Embedded e = new Embedded("an image", res);
-            e.setType(Embedded.TYPE_IMAGE);
-            e.addListener(new ClickListener() {
-
-                public void click(ClickEvent event) {
-                    TestListeners.this.click(event);
-
-                }
-            });
-            // e.addListener(this);
-            vl.addComponent(e);
-            TextField tf = new TextField("tf");
-            tf.setInputPrompt("Please enter a value");
-
-            // tf.addListener(this);
-            tf.addListener(new BlurListener() {
-
-                public void blur(BlurEvent event) {
-                    getMainWindow().showNotification(
-                            "Blurred " + event.getComponent());
-
-                }
-            });
-            tf.addListener(new FocusListener() {
-
-                public void focus(FocusEvent event) {
-                    getMainWindow().showNotification(
-                            "Focused " + event.getComponent());
-
-                }
-            });
-            vl.addComponent(tf);
-        }
-
-        // vl.addListener(this);
-        vl.addListener(new LayoutClickListener() {
-
-            public void layoutClick(LayoutClickEvent event) {
-                TestListeners.this.layoutClick(event);
-                vl.removeListener(this);
-            }
-        });
-        vl.setMargin(true);
-
-        hl.addComponent(vl);
-        hl.addComponent(createClickableGridLayout());
-        hl.addComponent(createClickableVerticalLayout());
-    }
-
-    private Layout createClickableGridLayout() {
-
-        GridLayout gl = new GridLayout(3, 3);
-        addContent(gl, 5);
-
-        gl.addListener(new LayoutClickListener() {
-
-            public void layoutClick(LayoutClickEvent event) {
-                getMainWindow().showNotification(
-                        "GL-click on " + event.getChildComponent());
-
-            }
-        });
-
-        return wrap(gl, "Clickable GridLayout");
-    }
-
-    private Layout createClickableVerticalLayout() {
-
-        VerticalLayout gl = new VerticalLayout();
-        addContent(gl, 5);
-
-        gl.addListener(new LayoutClickListener() {
-
-            public void layoutClick(LayoutClickEvent event) {
-                getMainWindow().showNotification(
-                        "VL-click on " + event.getChildComponent());
-
-            }
-        });
-
-        return wrap(gl, "Clickable VerticalLayout");
-    }
-
-    private void addContent(Layout gl, int nr) {
-        for (int i = 1; i < nr; i++) {
-            Label l = new Label("This is label " + i);
-            l.setWidth(null);
-            gl.addComponent(l);
-        }
-        for (int i = nr; i < nr * 2; i++) {
-            gl.addComponent(new TextField("This is tf" + i, "this is tf " + i));
-        }
-    }
-
-    private Layout wrap(Component c, String caption) {
-        VerticalLayout vl = new VerticalLayout();
-        Label l = new Label(caption);
-        l.setWidth(null);
-        vl.addComponent(l);
-        vl.addComponent(c);
-
-        return vl;
-    }
-
-    public void layoutClick(LayoutClickEvent event) {
-        if (event.getChildComponent() == null) {
-            getMainWindow().showNotification("You missed!");
-        } else {
-            getMainWindow().showNotification(
-                    "Clicked on " + event.getChildComponent() + "!");
-            // getMainWindow().removeComponent(event.getChildComponent());
-        }
-
-    }
-
-    public void click(ClickEvent event) {
-        getMainWindow().showNotification(
-                "Clicked on " + event.getComponent() + " using "
-                        + getButton(event));
-    }
-
-    private String getButton(ClickEvent event) {
-        if (event.getButton() == MouseEventDetails.BUTTON_LEFT) {
-            return "left";
-        } else if (event.getButton() == MouseEventDetails.BUTTON_RIGHT) {
-            return "right";
-        } else {
-            return "middle";
-        }
-    }
-
-    public void focus(FocusEvent event) {
-        TextField tf = (TextField) event.getComponent();
-        // tf.addStyleName("a");
-        // tf.setValue("");
-        getMainWindow().requestRepaintAll();
-
-    }
-
-}
index 3a9a64657cf868371b9a1dee4d4ebc432bc4d509..0a20b112d3165adc5e14fb9a22849aca8fa76e0e 100644 (file)
@@ -90,6 +90,18 @@ public class MouseEventDetails {
         return instance;
     }
 
+    public String getButtonName() {
+        if (button == BUTTON_LEFT) {
+            return "left";
+        } else if (button == BUTTON_RIGHT) {
+            return "right";
+        } else if (button == BUTTON_MIDDLE) {
+            return "middle";
+        }
+
+        return "";
+    }
+
     public Class<MouseEventDetails> getType() {
         return MouseEventDetails.class;
     }
index aae416ba6a62e4c87549e81eb40f06da5760b7f0..0e60246d48b1ce05542d050d672335c8ffb31e4d 100644 (file)
@@ -19,8 +19,8 @@ import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;\r
 import com.vaadin.terminal.gwt.client.Paintable;\r
 \r
-abstract class ClickEventHandler implements ClickHandler, DoubleClickHandler,\r
-        ContextMenuHandler, MouseUpHandler {\r
+public abstract class ClickEventHandler implements ClickHandler,\r
+        DoubleClickHandler, ContextMenuHandler, MouseUpHandler {\r
 \r
     private HandlerRegistration clickHandlerRegistration;\r
     private HandlerRegistration doubleClickHandlerRegistration;\r
@@ -29,13 +29,15 @@ abstract class ClickEventHandler implements ClickHandler, DoubleClickHandler,
 \r
     protected String clickEventIdentifier;\r
     protected Paintable paintable;\r
+    private ApplicationConnection client;\r
 \r
-    ClickEventHandler(Paintable paintable, String clickEventIdentifier) {\r
+    public ClickEventHandler(Paintable paintable, String clickEventIdentifier) {\r
         this.paintable = paintable;\r
         this.clickEventIdentifier = clickEventIdentifier;\r
     }\r
 \r
-    public void handleHandlerRegistration() {\r
+    public void handleEventHandlerRegistration(ApplicationConnection client) {\r
+        this.client = client;\r
         // Handle registering/unregistering of click handler depending on if\r
         // server side listeners have been added or removed.\r
         if (hasEventListener()) {\r
@@ -70,7 +72,9 @@ abstract class ClickEventHandler implements ClickHandler, DoubleClickHandler,
     protected abstract <H extends EventHandler> HandlerRegistration registerHandler(\r
             final H handler, DomEvent.Type<H> type);\r
 \r
-    public abstract ApplicationConnection getApplicationConnection();\r
+    protected ApplicationConnection getApplicationConnection() {\r
+        return client;\r
+    }\r
 \r
     public boolean hasEventListener() {\r
         return getApplicationConnection().hasEventListeners(paintable,\r
index c19d0b1c7d86b39b75babcad3d9d3eefd9e1dcd4..8cf55ca95202723f66705f717325ba46b27a9d24 100644 (file)
@@ -9,7 +9,7 @@ import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.terminal.gwt.client.Paintable;
 
-abstract class LayoutClickEventHandler extends ClickEventHandler {
+public abstract class LayoutClickEventHandler extends ClickEventHandler {
 
     LayoutClickEventHandler(Paintable paintable, String clickEventIdentifier) {
         super(paintable, clickEventIdentifier);
index a83df137f4ca44108c7154c2952bf01180a65d72..63f865082b673de3b0f0bbfece29d9a470064b34 100644 (file)
@@ -55,11 +55,6 @@ public class VAbsoluteLayout extends ComplexPanel implements Container {
     private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
             this, CLICK_EVENT_IDENTIFIER) {
 
-        @Override
-        public ApplicationConnection getApplicationConnection() {
-            return client;
-        }
-
         @Override
         protected Paintable getChildComponent(Element element) {
             return getComponent(element);
@@ -154,7 +149,7 @@ public class VAbsoluteLayout extends ComplexPanel implements Container {
             return;
         }
 
-        clickEventHandler.handleHandlerRegistration();
+        clickEventHandler.handleEventHandlerRegistration(client);
 
         HashSet<String> unrenderedPids = new HashSet<String>(
                 pidToComponentWrappper.keySet());
@@ -417,7 +412,6 @@ public class VAbsoluteLayout extends ComplexPanel implements Container {
         }
     }
 
-
     private Paintable getComponent(Element target) {
         while (target != null && target != canvas) {
             Paintable paintable = client.getPaintable(target);
index adf8d7c354ba5f739cdc1b57a68145e3463658a3..871e2ae35f47b956fdab8e0c0d2a21667b1a59a5 100644 (file)
@@ -39,11 +39,6 @@ public class VEmbedded extends HTML implements Paintable {
     private ClickEventHandler clickEventHandler = new ClickEventHandler(this,
             CLICK_EVENT_IDENTIFIER) {
 
-        @Override
-        public ApplicationConnection getApplicationConnection() {
-            return client;
-        }
-
         @Override
         protected <H extends EventHandler> HandlerRegistration registerHandler(
                 H handler, Type<H> type) {
@@ -64,7 +59,7 @@ public class VEmbedded extends HTML implements Paintable {
 
         boolean clearBrowserElement = true;
 
-        clickEventHandler.handleHandlerRegistration();
+        clickEventHandler.handleEventHandlerRegistration(client);
 
         if (uidl.hasAttribute("type")) {
             final String type = uidl.getStringAttribute("type");
index c057135862858794d0676fbb650ddd95d4d6230f..2dae5626d6e14ddefd25e1aeeb79a4be288d7c8f 100644 (file)
@@ -75,11 +75,6 @@ public class VGridLayout extends SimplePanel implements Paintable, Container {
     private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(
             this, CLICK_EVENT_IDENTIFIER) {
 
-        @Override
-        public ApplicationConnection getApplicationConnection() {
-            return client;
-        }
-
         @Override
         protected Paintable getChildComponent(Element element) {
             return getComponent(element);
@@ -112,7 +107,7 @@ public class VGridLayout extends SimplePanel implements Paintable, Container {
             rendering = false;
             return;
         }
-        clickEventHandler.handleHandlerRegistration();
+        clickEventHandler.handleEventHandlerRegistration(client);
 
         canvas.setWidth("0px");
 
index 0f548680a1aa9e8d18880a3ba799bfcafef01691..cb5624142fdc00c68becffd6b6d8399ebd236949 100644 (file)
@@ -55,11 +55,6 @@ public class VOrderedLayout extends CellBasedLayout {
     private LayoutClickEventHandler clickEventHandler = new LayoutClickEventHandler(\r
             this, CLICK_EVENT_IDENTIFIER) {\r
 \r
-        @Override\r
-        public ApplicationConnection getApplicationConnection() {\r
-            return client;\r
-        }\r
-\r
         @Override\r
         protected Paintable getChildComponent(Element element) {\r
             return getComponent(element);\r
@@ -100,7 +95,7 @@ public class VOrderedLayout extends CellBasedLayout {
             return;\r
         }\r
 \r
-        clickEventHandler.handleHandlerRegistration();\r
+        clickEventHandler.handleEventHandlerRegistration(client);\r
 \r
         if (allowOrientationUpdate) {\r
             handleOrientationUpdate(uidl);\r
index e6386e7a7c90632164ab5794911d3ad24e06c3b8..8b054160a809b9a53b7a92e8e6eab7a76222779a 100644 (file)
@@ -79,11 +79,6 @@ public class VPanel extends SimplePanel implements Container {
     private ClickEventHandler clickEventHandler = new ClickEventHandler(this,
             CLICK_EVENT_IDENTIFIER) {
 
-        @Override
-        public ApplicationConnection getApplicationConnection() {
-            return client;
-        }
-
         @Override
         protected <H extends EventHandler> HandlerRegistration registerHandler(
                 H handler, Type<H> type) {
@@ -126,7 +121,7 @@ public class VPanel extends SimplePanel implements Container {
     public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
         rendering = true;
         if (!uidl.hasAttribute("cached")) {
-            clickEventHandler.handleHandlerRegistration();
+            clickEventHandler.handleEventHandlerRegistration(client);
 
             // Handle caption displaying and style names, prior generics.
             // Affects size
index 5e5d0bf687d462b4b37c658669acbc37d42c7879..fe2c03496cc89476c8a03aee2ce963909dc3f959 100644 (file)
@@ -169,13 +169,39 @@ public class VTextField extends TextBoxBase implements Paintable, Field,
     }
 
     public void onChange(ChangeEvent event) {
+        valueChange(false);
+    }
+
+    /**
+     * Called when the field value might have changed and/or the field was
+     * blurred. These are combined so the blur event is sent in the same batch
+     * as a possible value change event (these are often connected).
+     * 
+     * @param blurred
+     *            true if the field was blurred
+     */
+    public void valueChange(boolean blurred) {
         if (client != null && id != null) {
+            boolean sendBlurEvent = false;
+            boolean sendValueChange = false;
+
+            if (blurred
+                    && client.hasEventListeners(this, BLUR_EVENT_IDENTIFIER)) {
+                sendBlurEvent = true;
+                client.updateVariable(id, BLUR_EVENT_IDENTIFIER, "", false);
+            }
+
             String newText = getText();
             if (!prompting && newText != null
                     && !newText.equals(valueBeforeEdit)) {
-                client.updateVariable(id, "text", getText(), immediate);
+                sendValueChange = immediate;
+                client.updateVariable(id, "text", getText(), false);
                 valueBeforeEdit = newText;
             }
+
+            if (sendBlurEvent || sendValueChange) {
+                client.sendPendingVariableChanges();
+            }
         }
     }
 
@@ -213,11 +239,8 @@ public class VTextField extends TextBoxBase implements Paintable, Field,
             setText(inputPrompt);
             addStyleDependentName(CLASSNAME_PROMPT);
         }
-        onChange(null);
-        if (client.hasEventListeners(this, BLUR_EVENT_IDENTIFIER)) {
-            client.updateVariable(client.getPid(this), BLUR_EVENT_IDENTIFIER,
-                    "", true);
-        }
+
+        valueChange(true);
     }
 
     private void setPrompting(boolean prompting) {
index ee2f1097f37d83d8c2917760a528c96ad3683142..59cf6640cecfb5f987acff2186dba41fc4062d7a 100644 (file)
@@ -248,13 +248,6 @@ public class TextField extends AbstractField {
 
         super.changeVariables(source, variables);
 
-        if (variables.containsKey(FOCUS_EVENT)) {
-            fireFocus(variables.get(FOCUS_EVENT));
-        }
-        if (variables.containsKey(BLUR_EVENT)) {
-            fireBlur(variables.get(BLUR_EVENT));
-        }
-
         // Sets the text
         if (variables.containsKey("text") && !isReadOnly()) {
 
@@ -285,6 +278,13 @@ public class TextField extends AbstractField {
             }
         }
 
+        if (variables.containsKey(FOCUS_EVENT)) {
+            fireFocus(variables.get(FOCUS_EVENT));
+        }
+        if (variables.containsKey(BLUR_EVENT)) {
+            fireBlur(variables.get(BLUR_EVENT));
+        }
+
     }
 
     /* Text field configuration */
diff --git a/tests/src/com/vaadin/tests/components/textfield/TextFieldFocusAndBlurListeners.java b/tests/src/com/vaadin/tests/components/textfield/TextFieldFocusAndBlurListeners.java
new file mode 100644 (file)
index 0000000..77cc587
--- /dev/null
@@ -0,0 +1,95 @@
+package com.vaadin.tests.components.textfield;
+
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.data.Property.ValueChangeListener;
+import com.vaadin.event.FieldEvents.BlurEvent;
+import com.vaadin.event.FieldEvents.BlurListener;
+import com.vaadin.event.FieldEvents.FocusEvent;
+import com.vaadin.event.FieldEvents.FocusListener;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.tests.layouts.TestLayoutClickListeners.Log;
+import com.vaadin.ui.TextField;
+
+public class TextFieldFocusAndBlurListeners extends TestBase implements
+        FocusListener, BlurListener, ValueChangeListener {
+    private Log log = new Log(5);
+
+    @Override
+    protected String getDescription() {
+        return "Tests the focus and blur functionality of TextField";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 3544;
+    }
+
+    @Override
+    public void setup() {
+        addComponent(log);
+        TextField tf1 = new TextField("TextField 1",
+                "Has focus and blur listeners");
+        tf1.setWidth("300px");
+        tf1.addListener((FocusListener) this);
+        tf1.addListener((BlurListener) this);
+
+        addComponent(tf1);
+
+        TextField tf2 = new TextField("TextField 2",
+                "Has focus, blur and valuechange listeners");
+        tf2.setWidth("300px");
+        tf2.addListener(new ValueChangeListener() {
+
+            public void valueChange(ValueChangeEvent event) {
+                TextFieldFocusAndBlurListeners.this.valueChange(event);
+            }
+        });
+        tf2.addListener(new FocusListener() {
+
+            public void focus(FocusEvent event) {
+                TextFieldFocusAndBlurListeners.this.focus(event);
+            }
+
+        });
+        tf2.addListener(new BlurListener() {
+
+            public void blur(BlurEvent event) {
+                TextFieldFocusAndBlurListeners.this.blur(event);
+            }
+        });
+
+        addComponent(tf2);
+
+        TextField tf3 = new TextField("TextField 3",
+                "Has non-immediate valuechange listener");
+        tf3.setWidth("300px");
+        tf3.addListener((ValueChangeListener) this);
+
+        addComponent(tf3);
+
+        TextField tf4 = new TextField("TextField 4",
+                "Has immediate valuechange listener");
+        tf4.setWidth("300px");
+        tf4.setImmediate(true);
+        tf4.addListener((ValueChangeListener) this);
+
+        addComponent(tf4);
+    }
+
+    public void focus(FocusEvent event) {
+        log.log(event.getComponent().getCaption() + ": Focus");
+
+    }
+
+    public void blur(BlurEvent event) {
+        TextField tf = (TextField) event.getComponent();
+        log.log(tf.getCaption() + ": Blur. Value is: "
+                + tf.getValue().toString());
+
+    }
+
+    public void valueChange(ValueChangeEvent event) {
+        TextField tf = (TextField) event.getProperty();
+        log.log(tf.getCaption() + ": ValueChange: " + tf.getValue().toString());
+    }
+}
diff --git a/tests/src/com/vaadin/tests/layouts/TestLayoutClickListeners.html b/tests/src/com/vaadin/tests/layouts/TestLayoutClickListeners.html
new file mode 100644 (file)
index 0000000..aa2e923
--- /dev/null
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="" />
+<title>TestLayoutClickListeners</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">TestLayoutClickListeners</td></tr>
+</thead><tbody>
+<tr>
+       <td>open</td>
+       <td>/run/com.vaadin.tests.layouts.TestLayoutClickListeners</td>
+       <td></td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>screenCapture</td>
+       <td></td>
+       <td>initial</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[0]/VLabel[0]</td>
+       <td>43,11</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>assertText</td>
+       <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td>
+       <td>exact:GridLayout: Click on This is label 1</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/AbsolutePanel[0]/ChildComponentContainer[4]/VTextField[0]</td>
+       <td>82,14</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>assertText</td>
+       <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td>
+       <td>exact:GridLayout: Click on This is tf5</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VTextField[0]</td>
+       <td>74,13</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>assertText</td>
+       <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td>
+       <td>exact:VerticalLayout: Click on This is tf6</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VLabel[0]</td>
+       <td>53,13</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>assertText</td>
+       <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td>
+       <td>exact:VerticalLayout: Click on This is label 3</td>
+</tr>
+<tr>
+       <td>click</td>
+       <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[2]/VAbsoluteLayout[0]/VAbsoluteLayout$AbsoluteWrapper[2]/VButton[0]/domChild[0]/domChild[0]</td>
+       <td></td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>assertText</td>
+       <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VLabel[0]</td>
+       <td>Button A button with its own click listener was clicked</td>
+</tr>
+<tr>
+       <td>assertText</td>
+       <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td>
+       <td>exact:AbsoluteLayout: Click on A button with its own click listener</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[2]/VAbsoluteLayout[0]/VAbsoluteLayout$AbsoluteWrapper[0]/VTextField[0]</td>
+       <td>101,14</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>assertText</td>
+       <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td>
+       <td>exact:AbsoluteLayout: Click on This is its caption</td>
+</tr>
+<tr>
+       <td>mouseClick</td>
+       <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[1]/VHorizontalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[1]/VGridLayout[0]/domChild[0]/domChild[0]/domChild[1]</td>
+       <td>87,42</td>
+</tr>
+<tr>
+       <td>waitForVaadin</td>
+       <td></td>
+       <td></td>
+</tr>
+<tr>
+       <td>assertText</td>
+       <td>vaadin=runcomvaadintestslayoutsTestLayoutClickListeners::/VVerticalLayout[0]/ChildComponentContainer[0]/VVerticalLayout[0]/ChildComponentContainer[0]/VLabel[0]</td>
+       <td>exact:GridLayout: Click on &lt;none&gt;</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/tests/src/com/vaadin/tests/layouts/TestLayoutClickListeners.java b/tests/src/com/vaadin/tests/layouts/TestLayoutClickListeners.java
new file mode 100644 (file)
index 0000000..a96404e
--- /dev/null
@@ -0,0 +1,195 @@
+package com.vaadin.tests.layouts;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.vaadin.event.LayoutEvents.LayoutClickEvent;
+import com.vaadin.event.LayoutEvents.LayoutClickListener;
+import com.vaadin.tests.components.AbstractTestCase;
+import com.vaadin.ui.AbsoluteLayout;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Component;
+import com.vaadin.ui.GridLayout;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Layout;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+public class TestLayoutClickListeners extends AbstractTestCase {
+
+    private Log log = new Log(5);
+
+    public static class Log extends VerticalLayout {
+        List<Label> eventLabels = new ArrayList<Label>();
+
+        public Log(int nr) {
+            for (int i = 0; i < nr; i++) {
+                Label l = createEventLabel();
+                eventLabels.add(l);
+                addComponent(l);
+            }
+
+            setCaption("Events:");
+        }
+
+        public void clear() {
+            for (Label l : eventLabels) {
+                l.setValue("");
+            }
+        }
+
+        public void log(String event) {
+            int nr = eventLabels.size();
+            for (int i = nr - 1; i > 0; i--) {
+                eventLabels.get(i).setValue(eventLabels.get(i - 1).getValue());
+            }
+            eventLabels.get(0).setValue(event);
+        }
+
+        private Label createEventLabel() {
+            Label l = new Label("&nbsp;", Label.CONTENT_XHTML);
+            l.setWidth(null);
+            return l;
+        }
+
+    }
+
+    @Override
+    public void init() {
+        Window w = new Window("main window");
+        setMainWindow(w);
+        setTheme("tests-tickets");
+
+        HorizontalLayout layoutsLayout = new HorizontalLayout();
+        layoutsLayout.setSpacing(true);
+        w.setContent(layoutsLayout);
+
+        layoutsLayout.addComponent(createClickableGridLayout());
+        layoutsLayout.addComponent(createClickableVerticalLayout());
+        layoutsLayout.addComponent(createClickableAbsoluteLayout());
+
+        VerticalLayout mainLayout = new VerticalLayout();
+        mainLayout.setMargin(true);
+        mainLayout.setSpacing(true);
+        w.setContent(mainLayout);
+        mainLayout.addComponent(log);
+        mainLayout.addComponent(layoutsLayout);
+    }
+
+    private Component createClickableAbsoluteLayout() {
+        final AbsoluteLayout al = new AbsoluteLayout();
+        al.setCaption("AbsoluteLayout");
+        al.setStyleName("borders");
+        al.setWidth("300px");
+        al.setHeight("500px");
+        al.addComponent(new TextField("This is its caption",
+                "This is a textfield"), "top: 60px; left: 0px; width: 100px;");
+        al.addComponent(new TextField("Another textfield caption",
+                "This is another textfield"),
+                "top: 120px; left: 20px; width: 100px;");
+
+        al.addComponent(new Button("A button with its own click listener",
+                new Button.ClickListener() {
+
+                    public void buttonClick(
+                            com.vaadin.ui.Button.ClickEvent event) {
+                        log.log("Button " + event.getButton().getCaption()
+                                + " was clicked");
+
+                    }
+                }));
+        al.addListener(new LayoutClickListener() {
+
+            public void layoutClick(LayoutClickEvent event) {
+                logLayoutClick("AbsoluteLayout", event.getChildComponent());
+            }
+        });
+
+        return al;
+
+    }
+
+    private Layout createClickableGridLayout() {
+
+        GridLayout gl = new GridLayout(4, 4);
+        gl.setHeight("400px");
+        gl.setStyleName("borders");
+        gl.setSpacing(true);
+        addContent(gl, 4);
+        TextField largeTextarea = new TextField("Large textarea");
+        largeTextarea.setWidth("100%");
+        largeTextarea.setHeight("99%");
+        gl.addComponent(largeTextarea, 0, 3, 3, 3);
+
+        gl.addListener(new LayoutClickListener() {
+
+            public void layoutClick(LayoutClickEvent event) {
+                logLayoutClick("GridLayout", event.getChildComponent());
+            }
+        });
+        gl.setRowExpandRatio(3, 1);
+        return wrap(gl, "GridLayout");
+    }
+
+    protected void logLayoutClick(String layout, Component comp) {
+        String target = "&lt;none>";
+        if (comp != null) {
+            target = comp.getCaption();
+            if (target == null && comp instanceof Label) {
+                target = ((Label) comp).getValue().toString();
+            }
+        }
+        log.log(layout + ": Click on " + target);
+
+    }
+
+    private Layout createClickableVerticalLayout() {
+
+        VerticalLayout gl = new VerticalLayout();
+        addContent(gl, 5);
+
+        gl.addListener(new LayoutClickListener() {
+
+            public void layoutClick(LayoutClickEvent event) {
+                logLayoutClick("VerticalLayout", event.getChildComponent());
+
+            }
+        });
+
+        return wrap(gl, "Clickable VerticalLayout");
+    }
+
+    private void addContent(Layout gl, int nr) {
+        for (int i = 1; i < nr; i++) {
+            Label l = new Label("This is label " + i);
+            l.setWidth(null);
+            gl.addComponent(l);
+        }
+        for (int i = nr; i < nr * 2; i++) {
+            gl.addComponent(new TextField("This is tf" + i, "this is tf " + i));
+        }
+    }
+
+    private Layout wrap(Component c, String caption) {
+        VerticalLayout vl = new VerticalLayout();
+        Label l = new Label(caption);
+        l.setWidth(null);
+        vl.addComponent(l);
+        vl.addComponent(c);
+
+        return vl;
+    }
+
+    @Override
+    protected String getDescription() {
+        return "All layouts have click listeners attached and the events are shown in the event log at the top";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 3541;
+    }
+
+}