=== modified file 'src/com/goldencode/p2j/ui/client/WidgetRegistry.java' --- src/com/goldencode/p2j/ui/client/WidgetRegistry.java 2016-02-17 19:32:15 +0000 +++ src/com/goldencode/p2j/ui/client/WidgetRegistry.java 2016-03-04 20:54:30 +0000 @@ -55,6 +55,7 @@ import java.util.*; import java.util.concurrent.locks.*; +import java.util.function.Predicate; import java.util.logging.*; import com.goldencode.p2j.ui.*; @@ -84,22 +85,22 @@ private final ReadWriteLock lock = new ReentrantReadWriteLock(); /** - * Returns a nearest widget's ancestor having a given type. + * Returns a nearest widget's ancestor that satisfies the target filter condition. * * @param w * The target widget that can have an ancestor of a given type. - * @param type - * The specified type condition. + * @param filter + * The target filter condition. * - * @return The ancestor having the specified type or null if there are no widgets - * satisfied this condition. + * @return The ancestor satisfied the target filter condition or null if there are no + * widgets satisfied this condition. */ - public static Widget findAncestor(Widget w, Class type) + public static Widget findAncestor(Widget w, Predicate filter) { Widget c = w; while (c != null) { - if (c.getClass().equals(type)) + if (filter.test(c)) { return c; } === modified file 'src/com/goldencode/p2j/ui/client/gui/FrameGuiImpl.java' --- src/com/goldencode/p2j/ui/client/gui/FrameGuiImpl.java 2016-02-24 17:44:15 +0000 +++ src/com/goldencode/p2j/ui/client/gui/FrameGuiImpl.java 2016-03-06 15:27:27 +0000 @@ -742,7 +742,8 @@ @Override protected MouseHoverAction createMouseHoverAction() { - return new MouseHoverAction(this) + // frame scroll component is the smallest widget that catch the mouse input and has an id. + return new MouseHoverAction(this, this.frameScroll.getId().asInt()) { @Override protected MousePtrWrapper parentCursor() === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/swing/SwingMouseHandler.java' --- src/com/goldencode/p2j/ui/client/gui/driver/swing/SwingMouseHandler.java 2016-02-18 11:36:28 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/swing/SwingMouseHandler.java 2016-03-06 15:19:42 +0000 @@ -29,11 +29,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Predicate; import com.goldencode.p2j.security.*; import com.goldencode.p2j.ui.WidgetId; import com.goldencode.p2j.ui.client.*; import com.goldencode.p2j.ui.client.event.*; +import com.goldencode.p2j.ui.client.gui.FrameGuiImpl; import com.goldencode.p2j.ui.client.gui.driver.*; import com.goldencode.p2j.ui.client.widget.*; @@ -161,7 +163,7 @@ { Widget mouseSource = findMouseSource(e); lastHoveredWidget = mouseSource; - + if (!processAction(e)) { SwingMouseHandler.super.mouseEntered(e); @@ -375,6 +377,7 @@ } Widget mouseSource = window.findMouseSource(new MouseEvt(e, window)); + return mouseSource; } @@ -415,7 +418,17 @@ return false; } - WidgetId wid = UiUtils.getWidgetId(widget); + // find widget in its ancestor's hierarchy that has an id + Widget parent = WidgetRegistry.findAncestor(widget, new Predicate() + { + @Override + public boolean test(Widget t) + { + return UiUtils.getWidgetId(t) != null; + } + }); + + WidgetId wid = UiUtils.getWidgetId(parent); if (wid == null) { === modified file 'src/com/goldencode/p2j/ui/client/gui/driver/web/WebMouseHandler.java' --- src/com/goldencode/p2j/ui/client/gui/driver/web/WebMouseHandler.java 2016-03-03 16:10:57 +0000 +++ src/com/goldencode/p2j/ui/client/gui/driver/web/WebMouseHandler.java 2016-03-04 20:57:16 +0000 @@ -20,6 +20,7 @@ package com.goldencode.p2j.ui.client.gui.driver.web; import java.awt.event.MouseEvent; +import java.util.function.Predicate; import com.goldencode.p2j.ui.client.*; import com.goldencode.p2j.ui.client.gui.*; @@ -63,7 +64,14 @@ } else { - Widget editor = WidgetRegistry.findAncestor(target, EditorGuiImpl.class); + Widget editor = WidgetRegistry.findAncestor(target, new Predicate() + { + @Override + public boolean test(Widget t) + { + return EditorGuiImpl.class.equals(t.getClass()); + } + }); if (editor != null && editor.getId() != null) { widgetId = editor.getId().asInt();