From: Matti Tahvonen Date: Tue, 26 May 2009 07:37:02 +0000 (+0000) Subject: mem leak safer approach for #2997 + javadocs X-Git-Tag: 6.7.0.beta1~2772 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=c329ef0b3451965a23872ad2551967228ed9455e;p=vaadin-framework.git mem leak safer approach for #2997 + javadocs svn changeset:8006/svn branch:6.0 --- diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index 5b4c762f31..24bc64b98e 100755 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -1098,30 +1098,23 @@ public class ApplicationConnection { styleBuf.append(MODIFIED_CLASSNAME); } + TooltipInfo tooltipInfo = componentDetail.getTooltipInfo(null); // Update tooltip - if (uidl.hasAttribute(ATTRIBUTE_DESCRIPTION) - || uidl.hasAttribute(ATTRIBUTE_ERROR)) { - TooltipInfo tooltipInfo = new TooltipInfo(); - - if (uidl.hasAttribute(ATTRIBUTE_DESCRIPTION)) { - tooltipInfo.setTitle(uidl - .getStringAttribute(ATTRIBUTE_DESCRIPTION)); - } - - if (uidl.hasAttribute(ATTRIBUTE_ERROR)) { - tooltipInfo.setErrorUidl(uidl.getErrors()); - } - - registerTooltip(component.getElement(), tooltipInfo); + if (uidl.hasAttribute(ATTRIBUTE_DESCRIPTION)) { + tooltipInfo + .setTitle(uidl.getStringAttribute(ATTRIBUTE_DESCRIPTION)); } else { - registerTooltip(component.getElement(), (TooltipInfo) null); + tooltipInfo.setTitle(null); } // add error classname to components w/ error if (uidl.hasAttribute(ATTRIBUTE_ERROR)) { + tooltipInfo.setErrorUidl(uidl.getErrors()); styleBuf.append(" "); styleBuf.append(primaryName); styleBuf.append(ERROR_CLASSNAME_EXT); + } else { + tooltipInfo.setErrorUidl(null); } // add required style to required components @@ -1539,8 +1532,16 @@ public class ApplicationConnection { * Updating TooltipInfo is done in updateComponent method. * */ - public TooltipInfo getTitleInfo(Paintable titleOwner) { - return tooltip.getTooltip(((Widget) titleOwner).getElement()); + public TooltipInfo getTooltipTitleInfo(Paintable titleOwner, Object key) { + if (null == titleOwner) { + return null; + } + ComponentDetail cd = idToPaintableDetail.get(getPid(titleOwner)); + if (null != cd) { + return cd.getTooltipInfo(key); + } else { + return null; + } } private final VTooltip tooltip = new VTooltip(this); @@ -1556,7 +1557,25 @@ public class ApplicationConnection { * @param owner */ public void handleTooltipEvent(Event event, Paintable owner) { - tooltip.handleTooltipEvent(event, owner); + tooltip.handleTooltipEvent(event, owner, null); + + } + + /** + * Component may want to delegate Tooltip handling to client. Layouts add + * Tooltip (description, errors) to caption, but some components may want + * them to appear one other elements too. + * + * Events wanted by this handler are same as in Tooltip.TOOLTIP_EVENTS + * + * @param event + * @param owner + * @param key + * the key for tooltip if this is "additional" tooltip, null for + * components "main tooltip" + */ + public void handleTooltipEvent(Event event, Paintable owner, Object key) { + tooltip.handleTooltipEvent(event, owner, key); } @@ -1632,16 +1651,33 @@ public class ApplicationConnection { return view; } - public void registerTooltip(Element e, String tooltip) { - if (tooltip == null || tooltip.equals("")) { - registerTooltip(e, (TooltipInfo) null); - } else { - registerTooltip(e, new TooltipInfo(tooltip)); - } - } - - public void registerTooltip(Element e, TooltipInfo tooltip) { - this.tooltip.registerTooltip(e, tooltip); + /** + * If component has several tooltips in addition to the one provided by + * {@link com.vaadin.ui.AbstractComponent}, component can register them with + * this method. + *

