aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorArtur Signell <artur@vaadin.com>2012-01-26 14:33:28 +0200
committerArtur Signell <artur@vaadin.com>2012-01-26 14:33:28 +0200
commitcc3d673ad83b048a838a8db3198066cad7bd7ab1 (patch)
tree0775310cddfddc602dbaeeb537b062d1c15f5b8e /src
parent1fc3e3d31402db674f4a63ce87932e1f2134ae25 (diff)
downloadvaadin-framework-cc3d673ad83b048a838a8db3198066cad7bd7ab1.tar.gz
vaadin-framework-cc3d673ad83b048a838a8db3198066cad7bd7ab1.zip
Split VScrollTable, VTreeTable and VMenuBar into paintable and
widget classes. Improved VAbstractPaintable
Diffstat (limited to 'src')
-rw-r--r--src/com/vaadin/terminal/gwt/client/ApplicationConnection.java41
-rw-r--r--src/com/vaadin/terminal/gwt/client/Container.java4
-rw-r--r--src/com/vaadin/terminal/gwt/client/Util.java18
-rw-r--r--src/com/vaadin/terminal/gwt/client/VPaintable.java57
-rw-r--r--src/com/vaadin/terminal/gwt/client/VPaintableMap.java11
-rw-r--r--src/com/vaadin/terminal/gwt/client/VPaintableWidget.java3
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/ShortcutActionHandler.java9
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java41
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java11
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java145
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java161
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java386
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java251
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java92
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VTreeTablePaintable.java98
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VUpload.java2
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/label/VLabel.java7
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/label/VLabelPaintable.java22
-rw-r--r--src/com/vaadin/ui/MenuBar.java3
-rw-r--r--src/com/vaadin/ui/Table.java3
-rw-r--r--src/com/vaadin/ui/TreeTable.java7
21 files changed, 809 insertions, 563 deletions
diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
index f8ca0a6959..9b756382f3 100644
--- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
+++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
@@ -36,6 +36,7 @@ import com.vaadin.terminal.gwt.client.ApplicationConfiguration.ErrorMessage;
import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize;
import com.vaadin.terminal.gwt.client.RenderInformation.Size;
import com.vaadin.terminal.gwt.client.ui.Field;
+import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidget;
import com.vaadin.terminal.gwt.client.ui.VContextMenu;
import com.vaadin.terminal.gwt.client.ui.VNotification;
import com.vaadin.terminal.gwt.client.ui.VNotification.HideEvent;
@@ -1586,9 +1587,10 @@ public class ApplicationConnection {
*
* @return Returns true iff no further painting is needed by caller
*/
- public boolean updateComponent(Widget component, UIDL uidl,
+ @Deprecated
+ public boolean updateComponent(VPaintableWidget paintable, UIDL uidl,
boolean manageCaption) {
- VPaintableWidget paintable = paintableMap.getPaintable(component);
+ Widget component = paintable.getWidgetForPaintable();
String pid = paintableMap.getPid(paintable);
if (pid == null) {
@@ -2029,6 +2031,10 @@ public class ApplicationConnection {
if (!paintableMap.hasPaintable(pid)) {
// Create and register a new paintable if no old was found
VPaintableWidget p = widgetSet.createWidget(uidl, configuration);
+ if (p instanceof VAbstractPaintableWidget) {
+ ((VAbstractPaintableWidget) p).setConnection(this);
+ ((VAbstractPaintableWidget) p).init();
+ }
paintableMap.registerPaintable(pid, p);
}
return (VPaintableWidget) paintableMap.getPaintable(pid);
@@ -2192,7 +2198,7 @@ public class ApplicationConnection {
}
};
- private VPaintableMap paintableMap = new VPaintableMap();
+ private VPaintableMap paintableMap = GWT.create(VPaintableMap.class);
/**
* Components can call this function to run all layout functions. This is
@@ -2275,7 +2281,7 @@ public class ApplicationConnection {
* @return true if at least one listener has been registered on server side
* for the event identified by eventIdentifier.
*/
- public boolean hasEventListeners(VPaintable paintable,
+ public boolean hasEventListeners(VPaintableWidget paintable,
String eventIdentifier) {
return paintableMap.hasEventListeners(paintable, eventIdentifier);
}
@@ -2330,4 +2336,31 @@ public class ApplicationConnection {
paintableMap.unregisterPaintable(p);
}
+ public VTooltip getVTooltip() {
+ return tooltip;
+ }
+
+ @Deprecated
+ public void handleWidgetTooltipEvent(Event event, Widget owner, Object key) {
+ handleTooltipEvent(event, getPaintableMap().getPaintable(owner), key);
+
+ }
+
+ @Deprecated
+ public void handleWidgetTooltipEvent(Event event, Widget owner) {
+ handleTooltipEvent(event, getPaintableMap().getPaintable(owner));
+
+ }
+
+ @Deprecated
+ public void registerWidgetTooltip(Widget owner, Object key, TooltipInfo info) {
+ registerTooltip(getPaintableMap().getPaintable(owner), key, info);
+ }
+
+ @Deprecated
+ public boolean hasWidgetEventListeners(Widget widget, String eventIdentifier) {
+ return hasEventListeners(getPaintableMap().getPaintable(widget),
+ eventIdentifier);
+ }
+
}
diff --git a/src/com/vaadin/terminal/gwt/client/Container.java b/src/com/vaadin/terminal/gwt/client/Container.java
index 7c92bc261b..db6bbf0ee4 100644
--- a/src/com/vaadin/terminal/gwt/client/Container.java
+++ b/src/com/vaadin/terminal/gwt/client/Container.java
@@ -42,12 +42,12 @@ public interface Container extends VPaintableWidget {
* must provide service for it's childen to show those elements for them.
* </p>
*
- * @param component
+ * @param paintable
* Child component for which service is requested.
* @param uidl
* UIDL of the child component.
*/
- void updateCaption(VPaintableWidget component, UIDL uidl);
+ void updateCaption(VPaintableWidget paintable, UIDL uidl);
/**
* Called when a child components size has been updated in the rendering
diff --git a/src/com/vaadin/terminal/gwt/client/Util.java b/src/com/vaadin/terminal/gwt/client/Util.java
index 597ca3d49c..2a3fc07195 100644
--- a/src/com/vaadin/terminal/gwt/client/Util.java
+++ b/src/com/vaadin/terminal/gwt/client/Util.java
@@ -830,6 +830,24 @@ public class Util {
}-*/;
/**
+ * Helper method to find the nearest parent paintable instance by traversing
+ * the DOM upwards from given element.
+ *
+ * @param element
+ * the element to start from
+ */
+ public static VPaintableWidget findPaintable(ApplicationConnection client,
+ Element element) {
+ Widget widget = Util.findWidget(element, null);
+ VPaintableMap vPaintableMap = VPaintableMap.get(client);
+ while (widget != null && !vPaintableMap.isPaintable(widget)) {
+ widget = widget.getParent();
+ }
+ return vPaintableMap.getPaintable(widget);
+
+ }
+
+ /**
* Helper method to find first instance of given Widget type found by
* traversing DOM upwards from given element.
*
diff --git a/src/com/vaadin/terminal/gwt/client/VPaintable.java b/src/com/vaadin/terminal/gwt/client/VPaintable.java
index 02b529b428..d85c6d33e2 100644
--- a/src/com/vaadin/terminal/gwt/client/VPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/VPaintable.java
@@ -4,8 +4,13 @@
package com.vaadin.terminal.gwt.client;
/**
- * TODO
+ * Interface implemented by all client side classes that can be communicate with
+ * the server. Classes implementing this interface are initialized by the
+ * framework when needed and have the ability to communicate with the server.
*
+ * @author Vaadin Ltd
+ * @version @VERSION@
+ * @since 7.0.0
*/
public interface VPaintable {
/**
@@ -16,4 +21,54 @@ public interface VPaintable {
*/
public void updateFromUIDL(UIDL uidl, ApplicationConnection client);
+ // /**
+ // * Returns the id for this VPaintable. This must always be what has been
+ // set
+ // * using {@link #setId(String)}.
+ // *
+ // * @return The id for the VPaintable.
+ // */
+ // public String getId();
+ //
+ // /**
+ // * Sets the id for the VPaintable. This method is called once by the
+ // * framework when the VPaintable is initialized and should never be called
+ // * otherwise.
+ // * <p>
+ // * The VPaintable id is used to map the server and the client paintables
+ // * together. It is unique in this root and assigned by the framework.
+ // * </p>
+ // *
+ // * @param id
+ // * The id of the paintable.
+ // */
+ // public void setId(String id);
+
+ /**
+ * Gets ApplicationConnection instance that created this VPaintable.
+ *
+ * @return The ApplicationConnection as set by
+ * {@link #setConnection(ApplicationConnection)}
+ */
+ // public ApplicationConnection getConnection();
+
+ /**
+ * Sets the reference to ApplicationConnection. This method is called by the
+ * framework when the VPaintable is created and should never be called
+ * otherwise.
+ *
+ * @param connection
+ * The ApplicationConnection that created this VPaintable
+ */
+ // public void setConnection(ApplicationConnection connection);
+
+ /**
+ * Tests whether the component is enabled or not. A user can not interact
+ * with disabled components. Disabled components are rendered in a style
+ * that indicates the status, usually in gray color. Children of a disabled
+ * component are also disabled.
+ *
+ * @return true if the component is enabled, false otherwise
+ */
+ // public boolean isEnabled();
}
diff --git a/src/com/vaadin/terminal/gwt/client/VPaintableMap.java b/src/com/vaadin/terminal/gwt/client/VPaintableMap.java
index ef355d3cad..f21d85558c 100644
--- a/src/com/vaadin/terminal/gwt/client/VPaintableMap.java
+++ b/src/com/vaadin/terminal/gwt/client/VPaintableMap.java
@@ -335,7 +335,7 @@ public class VPaintableMap {
}
- private ComponentDetail getComponentDetail(VPaintable paintable) {
+ private ComponentDetail getComponentDetail(VPaintableWidget paintable) {
return idToComponentDetail.get(getPid(paintable));
}
@@ -344,7 +344,7 @@ public class VPaintableMap {
}
/**
- * FIXME: Should not be here
+ * FIXME: Should be moved to VAbstractPaintableWidget
*
* @param paintable
* @return
@@ -354,6 +354,11 @@ public class VPaintableMap {
return getComponentDetail(paintable).getTooltipInfo(key);
}
+ @Deprecated
+ public TooltipInfo getWidgetTooltipInfo(Widget widget, Object key) {
+ return getTooltipInfo(getPaintable(widget), key);
+ }
+
public Collection<? extends VPaintable> getPaintables() {
return Collections.unmodifiableCollection(paintableToId.keySet());
}
@@ -378,7 +383,7 @@ public class VPaintableMap {
* @return
*/
@Deprecated
- public boolean hasEventListeners(VPaintable paintable,
+ public boolean hasEventListeners(VPaintableWidget paintable,
String eventIdentifier) {
return getComponentDetail(paintable).hasEventListeners(eventIdentifier);
}
diff --git a/src/com/vaadin/terminal/gwt/client/VPaintableWidget.java b/src/com/vaadin/terminal/gwt/client/VPaintableWidget.java
index 9171fdceda..2f0cae1cc1 100644
--- a/src/com/vaadin/terminal/gwt/client/VPaintableWidget.java
+++ b/src/com/vaadin/terminal/gwt/client/VPaintableWidget.java
@@ -17,7 +17,8 @@ import com.google.gwt.user.client.ui.Widget;
public interface VPaintableWidget extends VPaintable {
/**
- * TODO: Renamed to getWidget
+ * TODO: Rename to getWidget
*/
public Widget getWidgetForPaintable();
+
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/ShortcutActionHandler.java b/src/com/vaadin/terminal/gwt/client/ui/ShortcutActionHandler.java
index 38f7878ba4..2bd578a45d 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/ShortcutActionHandler.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/ShortcutActionHandler.java
@@ -15,13 +15,11 @@ import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.KeyboardListenerCollection;
-import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.Container;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.VPaintableMap;
import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.ui.richtextarea.VRichTextArea;
@@ -137,12 +135,7 @@ public class ShortcutActionHandler {
VPaintableWidget target) {
final Element et = DOM.eventGetTarget(event);
if (target == null) {
- Widget w = Util.findWidget(et, null);
- VPaintableMap paintableMap = VPaintableMap.get(client);
- while (w != null && !paintableMap.isPaintable(w)) {
- w = w.getParent();
- }
- target = paintableMap.getPaintable(w);
+ target = Util.findPaintable(client, et);
}
final VPaintableWidget finalTarget = target;
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java b/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java
index dff5a286ba..d4c8f79467 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VAbstractPaintableWidget.java
@@ -1,12 +1,16 @@
package com.vaadin.terminal.gwt.client.ui;
-import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.VPaintableWidget;
public abstract class VAbstractPaintableWidget implements VPaintableWidget {
private Widget widget;
+ private ApplicationConnection connection;
+
+ /* State variables */
+// private boolean enabled = true;
/**
* Default constructor
@@ -15,14 +19,18 @@ public abstract class VAbstractPaintableWidget implements VPaintableWidget {
}
/**
+ * Called after the application connection reference has been set up
+ */
+ public void init() {
+ }
+
+ /**
* Creates and returns the widget for this VPaintableWidget. This method
* should only be called once when initializing the paintable.
*
* @return
*/
- protected Widget createWidget() {
- return GWT.create(getWidgetClass());
- }
+ protected abstract Widget createWidget();
/**
* Returns the widget associated with this paintable. The widget returned by
@@ -38,12 +46,27 @@ public abstract class VAbstractPaintableWidget implements VPaintableWidget {
return widget;
}
- /**
- * Returns the class of the widget for this paintable. Used to instansiate
- * the widget.
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.vaadin.terminal.gwt.client.VPaintable#getConnection()
+ */
+ public final ApplicationConnection getConnection() {
+ return connection;
+ }
+
+ /*
+ * (non-Javadoc)
*
- * @return The widget class.
+ * @see
+ * com.vaadin.terminal.gwt.client.VPaintable#setConnection(com.vaadin.terminal
+ * .gwt.client.ApplicationConnection)
*/
- protected abstract Class<? extends Widget> getWidgetClass();
+ public final void setConnection(ApplicationConnection connection) {
+ this.connection = connection;
+ }
+// public boolean isEnabled() {
+// return enabled;
+// }
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java
index da916f262e..3251a03d6a 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java
@@ -113,14 +113,9 @@ public class VDragAndDropWrapper extends VCustomComponent implements
VTransferable transferable = new VTransferable();
transferable.setDragSource(VDragAndDropWrapper.this);
- Widget widget = Util.findWidget((Element) event.getEventTarget()
- .cast(), null);
- VPaintableMap vPaintableMap = VPaintableMap.get(client);
- while (widget != null && !vPaintableMap.isPaintable(widget)) {
- widget = widget.getParent();
- }
- VPaintableWidget paintable = vPaintableMap.getPaintable(widget);
-
+ VPaintableWidget paintable = Util.findPaintable(client,
+ (Element) event.getEventTarget().cast());
+ Widget widget = paintable.getWidgetForPaintable();
transferable.setData("component", paintable);
VDragEvent dragEvent = VDragAndDropManager.get().startDrag(
transferable, event, true);
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java b/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java
index 306086e357..372ddf25d2 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VMenuBar.java
@@ -4,9 +4,7 @@
package com.vaadin.terminal.gwt.client.ui;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
-import java.util.Stack;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
@@ -35,14 +33,12 @@ import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.ContainerResizedListener;
-import com.vaadin.terminal.gwt.client.VPaintableMap;
import com.vaadin.terminal.gwt.client.TooltipInfo;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.VTooltip;
-public class VMenuBar extends SimpleFocusablePanel implements VPaintableWidget,
+public class VMenuBar extends SimpleFocusablePanel implements
CloseHandler<PopupPanel>, ContainerResizedListener, KeyPressHandler,
KeyDownHandler, FocusHandler, SubPartAware {
@@ -82,7 +78,7 @@ public class VMenuBar extends SimpleFocusablePanel implements VPaintableWidget,
protected VMenuBar parentMenu;
protected CustomMenuItem selected;
- private boolean enabled = true;
+ boolean enabled = true;
private String width = "notinited";
@@ -94,9 +90,9 @@ public class VMenuBar extends SimpleFocusablePanel implements VPaintableWidget,
}
});
- private boolean openRootOnHover;
+ boolean openRootOnHover;
- private boolean htmlContentAllowed;
+ boolean htmlContentAllowed;
public VMenuBar() {
// Create an empty horizontal menubar
@@ -168,133 +164,6 @@ public class VMenuBar extends SimpleFocusablePanel implements VPaintableWidget,
}
/**
- * This method must be implemented to update the client-side component from
- * UIDL data received from server.
- *
- * This method is called when the page is loaded for the first time, and
- * every time UI changes in the component are received from the server.
- */
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- // This call should be made first. Ensure correct implementation,
- // and let the containing layout manage caption, etc.
- if (client.updateComponent(this, uidl, true)) {
- return;
- }
-
- htmlContentAllowed = uidl.hasAttribute(HTML_CONTENT_ALLOWED);
-
- openRootOnHover = uidl.getBooleanAttribute(OPEN_ROOT_MENU_ON_HOWER);
-
- enabled = !uidl.getBooleanAttribute("disabled");
-
- // For future connections
- this.client = client;
- uidlId = uidl.getId();
-
- // Empty the menu every time it receives new information
- if (!getItems().isEmpty()) {
- clearItems();
- }
-
- UIDL options = uidl.getChildUIDL(0);
-
- if (uidl.hasAttribute("width")) {
- UIDL moreItemUIDL = options.getChildUIDL(0);
- StringBuffer itemHTML = new StringBuffer();
-
- if (moreItemUIDL.hasAttribute("icon")) {
- itemHTML.append("<img src=\""
- + Util.escapeAttribute(client
- .translateVaadinUri(moreItemUIDL
- .getStringAttribute("icon")))
- + "\" class=\"" + Icon.CLASSNAME + "\" alt=\"\" />");
- }
-
- String moreItemText = moreItemUIDL.getStringAttribute("text");
- if ("".equals(moreItemText)) {
- moreItemText = "&#x25BA;";
- }
- itemHTML.append(moreItemText);
-
- moreItem = GWT.create(CustomMenuItem.class);
- moreItem.setHTML(itemHTML.toString());
- moreItem.setCommand(emptyCommand);
-
- collapsedRootItems = new VMenuBar(true, (VMenuBar) VPaintableMap
- .get(client).getPaintable(uidlId));
- moreItem.setSubMenu(collapsedRootItems);
- moreItem.addStyleName(CLASSNAME + "-more-menuitem");
- }
-
- UIDL uidlItems = uidl.getChildUIDL(1);
- Iterator<Object> itr = uidlItems.getChildIterator();
- Stack<Iterator<Object>> iteratorStack = new Stack<Iterator<Object>>();
- Stack<VMenuBar> menuStack = new Stack<VMenuBar>();
- VMenuBar currentMenu = this;
-
- while (itr.hasNext()) {
- UIDL item = (UIDL) itr.next();
- CustomMenuItem currentItem = null;
-
- final int itemId = item.getIntAttribute("id");
-
- boolean itemHasCommand = item.hasAttribute("command");
- boolean itemIsCheckable = item.hasAttribute(ATTRIBUTE_CHECKED);
-
- String itemHTML = buildItemHTML(item);
-
- Command cmd = null;
- if (!item.hasAttribute("separator")) {
- if (itemHasCommand || itemIsCheckable) {
- // Construct a command that fires onMenuClick(int) with the
- // item's id-number
- cmd = new Command() {
- public void execute() {
- hostReference.onMenuClick(itemId);
- }
- };
- }
- }
-
- currentItem = currentMenu.addItem(itemHTML.toString(), cmd);
- currentItem.updateFromUIDL(item, client);
-
- if (item.getChildCount() > 0) {
- menuStack.push(currentMenu);
- iteratorStack.push(itr);
- itr = item.getChildIterator();
- currentMenu = new VMenuBar(true, currentMenu);
- if (uidl.hasAttribute("style")) {
- for (String style : uidl.getStringAttribute("style").split(
- " ")) {
- currentMenu.addStyleDependentName(style);
- }
- }
- currentItem.setSubMenu(currentMenu);
- }
-
- while (!itr.hasNext() && !iteratorStack.empty()) {
- boolean hasCheckableItem = false;
- for (CustomMenuItem menuItem : currentMenu.getItems()) {
- hasCheckableItem = hasCheckableItem
- || menuItem.isCheckable();
- }
- if (hasCheckableItem) {
- currentMenu.addStyleDependentName("check-column");
- } else {
- currentMenu.removeStyleDependentName("check-column");
- }
-
- itr = iteratorStack.pop();
- currentMenu = menuStack.pop();
- }
- }// while
-
- iLayout(false);
-
- }// updateFromUIDL
-
- /**
* Build the HTML content for a menu item.
*
* @param item
@@ -473,7 +342,7 @@ public class VMenuBar extends SimpleFocusablePanel implements VPaintableWidget,
// Handle tooltips
if (targetItem == null && client != null) {
// Handle root menubar tooltips
- client.handleTooltipEvent(e, this);
+ client.handleWidgetTooltipEvent(e, this);
} else if (targetItem != null) {
// Handle item tooltips
targetItem.onBrowserEvent(e);
@@ -1051,7 +920,7 @@ public class VMenuBar extends SimpleFocusablePanel implements VPaintableWidget,
TooltipInfo info = new TooltipInfo(description);
VMenuBar root = findRootMenu();
- client.registerTooltip(root, this, info);
+ client.registerWidgetTooltip(root, this, info);
}
}
@@ -1059,7 +928,7 @@ public class VMenuBar extends SimpleFocusablePanel implements VPaintableWidget,
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
if (client != null) {
- client.handleTooltipEvent(event, findRootMenu(), this);
+ client.handleWidgetTooltipEvent(event, findRootMenu(), this);
}
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java
new file mode 100644
index 0000000000..38b3cac358
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VMenuBarPaintable.java
@@ -0,0 +1,161 @@
+package com.vaadin.terminal.gwt.client.ui;
+
+import java.util.Iterator;
+import java.util.Stack;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VPaintableMap;
+import com.vaadin.terminal.gwt.client.ui.VMenuBar.CustomMenuItem;
+
+public class VMenuBarPaintable extends VAbstractPaintableWidget {
+ /**
+ * This method must be implemented to update the client-side component from
+ * UIDL data received from server.
+ *
+ * This method is called when the page is loaded for the first time, and
+ * every time UI changes in the component are received from the server.
+ */
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ // This call should be made first. Ensure correct implementation,
+ // and let the containing layout manage caption, etc.
+ if (client.updateComponent(this, uidl, true)) {
+ return;
+ }
+
+ getWidgetForPaintable().htmlContentAllowed = uidl
+ .hasAttribute(VMenuBar.HTML_CONTENT_ALLOWED);
+
+ getWidgetForPaintable().openRootOnHover = uidl
+ .getBooleanAttribute(VMenuBar.OPEN_ROOT_MENU_ON_HOWER);
+
+ getWidgetForPaintable().enabled = !uidl.getBooleanAttribute("disabled");
+
+ // For future connections
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().uidlId = uidl.getId();
+
+ // Empty the menu every time it receives new information
+ if (!getWidgetForPaintable().getItems().isEmpty()) {
+ getWidgetForPaintable().clearItems();
+ }
+
+ UIDL options = uidl.getChildUIDL(0);
+
+ if (uidl.hasAttribute("width")) {
+ UIDL moreItemUIDL = options.getChildUIDL(0);
+ StringBuffer itemHTML = new StringBuffer();
+
+ if (moreItemUIDL.hasAttribute("icon")) {
+ itemHTML.append("<img src=\""
+ + Util.escapeAttribute(client
+ .translateVaadinUri(moreItemUIDL
+ .getStringAttribute("icon")))
+ + "\" class=\"" + Icon.CLASSNAME + "\" alt=\"\" />");
+ }
+
+ String moreItemText = moreItemUIDL.getStringAttribute("text");
+ if ("".equals(moreItemText)) {
+ moreItemText = "&#x25BA;";
+ }
+ itemHTML.append(moreItemText);
+
+ getWidgetForPaintable().moreItem = GWT.create(CustomMenuItem.class);
+ getWidgetForPaintable().moreItem.setHTML(itemHTML.toString());
+ getWidgetForPaintable().moreItem
+ .setCommand(getWidgetForPaintable().emptyCommand);
+
+ getWidgetForPaintable().collapsedRootItems = new VMenuBar(true,
+ (VMenuBar) VPaintableMap.get(client).getPaintable(
+ getWidgetForPaintable().uidlId));
+ getWidgetForPaintable().moreItem
+ .setSubMenu(getWidgetForPaintable().collapsedRootItems);
+ getWidgetForPaintable().moreItem.addStyleName(VMenuBar.CLASSNAME
+ + "-more-menuitem");
+ }
+
+ UIDL uidlItems = uidl.getChildUIDL(1);
+ Iterator<Object> itr = uidlItems.getChildIterator();
+ Stack<Iterator<Object>> iteratorStack = new Stack<Iterator<Object>>();
+ Stack<VMenuBar> menuStack = new Stack<VMenuBar>();
+ VMenuBar currentMenu = getWidgetForPaintable();
+
+ while (itr.hasNext()) {
+ UIDL item = (UIDL) itr.next();
+ CustomMenuItem currentItem = null;
+
+ final int itemId = item.getIntAttribute("id");
+
+ boolean itemHasCommand = item.hasAttribute("command");
+ boolean itemIsCheckable = item
+ .hasAttribute(VMenuBar.ATTRIBUTE_CHECKED);
+
+ String itemHTML = getWidgetForPaintable().buildItemHTML(item);
+
+ Command cmd = null;
+ if (!item.hasAttribute("separator")) {
+ if (itemHasCommand || itemIsCheckable) {
+ // Construct a command that fires onMenuClick(int) with the
+ // item's id-number
+ cmd = new Command() {
+ public void execute() {
+ getWidgetForPaintable().hostReference
+ .onMenuClick(itemId);
+ }
+ };
+ }
+ }
+
+ currentItem = currentMenu.addItem(itemHTML.toString(), cmd);
+ currentItem.updateFromUIDL(item, client);
+
+ if (item.getChildCount() > 0) {
+ menuStack.push(currentMenu);
+ iteratorStack.push(itr);
+ itr = item.getChildIterator();
+ currentMenu = new VMenuBar(true, currentMenu);
+ if (uidl.hasAttribute("style")) {
+ for (String style : uidl.getStringAttribute("style").split(
+ " ")) {
+ currentMenu.addStyleDependentName(style);
+ }
+ }
+ currentItem.setSubMenu(currentMenu);
+ }
+
+ while (!itr.hasNext() && !iteratorStack.empty()) {
+ boolean hasCheckableItem = false;
+ for (CustomMenuItem menuItem : currentMenu.getItems()) {
+ hasCheckableItem = hasCheckableItem
+ || menuItem.isCheckable();
+ }
+ if (hasCheckableItem) {
+ currentMenu.addStyleDependentName("check-column");
+ } else {
+ currentMenu.removeStyleDependentName("check-column");
+ }
+
+ itr = iteratorStack.pop();
+ currentMenu = menuStack.pop();
+ }
+ }// while
+
+ getWidgetForPaintable().iLayout(false);
+
+ }// updateFromUIDL
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VMenuBar.class);
+ }
+
+ @Override
+ public VMenuBar getWidgetForPaintable() {
+ return (VMenuBar) super.getWidgetForPaintable();
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
index 736635ecd0..41b7efcf02 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java
@@ -52,6 +52,7 @@ import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.UIObject;
@@ -103,17 +104,31 @@ import com.vaadin.terminal.gwt.client.ui.label.VLabel;
*
* TODO implement unregistering for child components in Cells
*/
-public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
- VHasDropHandler, FocusHandler, BlurHandler, Focusable, ActionOwner {
+public class VScrollTable extends FlowPanel implements HasWidgets,
+ ScrollHandler, VHasDropHandler, FocusHandler, BlurHandler, Focusable,
+ ActionOwner {
- public static final String ATTRIBUTE_PAGEBUFFER_FIRST = "pb-ft";
- public static final String ATTRIBUTE_PAGEBUFFER_LAST = "pb-l";
+ public enum SelectMode {
+ NONE(0), SINGLE(1), MULTI(2);
+ private int id;
+
+ private SelectMode(int id) {
+ this.id = id;
+ }
+
+ public int getId() {
+ return id;
+ }
+ }
private static final String ROW_HEADER_COLUMN_KEY = "0";
public static final String CLASSNAME = "v-table";
public static final String CLASSNAME_SELECTION_FOCUS = CLASSNAME + "-focus";
+ public static final String ATTRIBUTE_PAGEBUFFER_FIRST = "pb-ft";
+ public static final String ATTRIBUTE_PAGEBUFFER_LAST = "pb-l";
+
public static final String ITEM_CLICK_EVENT_ID = "itemClick";
public static final String HEADER_CLICK_EVENT_ID = "handleHeaderClick";
public static final String FOOTER_CLICK_EVENT_ID = "handleFooterClick";
@@ -162,10 +177,10 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
protected ApplicationConnection client;
protected String paintableId;
- private boolean immediate;
+ boolean immediate;
private boolean nullSelectionAllowed = true;
- private int selectMode = Table.SELECT_MODE_NONE;
+ private SelectMode selectMode = SelectMode.NONE;
private final HashSet<String> selectedRowKeys = new HashSet<String>();
@@ -178,15 +193,15 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
/*
* These are used when jumping between pages when pressing Home and End
*/
- private boolean selectLastItemInNextRender = false;
- private boolean selectFirstItemInNextRender = false;
- private boolean focusFirstItemInNextRender = false;
- private boolean focusLastItemInNextRender = false;
+ boolean selectLastItemInNextRender = false;
+ boolean selectFirstItemInNextRender = false;
+ boolean focusFirstItemInNextRender = false;
+ boolean focusLastItemInNextRender = false;
/*
* The currently focused row
*/
- private VScrollTableRow focusedRow;
+ VScrollTableRow focusedRow;
/*
* Helper to store selection range start in when using the keyboard
@@ -197,7 +212,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
* Flag for notifying when the selection has changed and should be sent to
* the server
*/
- private boolean selectionChanged = false;
+ boolean selectionChanged = false;
/*
* The speed (in pixels) which the scrolling scrolls vertically/horizontally
@@ -206,7 +221,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
private Timer scrollingVelocityTimer = null;
- private String[] bodyActionKeys;
+ String[] bodyActionKeys;
private boolean enableDebug = false;
@@ -282,19 +297,18 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
private final HashSet<SelectionRange> selectedRowRanges = new HashSet<SelectionRange>();
- private boolean initializedAndAttached = false;
+ boolean initializedAndAttached = false;
/**
* Flag to indicate if a column width recalculation is needed due update.
*/
- private boolean headerChangedDuringUpdate = false;
+ boolean headerChangedDuringUpdate = false;
protected final TableHead tHead = new TableHead();
- private final TableFooter tFoot = new TableFooter();
+ final TableFooter tFoot = new TableFooter();
- private final FocusableScrollPanel scrollBodyPanel = new FocusableScrollPanel(
- true);
+ final FocusableScrollPanel scrollBodyPanel = new FocusableScrollPanel(true);
private KeyPressHandler navKeyPressHandler = new KeyPressHandler() {
public void onKeyPress(KeyPressEvent keyPressEvent) {
@@ -383,12 +397,12 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
}
}
};
- private int totalRows;
+ int totalRows;
private Set<String> collapsedColumns;
- private final RowRequestHandler rowRequestHandler;
- private VScrollTableBody scrollBody;
+ final RowRequestHandler rowRequestHandler;
+ VScrollTableBody scrollBody;
private int firstvisible = 0;
private boolean sortAscending;
private String sortColumn;
@@ -403,9 +417,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
private String[] visibleColOrder;
private boolean initialContentReceived = false;
private Element scrollPositionElement;
- private boolean enabled;
- private boolean showColHeaders;
- private boolean showColFooters;
+ boolean enabled;
+ boolean showColHeaders;
+ boolean showColFooters;
/** flag to indicate that table body has changed */
private boolean isNewBody = true;
@@ -420,15 +434,15 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
private final ArrayList<Panel> lazyUnregistryBag = new ArrayList<Panel>();
private String height;
private String width = "";
- private boolean rendering = false;
+ boolean rendering = false;
private boolean hasFocus = false;
private int dragmode;
private int multiselectmode;
- private int tabIndex;
+ int tabIndex;
private TouchScrollDelegate touchScrollDelegate;
- private int lastRenderedHeight;
+ int lastRenderedHeight;
/**
* Values (serverCacheFirst+serverCacheLast) sent by server that tells which
@@ -442,8 +456,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
* scrolling in the client will cause empty buttons to be rendered
* (cached=true request for non-existing components)
*/
- private int serverCacheFirst = -1;
- private int serverCacheLast = -1;
+ int serverCacheFirst = -1;
+ int serverCacheLast = -1;
public VScrollTable() {
setMultiSelectMode(MULTISELECT_MODE_DEFAULT);
@@ -810,211 +824,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
return KeyCodes.KEY_END;
}
- /*
- * (non-Javadoc)
- *
- * @see
- * com.vaadin.terminal.gwt.client.Paintable#updateFromUIDL(com.vaadin.terminal
- * .gwt.client.UIDL, com.vaadin.terminal.gwt.client.ApplicationConnection)
- */
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- rendering = true;
-
- if (uidl.hasAttribute(ATTRIBUTE_PAGEBUFFER_FIRST)) {
- serverCacheFirst = uidl.getIntAttribute(ATTRIBUTE_PAGEBUFFER_FIRST);
- serverCacheLast = uidl.getIntAttribute(ATTRIBUTE_PAGEBUFFER_LAST);
- } else {
- serverCacheFirst = -1;
- serverCacheLast = -1;
- }
- /*
- * We need to do this before updateComponent since updateComponent calls
- * this.setHeight() which will calculate a new body height depending on
- * the space available.
- */
- if (uidl.hasAttribute("colfooters")) {
- showColFooters = uidl.getBooleanAttribute("colfooters");
- }
-
- tFoot.setVisible(showColFooters);
-
- if (client.updateComponent(this, uidl, true)) {
- rendering = false;
- return;
- }
-
- enabled = !uidl.hasAttribute("disabled");
-
- if (BrowserInfo.get().isIE8() && !enabled) {
- /*
- * The disabled shim will not cover the table body if it is relative
- * in IE8. See #7324
- */
- scrollBodyPanel.getElement().getStyle()
- .setPosition(Position.STATIC);
- } else if (BrowserInfo.get().isIE8()) {
- scrollBodyPanel.getElement().getStyle()
- .setPosition(Position.RELATIVE);
- }
-
- this.client = client;
- paintableId = uidl.getStringAttribute("id");
- immediate = uidl.getBooleanAttribute("immediate");
-
- int previousTotalRows = totalRows;
- updateTotalRows(uidl);
- boolean totalRowsChanged = (totalRows != previousTotalRows);
-
- updateDragMode(uidl);
-
- updateSelectionProperties(uidl);
-
- if (uidl.hasAttribute("alb")) {
- bodyActionKeys = uidl.getStringArrayAttribute("alb");
- } else {
- // Need to clear the actions if the action handlers have been
- // removed
- bodyActionKeys = null;
- }
-
- setCacheRateFromUIDL(uidl);
-
- recalcWidths = uidl.hasAttribute("recalcWidths");
- if (recalcWidths) {
- tHead.clear();
- tFoot.clear();
- }
-
- updatePageLength(uidl);
-
- updateFirstVisibleAndScrollIfNeeded(uidl);
-
- showRowHeaders = uidl.getBooleanAttribute("rowheaders");
- showColHeaders = uidl.getBooleanAttribute("colheaders");
-
- updateSortingProperties(uidl);
-
- boolean keyboardSelectionOverRowFetchInProgress = selectSelectedRows(uidl);
-
- updateActionMap(uidl);
-
- updateColumnProperties(uidl);
-
- UIDL ac = uidl.getChildByTagName("-ac");
- if (ac == null) {
- if (dropHandler != null) {
- // remove dropHandler if not present anymore
- dropHandler = null;
- }
- } else {
- if (dropHandler == null) {
- dropHandler = new VScrollTableDropHandler();
- }
- dropHandler.updateAcceptRules(ac);
- }
-
- UIDL partialRowAdditions = uidl.getChildByTagName("prows");
- UIDL partialRowUpdates = uidl.getChildByTagName("urows");
- if (partialRowUpdates != null || partialRowAdditions != null) {
- // we may have pending cache row fetch, cancel it. See #2136
- rowRequestHandler.cancel();
-
- updateRowsInBody(partialRowUpdates);
- addAndRemoveRows(partialRowAdditions);
- } else {
- UIDL rowData = uidl.getChildByTagName("rows");
- if (rowData != null) {
- // we may have pending cache row fetch, cancel it. See #2136
- rowRequestHandler.cancel();
-
- if (!recalcWidths && initializedAndAttached) {
- updateBody(rowData, uidl.getIntAttribute("firstrow"),
- uidl.getIntAttribute("rows"));
- if (headerChangedDuringUpdate) {
- triggerLazyColumnAdjustment(true);
- } else if (!isScrollPositionVisible()
- || totalRowsChanged
- || lastRenderedHeight != scrollBody
- .getOffsetHeight()) {
- // webkits may still bug with their disturbing scrollbar
- // bug, see #3457
- // Run overflow fix for the scrollable area
- // #6698 - If there's a scroll going on, don't abort it
- // by changing overflows as the length of the contents
- // *shouldn't* have changed (unless the number of rows
- // or the height of the widget has also changed)
- Scheduler.get().scheduleDeferred(new Command() {
- public void execute() {
- Util.runWebkitOverflowAutoFix(scrollBodyPanel
- .getElement());
- }
- });
- }
- } else {
- initializeRows(uidl, rowData);
- }
- }
- }
-
- if (!isSelectable()) {
- scrollBody.addStyleName(CLASSNAME + "-body-noselection");
- } else {
- scrollBody.removeStyleName(CLASSNAME + "-body-noselection");
- }
-
- hideScrollPositionAnnotation();
- purgeUnregistryBag();
-
- // selection is no in sync with server, avoid excessive server visits by
- // clearing to flag used during the normal operation
- if (!keyboardSelectionOverRowFetchInProgress) {
- selectionChanged = false;
- }
-
- /*
- * This is called when the Home or page up button has been pressed in
- * selectable mode and the next selected row was not yet rendered in the
- * client
- */
- if (selectFirstItemInNextRender || focusFirstItemInNextRender) {
- selectFirstRenderedRowInViewPort(focusFirstItemInNextRender);
- selectFirstItemInNextRender = focusFirstItemInNextRender = false;
- }
-
- /*
- * This is called when the page down or end button has been pressed in
- * selectable mode and the next selected row was not yet rendered in the
- * client
- */
- if (selectLastItemInNextRender || focusLastItemInNextRender) {
- selectLastRenderedRowInViewPort(focusLastItemInNextRender);
- selectLastItemInNextRender = focusLastItemInNextRender = false;
- }
- multiselectPending = false;
-
- if (focusedRow != null) {
- if (!focusedRow.isAttached() && !rowRequestHandler.isRunning()) {
- // focused row has been orphaned, can't focus
- focusRowFromBody();
- }
- }
-
- tabIndex = uidl.hasAttribute("tabindex") ? uidl
- .getIntAttribute("tabindex") : 0;
- setProperTabIndex();
-
- resizeSortedColumnForSortIndicator();
-
- // Remember this to detect situations where overflow hack might be
- // needed during scrolling
- lastRenderedHeight = scrollBody.getOffsetHeight();
-
- rendering = false;
- headerChangedDuringUpdate = false;
-
- }
-
- private void initializeRows(UIDL uidl, UIDL rowData) {
+ void initializeRows(UIDL uidl, UIDL rowData) {
if (scrollBody != null) {
scrollBody.removeFromParent();
lazyUnregistryBag.add(scrollBody);
@@ -1037,7 +847,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
scrollBody.restoreRowVisibility();
}
- private void updateColumnProperties(UIDL uidl) {
+ void updateColumnProperties(UIDL uidl) {
updateColumnOrder(uidl);
updateCollapsedColumns(uidl);
@@ -1072,7 +882,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
}
}
- private boolean selectSelectedRows(UIDL uidl) {
+ boolean selectSelectedRows(UIDL uidl) {
boolean keyboardSelectionOverRowFetchInProgress = false;
if (uidl.hasVariable("selected")) {
@@ -1109,7 +919,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
return keyboardSelectionOverRowFetchInProgress;
}
- private void updateSortingProperties(UIDL uidl) {
+ void updateSortingProperties(UIDL uidl) {
oldSortColumn = sortColumn;
if (uidl.hasVariable("sortascending")) {
sortAscending = uidl.getBooleanVariable("sortascending");
@@ -1117,7 +927,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
}
}
- private void resizeSortedColumnForSortIndicator() {
+ void resizeSortedColumnForSortIndicator() {
// Force recalculation of the captionContainer element inside the header
// cell to accomodate for the size of the sort arrow.
HeaderCell sortedHeader = tHead.getHeaderCell(sortColumn);
@@ -1132,7 +942,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
}
}
- private void updateFirstVisibleAndScrollIfNeeded(UIDL uidl) {
+ void updateFirstVisibleAndScrollIfNeeded(UIDL uidl) {
firstvisible = uidl.hasVariable("firstvisible") ? uidl
.getIntVariable("firstvisible") : 0;
if (firstvisible != lastRequestedFirstvisible && scrollBody != null) {
@@ -1147,7 +957,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
return (int) (rowIx * scrollBody.getRowHeight());
}
- private void updatePageLength(UIDL uidl) {
+ void updatePageLength(UIDL uidl) {
int oldPageLength = pageLength;
if (uidl.hasAttribute("pagelength")) {
pageLength = uidl.getIntAttribute("pagelength");
@@ -1162,7 +972,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
}
}
- private void updateSelectionProperties(UIDL uidl) {
+ void updateSelectionProperties(UIDL uidl) {
setMultiSelectMode(uidl.hasAttribute("multiselectmode") ? uidl
.getIntAttribute("multiselectmode") : MULTISELECT_MODE_DEFAULT);
@@ -1171,18 +981,18 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
if (uidl.hasAttribute("selectmode")) {
if (uidl.getBooleanAttribute("readonly")) {
- selectMode = Table.SELECT_MODE_NONE;
+ selectMode = SelectMode.NONE;
} else if (uidl.getStringAttribute("selectmode").equals("multi")) {
- selectMode = Table.SELECT_MODE_MULTI;
+ selectMode = SelectMode.MULTI;
} else if (uidl.getStringAttribute("selectmode").equals("single")) {
- selectMode = Table.SELECT_MODE_SINGLE;
+ selectMode = SelectMode.SINGLE;
} else {
- selectMode = Table.SELECT_MODE_NONE;
+ selectMode = SelectMode.NONE;
}
}
}
- private void updateDragMode(UIDL uidl) {
+ void updateDragMode(UIDL uidl) {
dragmode = uidl.hasAttribute("dragmode") ? uidl
.getIntAttribute("dragmode") : 0;
if (BrowserInfo.get().isIE()) {
@@ -1219,7 +1029,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
return totalRows;
}
- private void focusRowFromBody() {
+ void focusRowFromBody() {
if (selectedRowKeys.size() == 1) {
// try to focus a row currently selected and in viewport
String selectedRowKey = selectedRowKeys.iterator().next();
@@ -1247,7 +1057,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
* @param focusOnly
* Should the focus only be moved to the last row
*/
- private void selectLastRenderedRowInViewPort(boolean focusOnly) {
+ void selectLastRenderedRowInViewPort(boolean focusOnly) {
int index = firstRowInViewPort + getFullyVisibleRowCount();
VScrollTableRow lastRowInViewport = scrollBody.getRowByRowIndex(index);
if (lastRowInViewport == null) {
@@ -1272,7 +1082,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
* @param focusOnly
* Should the focus only be moved to the first row
*/
- private void selectFirstRenderedRowInViewPort(boolean focusOnly) {
+ void selectFirstRenderedRowInViewPort(boolean focusOnly) {
int index = firstRowInViewPort;
VScrollTableRow firstInViewport = scrollBody.getRowByRowIndex(index);
if (firstInViewport == null) {
@@ -1286,7 +1096,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
}
}
- private void setCacheRateFromUIDL(UIDL uidl) {
+ void setCacheRateFromUIDL(UIDL uidl) {
setCacheRate(uidl.hasAttribute("cr") ? uidl.getDoubleAttribute("cr")
: CACHE_RATE_DEFAULT);
}
@@ -1303,7 +1113,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
* IScrollTableRows). This is done lazily as Table must survive from
* "subtreecaching" logic.
*/
- private void purgeUnregistryBag() {
+ void purgeUnregistryBag() {
for (Iterator<Panel> iterator = lazyUnregistryBag.iterator(); iterator
.hasNext();) {
VPaintableMap.get(client)
@@ -1312,7 +1122,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
lazyUnregistryBag.clear();
}
- private void updateActionMap(UIDL mainUidl) {
+ void updateActionMap(UIDL mainUidl) {
UIDL actionsUidl = mainUidl.getChildByTagName("actions");
if (actionsUidl == null) {
return;
@@ -1414,7 +1224,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
* @param reqRows
* amount of rows in data set
*/
- private void updateBody(UIDL uidl, int firstRow, int reqRows) {
+ void updateBody(UIDL uidl, int firstRow, int reqRows) {
if (uidl == null || reqRows < 1) {
// container is empty, remove possibly existing rows
if (firstRow <= 0) {
@@ -1431,7 +1241,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
discardRowsOutsideCacheWindow();
}
- private void updateRowsInBody(UIDL partialRowUpdates) {
+ void updateRowsInBody(UIDL partialRowUpdates) {
if (partialRowUpdates == null) {
return;
}
@@ -1564,20 +1374,20 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
}
private boolean isMultiSelectModeSimple() {
- return selectMode == Table.SELECT_MODE_MULTI
+ return selectMode == SelectMode.MULTI
&& multiselectmode == MULTISELECT_MODE_SIMPLE;
}
private boolean isSingleSelectMode() {
- return selectMode == Table.SELECT_MODE_SINGLE;
+ return selectMode == SelectMode.SINGLE;
}
private boolean isMultiSelectModeAny() {
- return selectMode == Table.SELECT_MODE_MULTI;
+ return selectMode == SelectMode.MULTI;
}
private boolean isMultiSelectModeDefault() {
- return selectMode == Table.SELECT_MODE_MULTI
+ return selectMode == SelectMode.MULTI
&& multiselectmode == MULTISELECT_MODE_DEFAULT;
}
@@ -1593,7 +1403,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
}
protected boolean isSelectable() {
- return selectMode > Table.SELECT_MODE_NONE;
+ return selectMode.getId() > SelectMode.NONE.getId();
}
private boolean isCollapsedColumn(String colKey) {
@@ -1769,7 +1579,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
}
}
client.updateVariable(paintableId, "columnorder", columnOrder, false);
- if (client.hasEventListeners(this, COLUMN_REORDER_EVENT_ID)) {
+ if (client.hasWidgetEventListeners(this, COLUMN_REORDER_EVENT_ID)) {
client.sendPendingVariableChanges();
}
}
@@ -2108,19 +1918,19 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
style.setDisplay(Display.BLOCK);
}
- private void hideScrollPositionAnnotation() {
+ void hideScrollPositionAnnotation() {
if (scrollPositionElement != null) {
DOM.setStyleAttribute(scrollPositionElement, "display", "none");
}
}
- private boolean isScrollPositionVisible() {
+ boolean isScrollPositionVisible() {
return scrollPositionElement != null
&& !scrollPositionElement.getStyle().getDisplay()
.equals(Display.NONE.toString());
}
- private class RowRequestHandler extends Timer {
+ class RowRequestHandler extends Timer {
private int reqFirstRow = 0;
private int reqRows = 0;
@@ -2512,7 +2322,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
* The click event
*/
private void fireHeaderClickedEvent(Event event) {
- if (client.hasEventListeners(VScrollTable.this,
+ if (client.hasWidgetEventListeners(VScrollTable.this,
HEADER_CLICK_EVENT_ID)) {
MouseEventDetails details = new MouseEventDetails(event);
client.updateVariable(paintableId, "headerClickEvent",
@@ -3543,7 +3353,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
* The click event
*/
private void fireFooterClickedEvent(Event event) {
- if (client.hasEventListeners(VScrollTable.this,
+ if (client.hasWidgetEventListeners(VScrollTable.this,
FOOTER_CLICK_EVENT_ID)) {
MouseEventDetails details = new MouseEventDetails(event);
client.updateVariable(paintableId, "footerClickEvent",
@@ -4295,12 +4105,12 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
final VScrollTableRow toBeRemoved = (VScrollTableRow) renderedRows
.get(index);
// Unregister row tooltip
- client.registerTooltip(VScrollTable.this, toBeRemoved.getElement(),
- null);
+ client.registerWidgetTooltip(VScrollTable.this,
+ toBeRemoved.getElement(), null);
for (int i = 0; i < toBeRemoved.getElement().getChildCount(); i++) {
// Unregister cell tooltips
Element td = toBeRemoved.getElement().getChild(i).cast();
- client.registerTooltip(VScrollTable.this, td, null);
+ client.registerWidgetTooltip(VScrollTable.this, td, null);
}
lazyUnregistryBag.add(toBeRemoved);
tBodyElement.removeChild(toBeRemoved.getElement());
@@ -4559,10 +4369,12 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
String rowDescription = uidl.getStringAttribute("rowdescr");
if (rowDescription != null && !rowDescription.equals("")) {
TooltipInfo info = new TooltipInfo(rowDescription);
- client.registerTooltip(VScrollTable.this, rowElement, info);
+ client.registerWidgetTooltip(VScrollTable.this, rowElement,
+ info);
} else {
// Remove possibly previously set tooltip
- client.registerTooltip(VScrollTable.this, rowElement, null);
+ client.registerWidgetTooltip(VScrollTable.this, rowElement,
+ null);
}
tHead.getColumnAlignments();
@@ -4797,10 +4609,10 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
if (description != null && !description.equals("")) {
TooltipInfo info = new TooltipInfo(description);
- client.registerTooltip(VScrollTable.this, td, info);
+ client.registerWidgetTooltip(VScrollTable.this, td, info);
} else {
// Remove possibly previously set tooltip
- client.registerTooltip(VScrollTable.this, td, null);
+ client.registerWidgetTooltip(VScrollTable.this, td, null);
}
td.appendChild(container);
@@ -4879,7 +4691,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
*/
private boolean handleClickEvent(Event event, Element targetTdOrTr,
boolean immediate) {
- if (!client.hasEventListeners(VScrollTable.this,
+ if (!client.hasWidgetEventListeners(VScrollTable.this,
ITEM_CLICK_EVENT_ID)) {
// Don't send an event if nobody is listening
return false;
@@ -4923,22 +4735,24 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
if (!containsWidget) {
// Only text nodes has tooltips
- if (client.getTooltipTitleInfo(VScrollTable.this,
- target) != null) {
+ if (VPaintableMap.get(client).getWidgetTooltipInfo(
+ VScrollTable.this, target) != null) {
// Cell has description, use it
- client.handleTooltipEvent(event, VScrollTable.this,
- target);
+ client.handleWidgetTooltipEvent(event,
+ VScrollTable.this, target);
} else {
// Cell might have row description, use row
// description
- client.handleTooltipEvent(event, VScrollTable.this,
+ client.handleWidgetTooltipEvent(event,
+ VScrollTable.this,
target.getParentElement());
}
}
} else {
// Table row (tr)
- client.handleTooltipEvent(event, VScrollTable.this, target);
+ client.handleWidgetTooltipEvent(event, VScrollTable.this,
+ target);
}
}
@@ -4954,7 +4768,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
showContextMenu(event);
if (enabled
&& (actionKeys != null || client
- .hasEventListeners(VScrollTable.this,
+ .hasWidgetEventListeners(
+ VScrollTable.this,
ITEM_CLICK_EVENT_ID))) {
/*
* Prevent browser context menu only if there are
@@ -5243,7 +5058,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
Element targetTdOrTr) {
mDown = true;
VTransferable transferable = new VTransferable();
- transferable.setDragSource(VScrollTable.this);
+ transferable.setDragSource(VPaintableMap.get(client)
+ .getPaintable(VScrollTable.this));
transferable.setData("itemId", "" + rowKey);
NodeList<TableCellElement> cells = rowElement.getCells();
for (int i = 0; i < cells.getLength(); i++) {
@@ -5972,9 +5788,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
private int contentAreaBorderHeight = -1;
private int scrollLeft;
private int scrollTop;
- private VScrollTableDropHandler dropHandler;
+ VScrollTableDropHandler dropHandler;
private boolean navKeyDown;
- private boolean multiselectPending;
+ boolean multiselectPending;
/**
* @return border top + border bottom of the scrollable area of table
@@ -6315,7 +6131,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
@Override
public VPaintableWidget getPaintable() {
- return VScrollTable.this;
+ return VPaintableMap.get(client).getPaintable(VScrollTable.this);
}
public ApplicationConnection getApplicationConnection() {
@@ -6752,7 +6568,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler,
* actions may need focus.
*
*/
- private void setProperTabIndex() {
+ void setProperTabIndex() {
int storedScrollTop = 0;
int storedScrollLeft = 0;
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java
new file mode 100644
index 0000000000..c747a29a21
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTablePaintable.java
@@ -0,0 +1,251 @@
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.dom.client.Style.Position;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.Util;
+
+public class VScrollTablePaintable extends VAbstractPaintableWidget {
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * com.vaadin.terminal.gwt.client.Paintable#updateFromUIDL(com.vaadin.terminal
+ * .gwt.client.UIDL, com.vaadin.terminal.gwt.client.ApplicationConnection)
+ */
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ getWidgetForPaintable().rendering = true;
+
+ if (uidl.hasAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_FIRST)) {
+ getWidgetForPaintable().serverCacheFirst = uidl
+ .getIntAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_FIRST);
+ getWidgetForPaintable().serverCacheLast = uidl
+ .getIntAttribute(VScrollTable.ATTRIBUTE_PAGEBUFFER_LAST);
+ } else {
+ getWidgetForPaintable().serverCacheFirst = -1;
+ getWidgetForPaintable().serverCacheLast = -1;
+ }
+ /*
+ * We need to do this before updateComponent since updateComponent calls
+ * this.setHeight() which will calculate a new body height depending on
+ * the space available.
+ */
+ if (uidl.hasAttribute("colfooters")) {
+ getWidgetForPaintable().showColFooters = uidl
+ .getBooleanAttribute("colfooters");
+ }
+
+ getWidgetForPaintable().tFoot
+ .setVisible(getWidgetForPaintable().showColFooters);
+
+ if (client.updateComponent(this, uidl, true)) {
+ getWidgetForPaintable().rendering = false;
+ return;
+ }
+
+ getWidgetForPaintable().enabled = !uidl.hasAttribute("disabled");
+
+ if (BrowserInfo.get().isIE8() && !getWidgetForPaintable().enabled) {
+ /*
+ * The disabled shim will not cover the table body if it is relative
+ * in IE8. See #7324
+ */
+ getWidgetForPaintable().scrollBodyPanel.getElement().getStyle()
+ .setPosition(Position.STATIC);
+ } else if (BrowserInfo.get().isIE8()) {
+ getWidgetForPaintable().scrollBodyPanel.getElement().getStyle()
+ .setPosition(Position.RELATIVE);
+ }
+
+ getWidgetForPaintable().client = client;
+ getWidgetForPaintable().paintableId = uidl.getStringAttribute("id");
+ getWidgetForPaintable().immediate = uidl
+ .getBooleanAttribute("immediate");
+
+ int previousTotalRows = getWidgetForPaintable().totalRows;
+ getWidgetForPaintable().updateTotalRows(uidl);
+ boolean totalRowsChanged = (getWidgetForPaintable().totalRows != previousTotalRows);
+
+ getWidgetForPaintable().updateDragMode(uidl);
+
+ getWidgetForPaintable().updateSelectionProperties(uidl);
+
+ if (uidl.hasAttribute("alb")) {
+ getWidgetForPaintable().bodyActionKeys = uidl
+ .getStringArrayAttribute("alb");
+ } else {
+ // Need to clear the actions if the action handlers have been
+ // removed
+ getWidgetForPaintable().bodyActionKeys = null;
+ }
+
+ getWidgetForPaintable().setCacheRateFromUIDL(uidl);
+
+ getWidgetForPaintable().recalcWidths = uidl
+ .hasAttribute("recalcWidths");
+ if (getWidgetForPaintable().recalcWidths) {
+ getWidgetForPaintable().tHead.clear();
+ getWidgetForPaintable().tFoot.clear();
+ }
+
+ getWidgetForPaintable().updatePageLength(uidl);
+
+ getWidgetForPaintable().updateFirstVisibleAndScrollIfNeeded(uidl);
+
+ getWidgetForPaintable().showRowHeaders = uidl
+ .getBooleanAttribute("rowheaders");
+ getWidgetForPaintable().showColHeaders = uidl
+ .getBooleanAttribute("colheaders");
+
+ getWidgetForPaintable().updateSortingProperties(uidl);
+
+ boolean keyboardSelectionOverRowFetchInProgress = getWidgetForPaintable()
+ .selectSelectedRows(uidl);
+
+ getWidgetForPaintable().updateActionMap(uidl);
+
+ getWidgetForPaintable().updateColumnProperties(uidl);
+
+ UIDL ac = uidl.getChildByTagName("-ac");
+ if (ac == null) {
+ if (getWidgetForPaintable().dropHandler != null) {
+ // remove dropHandler if not present anymore
+ getWidgetForPaintable().dropHandler = null;
+ }
+ } else {
+ if (getWidgetForPaintable().dropHandler == null) {
+ getWidgetForPaintable().dropHandler = getWidgetForPaintable().new VScrollTableDropHandler();
+ }
+ getWidgetForPaintable().dropHandler.updateAcceptRules(ac);
+ }
+
+ UIDL partialRowAdditions = uidl.getChildByTagName("prows");
+ UIDL partialRowUpdates = uidl.getChildByTagName("urows");
+ if (partialRowUpdates != null || partialRowAdditions != null) {
+ // we may have pending cache row fetch, cancel it. See #2136
+ getWidgetForPaintable().rowRequestHandler.cancel();
+
+ getWidgetForPaintable().updateRowsInBody(partialRowUpdates);
+ getWidgetForPaintable().addAndRemoveRows(partialRowAdditions);
+ } else {
+ UIDL rowData = uidl.getChildByTagName("rows");
+ if (rowData != null) {
+ // we may have pending cache row fetch, cancel it. See #2136
+ getWidgetForPaintable().rowRequestHandler.cancel();
+
+ if (!getWidgetForPaintable().recalcWidths
+ && getWidgetForPaintable().initializedAndAttached) {
+ getWidgetForPaintable().updateBody(rowData,
+ uidl.getIntAttribute("firstrow"),
+ uidl.getIntAttribute("rows"));
+ if (getWidgetForPaintable().headerChangedDuringUpdate) {
+ getWidgetForPaintable().triggerLazyColumnAdjustment(
+ true);
+ } else if (!getWidgetForPaintable()
+ .isScrollPositionVisible()
+ || totalRowsChanged
+ || getWidgetForPaintable().lastRenderedHeight != getWidgetForPaintable().scrollBody
+ .getOffsetHeight()) {
+ // webkits may still bug with their disturbing scrollbar
+ // bug, see #3457
+ // Run overflow fix for the scrollable area
+ // #6698 - If there's a scroll going on, don't abort it
+ // by changing overflows as the length of the contents
+ // *shouldn't* have changed (unless the number of rows
+ // or the height of the widget has also changed)
+ Scheduler.get().scheduleDeferred(new Command() {
+ public void execute() {
+ Util.runWebkitOverflowAutoFix(getWidgetForPaintable().scrollBodyPanel
+ .getElement());
+ }
+ });
+ }
+ } else {
+ getWidgetForPaintable().initializeRows(uidl, rowData);
+ }
+ }
+ }
+
+ if (!getWidgetForPaintable().isSelectable()) {
+ getWidgetForPaintable().scrollBody
+ .addStyleName(VScrollTable.CLASSNAME + "-body-noselection");
+ } else {
+ getWidgetForPaintable().scrollBody
+ .removeStyleName(VScrollTable.CLASSNAME
+ + "-body-noselection");
+ }
+
+ getWidgetForPaintable().hideScrollPositionAnnotation();
+ getWidgetForPaintable().purgeUnregistryBag();
+
+ // selection is no in sync with server, avoid excessive server visits by
+ // clearing to flag used during the normal operation
+ if (!keyboardSelectionOverRowFetchInProgress) {
+ getWidgetForPaintable().selectionChanged = false;
+ }
+
+ /*
+ * This is called when the Home or page up button has been pressed in
+ * selectable mode and the next selected row was not yet rendered in the
+ * client
+ */
+ if (getWidgetForPaintable().selectFirstItemInNextRender
+ || getWidgetForPaintable().focusFirstItemInNextRender) {
+ getWidgetForPaintable().selectFirstRenderedRowInViewPort(
+ getWidgetForPaintable().focusFirstItemInNextRender);
+ getWidgetForPaintable().selectFirstItemInNextRender = getWidgetForPaintable().focusFirstItemInNextRender = false;
+ }
+
+ /*
+ * This is called when the page down or end button has been pressed in
+ * selectable mode and the next selected row was not yet rendered in the
+ * client
+ */
+ if (getWidgetForPaintable().selectLastItemInNextRender
+ || getWidgetForPaintable().focusLastItemInNextRender) {
+ getWidgetForPaintable().selectLastRenderedRowInViewPort(
+ getWidgetForPaintable().focusLastItemInNextRender);
+ getWidgetForPaintable().selectLastItemInNextRender = getWidgetForPaintable().focusLastItemInNextRender = false;
+ }
+ getWidgetForPaintable().multiselectPending = false;
+
+ if (getWidgetForPaintable().focusedRow != null) {
+ if (!getWidgetForPaintable().focusedRow.isAttached()
+ && !getWidgetForPaintable().rowRequestHandler.isRunning()) {
+ // focused row has been orphaned, can't focus
+ getWidgetForPaintable().focusRowFromBody();
+ }
+ }
+
+ getWidgetForPaintable().tabIndex = uidl.hasAttribute("tabindex") ? uidl
+ .getIntAttribute("tabindex") : 0;
+ getWidgetForPaintable().setProperTabIndex();
+
+ getWidgetForPaintable().resizeSortedColumnForSortIndicator();
+
+ // Remember this to detect situations where overflow hack might be
+ // needed during scrolling
+ getWidgetForPaintable().lastRenderedHeight = getWidgetForPaintable().scrollBody
+ .getOffsetHeight();
+
+ getWidgetForPaintable().rendering = false;
+ getWidgetForPaintable().headerChangedDuringUpdate = false;
+
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VScrollTable.class);
+ }
+
+ @Override
+ public VScrollTable getWidgetForPaintable() {
+ return (VScrollTable) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java b/src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java
index 77dd1cc39e..0eddca0ed3 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTreeTable.java
@@ -24,21 +24,19 @@ import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Widget;
-import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.ComputedStyle;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.ui.VScrollTable.VScrollTableBody.VScrollTableRow;
import com.vaadin.terminal.gwt.client.ui.VTreeTable.VTreeTableScrollBody.VTreeTableRow;
public class VTreeTable extends VScrollTable {
- private static class PendingNavigationEvent {
- private final int keycode;
- private final boolean ctrl;
- private final boolean shift;
+ static class PendingNavigationEvent {
+ final int keycode;
+ final boolean ctrl;
+ final boolean shift;
public PendingNavigationEvent(int keycode, boolean ctrl, boolean shift) {
this.keycode = keycode;
@@ -59,82 +57,14 @@ public class VTreeTable extends VScrollTable {
}
}
- public static final String ATTRIBUTE_HIERARCHY_COLUMN_INDEX = "hci";
- private boolean collapseRequest;
+ boolean collapseRequest;
private boolean selectionPending;
- private int colIndexOfHierarchy;
- private String collapsedRowKey;
- private VTreeTableScrollBody scrollBody;
- private boolean animationsEnabled;
- private LinkedList<PendingNavigationEvent> pendingNavigationEvents = new LinkedList<VTreeTable.PendingNavigationEvent>();
- private boolean focusParentResponsePending;
-
- @Override
- public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
- FocusableScrollPanel widget = null;
- int scrollPosition = 0;
- if (collapseRequest) {
- widget = (FocusableScrollPanel) getWidget(1);
- scrollPosition = widget.getScrollPosition();
- }
- animationsEnabled = uidl.getBooleanAttribute("animate");
- colIndexOfHierarchy = uidl
- .hasAttribute(ATTRIBUTE_HIERARCHY_COLUMN_INDEX) ? uidl
- .getIntAttribute(ATTRIBUTE_HIERARCHY_COLUMN_INDEX) : 0;
- int oldTotalRows = getTotalRows();
- super.updateFromUIDL(uidl, client);
- if (collapseRequest) {
- if (collapsedRowKey != null && scrollBody != null) {
- VScrollTableRow row = getRenderedRowByKey(collapsedRowKey);
- if (row != null) {
- setRowFocus(row);
- focus();
- }
- }
-
- int scrollPosition2 = widget.getScrollPosition();
- if (scrollPosition != scrollPosition2) {
- widget.setScrollPosition(scrollPosition);
- }
-
- // check which rows are needed from the server and initiate a
- // deferred fetch
- onScroll(null);
- }
- // Recalculate table size if collapse request, or if page length is zero
- // (not sent by server) and row count changes (#7908).
- if (collapseRequest
- || (!uidl.hasAttribute("pagelength") && getTotalRows() != oldTotalRows)) {
- /*
- * Ensure that possibly removed/added scrollbars are considered.
- * Triggers row calculations, removes cached rows etc. Basically
- * cleans up state. Be careful if touching this, you will break
- * pageLength=0 if you remove this.
- */
- triggerLazyColumnAdjustment(true);
-
- collapseRequest = false;
- }
- if (uidl.hasAttribute("focusedRow")) {
- String key = uidl.getStringAttribute("focusedRow");
- setRowFocus(getRenderedRowByKey(key));
- focusParentResponsePending = false;
- } else if (uidl.hasAttribute("clearFocusPending")) {
- // Special case to detect a response to a focusParent request that
- // does not return any focusedRow because the selected node has no
- // parent
- focusParentResponsePending = false;
- }
-
- while (!collapseRequest && !focusParentResponsePending
- && !pendingNavigationEvents.isEmpty()) {
- // Keep replaying any queued events as long as we don't have any
- // potential content changes pending
- PendingNavigationEvent event = pendingNavigationEvents
- .removeFirst();
- handleNavigation(event.keycode, event.ctrl, event.shift);
- }
- }
+ int colIndexOfHierarchy;
+ String collapsedRowKey;
+ VTreeTableScrollBody scrollBody;
+ boolean animationsEnabled;
+ LinkedList<PendingNavigationEvent> pendingNavigationEvents = new LinkedList<VTreeTable.PendingNavigationEvent>();
+ boolean focusParentResponsePending;
@Override
protected VScrollTableBody createScrollBody() {
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTreeTablePaintable.java b/src/com/vaadin/terminal/gwt/client/ui/VTreeTablePaintable.java
new file mode 100644
index 0000000000..8fec0558ec
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VTreeTablePaintable.java
@@ -0,0 +1,98 @@
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.Widget;
+import com.vaadin.terminal.gwt.client.ApplicationConnection;
+import com.vaadin.terminal.gwt.client.UIDL;
+import com.vaadin.terminal.gwt.client.ui.VScrollTable.VScrollTableBody.VScrollTableRow;
+import com.vaadin.terminal.gwt.client.ui.VTreeTable.PendingNavigationEvent;
+
+public class VTreeTablePaintable extends VScrollTablePaintable {
+ public static final String ATTRIBUTE_HIERARCHY_COLUMN_INDEX = "hci";
+
+ @Override
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ FocusableScrollPanel widget = null;
+ int scrollPosition = 0;
+ if (getWidgetForPaintable().collapseRequest) {
+ widget = (FocusableScrollPanel) getWidgetForPaintable()
+ .getWidget(1);
+ scrollPosition = widget.getScrollPosition();
+ }
+ getWidgetForPaintable().animationsEnabled = uidl
+ .getBooleanAttribute("animate");
+ getWidgetForPaintable().colIndexOfHierarchy = uidl
+ .hasAttribute(ATTRIBUTE_HIERARCHY_COLUMN_INDEX) ? uidl
+ .getIntAttribute(ATTRIBUTE_HIERARCHY_COLUMN_INDEX) : 0;
+ int oldTotalRows = getWidgetForPaintable().getTotalRows();
+ super.updateFromUIDL(uidl, client);
+ if (getWidgetForPaintable().collapseRequest) {
+ if (getWidgetForPaintable().collapsedRowKey != null
+ && getWidgetForPaintable().scrollBody != null) {
+ VScrollTableRow row = getWidgetForPaintable()
+ .getRenderedRowByKey(
+ getWidgetForPaintable().collapsedRowKey);
+ if (row != null) {
+ getWidgetForPaintable().setRowFocus(row);
+ getWidgetForPaintable().focus();
+ }
+ }
+
+ int scrollPosition2 = widget.getScrollPosition();
+ if (scrollPosition != scrollPosition2) {
+ widget.setScrollPosition(scrollPosition);
+ }
+
+ // check which rows are needed from the server and initiate a
+ // deferred fetch
+ getWidgetForPaintable().onScroll(null);
+ }
+ // Recalculate table size if collapse request, or if page length is zero
+ // (not sent by server) and row count changes (#7908).
+ if (getWidgetForPaintable().collapseRequest
+ || (!uidl.hasAttribute("pagelength") && getWidgetForPaintable()
+ .getTotalRows() != oldTotalRows)) {
+ /*
+ * Ensure that possibly removed/added scrollbars are considered.
+ * Triggers row calculations, removes cached rows etc. Basically
+ * cleans up state. Be careful if touching this, you will break
+ * pageLength=0 if you remove this.
+ */
+ getWidgetForPaintable().triggerLazyColumnAdjustment(true);
+
+ getWidgetForPaintable().collapseRequest = false;
+ }
+ if (uidl.hasAttribute("focusedRow")) {
+ String key = uidl.getStringAttribute("focusedRow");
+ getWidgetForPaintable().setRowFocus(
+ getWidgetForPaintable().getRenderedRowByKey(key));
+ getWidgetForPaintable().focusParentResponsePending = false;
+ } else if (uidl.hasAttribute("clearFocusPending")) {
+ // Special case to detect a response to a focusParent request that
+ // does not return any focusedRow because the selected node has no
+ // parent
+ getWidgetForPaintable().focusParentResponsePending = false;
+ }
+
+ while (!getWidgetForPaintable().collapseRequest
+ && !getWidgetForPaintable().focusParentResponsePending
+ && !getWidgetForPaintable().pendingNavigationEvents.isEmpty()) {
+ // Keep replaying any queued events as long as we don't have any
+ // potential content changes pending
+ PendingNavigationEvent event = getWidgetForPaintable().pendingNavigationEvents
+ .removeFirst();
+ getWidgetForPaintable().handleNavigation(event.keycode, event.ctrl,
+ event.shift);
+ }
+ }
+
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VTreeTable.class);
+ }
+
+ @Override
+ public VTreeTable getWidgetForPaintable() {
+ return (VTreeTable) super.getWidgetForPaintable();
+ }
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VUpload.java b/src/com/vaadin/terminal/gwt/client/ui/VUpload.java
index 3d49b8d9d1..66894417f3 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VUpload.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VUpload.java
@@ -24,9 +24,9 @@ import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.VConsole;
+import com.vaadin.terminal.gwt.client.VPaintableWidget;
import com.vaadin.terminal.gwt.client.VTooltip;
/**
diff --git a/src/com/vaadin/terminal/gwt/client/ui/label/VLabel.java b/src/com/vaadin/terminal/gwt/client/ui/label/VLabel.java
index 09f435227d..8828582b57 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/label/VLabel.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/label/VLabel.java
@@ -34,15 +34,10 @@ public class VLabel extends HTML {
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
if (event.getTypeInt() == Event.ONLOAD) {
- // FIXME: Should not be here but in paintable
Util.notifyParentOfSizeChange(this, true);
- event.cancelBubble(true);
+ event.stopPropagation();
return;
}
- // FIXME: Move to paintable
- // if (client != null) {
- // client.handleTooltipEvent(event, this);
- // }
}
@Override
diff --git a/src/com/vaadin/terminal/gwt/client/ui/label/VLabelPaintable.java b/src/com/vaadin/terminal/gwt/client/ui/label/VLabelPaintable.java
index 796bce265e..269afde25d 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/label/VLabelPaintable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/label/VLabelPaintable.java
@@ -6,27 +6,21 @@ package com.vaadin.terminal.gwt.client.ui.label;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.PreElement;
+import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
-import com.vaadin.terminal.gwt.client.VPaintableWidget;
-
-public class VLabelPaintable implements VPaintableWidget {
-
- private VLabel widget = GWT.create(VLabel.class);
- private ApplicationConnection client;
+import com.vaadin.terminal.gwt.client.ui.VAbstractPaintableWidget;
+public class VLabelPaintable extends VAbstractPaintableWidget {
public VLabelPaintable() {
}
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
-
- if (client.updateComponent(getWidgetForPaintable(), uidl, true)) {
+ if (client.updateComponent(this, uidl, true)) {
return;
}
- this.client = client;
-
boolean sinkOnloads = false;
final String mode = uidl.getStringAttribute("mode");
@@ -64,8 +58,14 @@ public class VLabelPaintable implements VPaintableWidget {
}
}
+ @Override
+ protected Widget createWidget() {
+ return GWT.create(VLabel.class);
+ }
+
+ @Override
public VLabel getWidgetForPaintable() {
- return widget;
+ return (VLabel) super.getWidgetForPaintable();
}
}
diff --git a/src/com/vaadin/ui/MenuBar.java b/src/com/vaadin/ui/MenuBar.java
index 7ed432a12b..54a094a4e7 100644
--- a/src/com/vaadin/ui/MenuBar.java
+++ b/src/com/vaadin/ui/MenuBar.java
@@ -14,6 +14,7 @@ import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.Resource;
import com.vaadin.terminal.gwt.client.ui.VMenuBar;
+import com.vaadin.terminal.gwt.client.ui.VMenuBarPaintable;
import com.vaadin.ui.ClientWidget.LoadStyle;
/**
@@ -24,7 +25,7 @@ import com.vaadin.ui.ClientWidget.LoadStyle;
* </p>
*/
@SuppressWarnings("serial")
-@ClientWidget(value = VMenuBar.class, loadStyle = LoadStyle.LAZY)
+@ClientWidget(value = VMenuBarPaintable.class, loadStyle = LoadStyle.LAZY)
public class MenuBar extends AbstractComponent {
// Items of the top-level menu
diff --git a/src/com/vaadin/ui/Table.java b/src/com/vaadin/ui/Table.java
index 8b9dc3ef81..ec620ddcd5 100644
--- a/src/com/vaadin/ui/Table.java
+++ b/src/com/vaadin/ui/Table.java
@@ -47,6 +47,7 @@ import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.Resource;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
import com.vaadin.terminal.gwt.client.ui.VScrollTable;
+import com.vaadin.terminal.gwt.client.ui.VScrollTablePaintable;
import com.vaadin.terminal.gwt.client.ui.dd.VLazyInitItemIdentifiers;
/**
@@ -73,7 +74,7 @@ import com.vaadin.terminal.gwt.client.ui.dd.VLazyInitItemIdentifiers;
* @since 3.0
*/
@SuppressWarnings({ "deprecation" })
-@ClientWidget(VScrollTable.class)
+@ClientWidget(VScrollTablePaintable.class)
public class Table extends AbstractSelect implements Action.Container,
Container.Ordered, Container.Sortable, ItemClickSource,
ItemClickNotifier, DragSource, DropTarget {
diff --git a/src/com/vaadin/ui/TreeTable.java b/src/com/vaadin/ui/TreeTable.java
index 43bc7a80fe..09417e1e16 100644
--- a/src/com/vaadin/ui/TreeTable.java
+++ b/src/com/vaadin/ui/TreeTable.java
@@ -22,7 +22,7 @@ import com.vaadin.data.util.HierarchicalContainer;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.terminal.Resource;
-import com.vaadin.terminal.gwt.client.ui.VTreeTable;
+import com.vaadin.terminal.gwt.client.ui.VTreeTablePaintable;
import com.vaadin.ui.Tree.CollapseEvent;
import com.vaadin.ui.Tree.CollapseListener;
import com.vaadin.ui.Tree.ExpandEvent;
@@ -48,7 +48,7 @@ import com.vaadin.ui.treetable.HierarchicalContainerOrderedWrapper;
* share UI state in the container.
*/
@SuppressWarnings({ "serial" })
-@ClientWidget(VTreeTable.class)
+@ClientWidget(VTreeTablePaintable.class)
public class TreeTable extends Table implements Hierarchical {
private static final Logger logger = Logger.getLogger(TreeTable.class
@@ -454,7 +454,8 @@ public class TreeTable extends Table implements Hierarchical {
Object object = visibleColumns2[i];
if (hierarchyColumnId.equals(object)) {
target.addAttribute(
- VTreeTable.ATTRIBUTE_HIERARCHY_COLUMN_INDEX, i);
+ VTreeTablePaintable.ATTRIBUTE_HIERARCHY_COLUMN_INDEX,
+ i);
break;
}
}