+ * Component must also pipe events to + * {@link #handleTooltipEvent(Event, Paintable, Object)} method. + *

+ * This method can also be used to deregister tooltips by using null as + * tooltip + * + * @param paintable + * Paintable "owning" this tooltip + * @param key + * key assosiated with given tooltip. Can be any object. For + * example a related dom element. Same key must be given for + * {@link #handleTooltipEvent(Event, Paintable, Object)} method. + * + * @param tooltip + * the TooltipInfo object containing details shown in tooltip, + * null if deregistering tooltip + */ + public void registerTooltip(Paintable paintable, Object key, + TooltipInfo tooltip) { + ComponentDetail componentDetail = idToPaintableDetail + .get(getPid(paintable)); + componentDetail.putAdditionalTooltip(key, tooltip); } } diff --git a/src/com/vaadin/terminal/gwt/client/ComponentDetail.java b/src/com/vaadin/terminal/gwt/client/ComponentDetail.java index 3254346c76..8e61ec7429 100644 --- a/src/com/vaadin/terminal/gwt/client/ComponentDetail.java +++ b/src/com/vaadin/terminal/gwt/client/ComponentDetail.java @@ -1,5 +1,7 @@ package com.vaadin.terminal.gwt.client; +import java.util.HashMap; + import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize; import com.vaadin.terminal.gwt.client.RenderInformation.Size; @@ -7,8 +9,37 @@ class ComponentDetail { private String pid; private Paintable component; private TooltipInfo tooltipInfo = new TooltipInfo(); + + /** + * Returns a TooltipInfo assosiated with Component. If element is given, + * returns an additional TooltipInfo. + * + * @param key + * @return the tooltipInfo + */ + public TooltipInfo getTooltipInfo(Object key) { + if (key == null) { + return tooltipInfo; + } else { + if (additionalTooltips != null) { + return additionalTooltips.get(key); + } else { + return null; + } + } + } + + /** + * @param tooltipInfo + * the tooltipInfo to set + */ + public void setTooltipInfo(TooltipInfo tooltipInfo) { + this.tooltipInfo = tooltipInfo; + } + private FloatSize relativeSize; private Size offsetSize; + private HashMap additionalTooltips; /** * @return the pid @@ -70,4 +101,15 @@ class ComponentDetail { this.offsetSize = offsetSize; } + public void putAdditionalTooltip(Object key, TooltipInfo tooltip) { + if (tooltip == null && additionalTooltips != null) { + additionalTooltips.remove(key); + } else { + if (additionalTooltips == null) { + additionalTooltips = new HashMap(); + } + additionalTooltips.put(key, tooltip); + } + } + } diff --git a/src/com/vaadin/terminal/gwt/client/VTooltip.java b/src/com/vaadin/terminal/gwt/client/VTooltip.java index e3a0ca060a..b42b4f3bf3 100644 --- a/src/com/vaadin/terminal/gwt/client/VTooltip.java +++ b/src/com/vaadin/terminal/gwt/client/VTooltip.java @@ -9,7 +9,6 @@ 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.Widget; import com.vaadin.terminal.gwt.client.ui.VOverlay; /** @@ -29,14 +28,14 @@ public class VTooltip extends VOverlay { VErrorMessage em = new VErrorMessage(); Element description = DOM.createDiv(); private Paintable tooltipOwner; - private Element tooltipTargetElement; private boolean closing = false; private boolean opening = false; private ApplicationConnection ac; // Open next tooltip faster. Disabled after 2 sec of showTooltip-silence. private boolean justClosed = false; - private TooltipInfo visibleTooltip = null; + // If this is "additional" tooltip, this field contains the key for it + private Object tooltipKey; public VTooltip(ApplicationConnection client) { super(false, false, true); @@ -98,25 +97,19 @@ public class VTooltip extends VOverlay { sinkEvents(Event.ONMOUSEOVER | Event.ONMOUSEOUT); } }); - visibleTooltip = info; } else { hide(); - visibleTooltip = null; } } - public void showTooltip(Paintable owner, Event event) { - Element targetElement = event.getEventTarget().cast(); - if (closing && tooltipOwner == owner) { - TooltipInfo newToolTip = getTooltip(owner, targetElement); - if (newToolTip == visibleTooltip) { - // return to same tooltip, cancel closing - closeTimer.cancel(); - closing = false; - justClosedTimer.cancel(); - justClosed = false; - return; - } + public void showTooltip(Paintable owner, Event event, Object key) { + if (closing && tooltipOwner == owner && tooltipKey == key) { + // return to same tooltip, cancel closing + closeTimer.cancel(); + closing = false; + justClosedTimer.cancel(); + justClosed = false; + return; } if (closing) { @@ -129,7 +122,7 @@ public class VTooltip extends VOverlay { showTimer.cancel(); } tooltipOwner = owner; - tooltipTargetElement = targetElement; + tooltipKey = key; // Schedule timer for showing the tooltip according to if it was // recently closed or not. @@ -153,7 +146,7 @@ public class VTooltip extends VOverlay { private Timer showTimer = new Timer() { @Override public void run() { - TooltipInfo info = getTooltip(tooltipOwner, tooltipTargetElement); + TooltipInfo info = ac.getTooltipTitleInfo(tooltipOwner, tooltipKey); if (null != info) { show(info); } @@ -197,38 +190,6 @@ public class VTooltip extends VOverlay { } - /** - * Returns the tooltip that should be shown for the element. Searches upward - * in the DOM tree for registered tooltips until the root of the Paintable - * is found. Returns null if no tooltip was found (none should be shown). - * - * @param paintable - * @param element - * @return - */ - private TooltipInfo getTooltip(Paintable paintable, Element element) { - /* Try to find registered tooltips */ - while (element != null) { - TooltipInfo info = getTooltip(element); - if (info != null) { - return info; - } - - if (ac.getPid(element) != null) { - // This is the Paintable root so we stop searching - break; - } - - element = DOM.getParent(element); - } - - /* - * No registered tooltips found. Still try the owner (needed if we are - * e.g. hovering caption and the owner is not a parent). - */ - return getTooltip(((Widget) paintable).getElement()); - } - private int tooltipEventMouseX; private int tooltipEventMouseY; @@ -238,11 +199,11 @@ public class VTooltip extends VOverlay { } - public void handleTooltipEvent(Event event, Paintable owner) { + public void handleTooltipEvent(Event event, Paintable owner, Object key) { final int type = DOM.eventGetType(event); if ((VTooltip.TOOLTIP_EVENTS & type) == type) { if (type == Event.ONMOUSEOVER) { - showTooltip(owner, event); + showTooltip(owner, event, key); } else if (type == Event.ONMOUSEMOVE) { updatePosition(event); } else { @@ -273,13 +234,4 @@ public class VTooltip extends VOverlay { } } - native TooltipInfo getTooltip(Element e) - /*-{ - return e.vaadinTooltip; - }-*/; - - native void registerTooltip(Element e, TooltipInfo tooltipInfo) - /*-{ - e.vaadinTooltip = tooltipInfo; - }-*/; } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java b/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java index 49d3546eb8..0e6f0f12fd 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTabsheet.java @@ -44,9 +44,10 @@ public class VTabsheet extends VTabsheetBase { if (uidl.hasAttribute(ATTRIBUTE_ERROR)) { tooltipInfo.setErrorUidl(uidl.getErrors()); } - client.registerTooltip(getElement(), tooltipInfo); + client.registerTooltip(VTabsheet.this, getElement(), + tooltipInfo); } else { - client.registerTooltip(getElement(), ""); + client.registerTooltip(VTabsheet.this, getElement(), null); } return super.updateCaption(uidl); @@ -62,8 +63,7 @@ public class VTabsheet extends VTabsheetBase { } updateTabScroller(); } - - client.handleTooltipEvent(event, VTabsheet.this); + client.handleTooltipEvent(event, VTabsheet.this, getElement()); } @Override