monitor mouse events but not capture them

Tom Eugelink tbee at tbee.org
Tue Jun 10 17:14:45 UTC 2014


My internet provider has problems sending to GMail addresses.

For me it worked to register to scene.getRoot().

I like registering to a node, because it allows to install different menu's to different nodes, but still do the most common approach of install a single menu to the top level pane.

Your code already uses addEventHandler, I adopted that.

Tom


On 2014-6-10 19:07, Tomas Mikula wrote:
> Somehow I didn't get your previous email that you are quoting now.
>
> Listening to MOUSE_MOVED events on the Scene seemed to work for me.
> Didn't it work for you? You may as well install the menu to a Scene
> instead of a Node. That will also simplify listening to scene's
> events, because you don't have to worry about the case when the node
> is not yet attached to the scene (when node.getScene() returns null).
>
> By the way, you should probably use addEventHandler instead of
> addEventFilter, to allow child nodes to consume the event if they want
> to override the right click.
>
> Tomas
>
> On Tue, Jun 10, 2014 at 6:50 PM, Tom Eugelink <tbee at tbee.org> wrote:
>> Ah, attaching to Node is a good idea after all!
>>
>> Tom
>>
>>
>> On 2014-6-10 17:44, Tom Eugelink wrote:
>>>
>>> Thanks for all the help, you've given me a lot of helpful tips. I already
>>> was working on a popup based version and I see you ran into the same
>>> problems as I did (initial popup had no width for the circularPane, etc),
>>> the difference is that I bind the menu to Stage, since I do not envision
>>> CirclePopupMenu as a context menu to a specific node. It could of course...
>>> Uncertain about that.
>>>
>>> Anyhow, the only remaining problem is hiding when the mouse exits. Stage
>>> does not send the mouse events to addEventFilter. The node.addEventFilter
>>> does not solve that and on scene I'm not getting the events either. But I
>>> like the way it is going.
>>>
>>> Thanks!
>>>
>>> Tom
>>>
>>>
>>> On 2014-6-10 16:26, Tomas Mikula wrote:
>>>> Here it is, using a Popup:
>>>>
>>>> https://github.com/TomasMikula/jfxtras-labs/blob/8.0/src/main/java/jfxtras/labs/scene/menu/CirclePopupMenu2.java
>>>>
>>>> https://github.com/TomasMikula/jfxtras-labs/blob/8.0/src/main/java/jfxtras/labs/scene/menu/Sample2.java
>>>>
>>>> The nice thing about popup window is that it can extend beyond the
>>>> bounds of the owner window.
>>>> Just let me know if transparency works for you as expected. Some time
>>>> ago transparency stopped working on my system and I didn't care to
>>>> find out why, so my Popup has white background instead of transparent,
>>>> but should be transparent on a healthy system.
>>>>
>>>> On Tue, Jun 10, 2014 at 3:57 PM, Tomas Mikula <tomas.mikula at gmail.com>
>>>> wrote:
>>>>> Just because I wanted to make minimal changes to your code, which was
>>>>> already using StackPane. Yes, Popup would remove the need for a
>>>>> StackPane.
>>>>>
>>>>> On Tue, Jun 10, 2014 at 3:52 PM, Tom Eugelink <tbee at tbee.org> wrote:
>>>>>> You're way ahead of me. Why use stackpane and not popup as suggested?
>>>>>> Wouldn't Popup remove the need for a stackpane?
>>>>>>
>>>>>> Tom
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 2014-6-10 15:38, Tomas Mikula wrote:
>>>>>>> Since talk is cheap, I slightly reworked your code (not using
>>>>>>> PopupWindow) and it seems to work.
>>>>>>>
>>>>>>> CircularPopupMenu:
>>>>>>>
>>>>>>>
>>>>>>> https://github.com/TomasMikula/jfxtras-labs/blob/8.0/src/main/java/jfxtras/labs/scene/menu/CirclePopupMenu1.java
>>>>>>>
>>>>>>> Sample:
>>>>>>>
>>>>>>>
>>>>>>> https://github.com/TomasMikula/jfxtras-labs/blob/8.0/src/main/java/jfxtras/labs/scene/menu/Sample1.java
>>>>>>>
>>>>>>> Main points:
>>>>>>> * No "canvas" pane used, CircularPane is added directly to the stack
>>>>>>> pane.
>>>>>>> * CircularPane is added as the last child to the stack pane in order
>>>>>>> to be on top.
>>>>>>> * CircularPane is an "unmanaged" child of the stack pane, in order to
>>>>>>> allow custom positioning (at mouse pointer)
>>>>>>> * Since setPickOnBounds(false) causes the mouse exit the circular pane
>>>>>>> as soon as it opens, there's slightly more logic to hide the menu
>>>>>>> instead of just listening to MOUSE_EXITED events:
>>>>>>>
>>>>>>>        stackPane.addEventHandler(MouseEvent.MOUSE_MOVED, e -> {
>>>>>>>           if(isShown()) {
>>>>>>>               Bounds localBounds = circularPane.getBoundsInLocal();
>>>>>>>               Bounds screenBounds =
>>>>>>> circularPane.localToScreen(localBounds);
>>>>>>>               if(!screenBounds.contains(e.getScreenX(),
>>>>>>> e.getScreenY())) {
>>>>>>>                   hide();
>>>>>>>               }
>>>>>>>           }
>>>>>>>        });
>>>>>>>
>>>>>>> Cheers,
>>>>>>> Tomas
>>>>>>>
>>>>>>> On Tue, Jun 10, 2014 at 1:45 PM, Tomas Mikula <tomas.mikula at gmail.com>
>>>>>>> wrote:
>>>>>>>> What about using Popup, which is a subclass of PopupWindow? You just
>>>>>>>> need
>>>>>>>> to
>>>>>>>> populate its content
>>>>>>>>
>>>>>>>>        popup.getContent().addAll(Node...);
>>>>>>>>
>>>>>>>> and then show it at the right position, relative to any node
>>>>>>>>
>>>>>>>>        popup.show(canvas, x, y);
>>>>>>>>
>>>>>>>> Tomas
>>>>>>>>
>>>>>>>> On Jun 10, 2014 8:49 AM, "Tom Eugelink" <tbee at tbee.org> wrote:
>>>>>>>>>
>>>>>>>>> Looking at PopupWindow; that is an abstract class and I'm not
>>>>>>>>> finding
>>>>>>>>> much
>>>>>>>>> examples on how to use it. Maybe extending PopupControl would be a
>>>>>>>>> better
>>>>>>>>> choice.
>>>>>>>>>
>>>>>>>>> Been looking at the ContextMenu source code (which is extending
>>>>>>>>> PopupControl), but it is somewhat mysterious how those MenuItems get
>>>>>>>>> rendered. I would expect maybe a skin, but I'm not finding it.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 2014-6-9 13:48, Tomas Mikula wrote:
>>>>>>>>>> Hi Tom,
>>>>>>>>>>
>>>>>>>>>> I am in favor of the menu being a PopupWindow, but alternatively,
>>>>>>>>>> could your "canvas" be a Group instead of a Pane?
>>>>>>>>>>
>>>>>>>>>> The code would look like this:
>>>>>>>>>>
>>>>>>>>>>         StackPane stack = new StackPane();
>>>>>>>>>>
>>>>>>>>>>         Group canvas = new Group();
>>>>>>>>>>         canvas.setManaged(false);
>>>>>>>>>>
>>>>>>>>>>         stack.setOnMousePressed(e -> {
>>>>>>>>>>             // layout in the top left corner of the stack pane
>>>>>>>>>>             canvas.setLayoutX(0);
>>>>>>>>>>             canvas.setLayoutY(0);
>>>>>>>>>>
>>>>>>>>>>             stack.getChildren().add(canvas);
>>>>>>>>>>         });
>>>>>>>>>>
>>>>>>>>>> Regards,
>>>>>>>>>> Tomas
>>>>>>>>>>
>>>>>>>>>> On Mon, Jun 9, 2014 at 11:01 AM, Tom Eugelink <tbee at tbee.org>
>>>>>>>>>> wrote:
>>>>>>>>>>> But a PopupWindow would be detached from the pane? Not sure if
>>>>>>>>>>> that is
>>>>>>>>>>> what
>>>>>>>>>>> I envision, but I'll give it a go and see what it looks like.
>>>>>>>>>>>
>>>>>>>>>>> Your event filter does work though for what I need now.
>>>>>>>>>>>
>>>>>>>>>>> Thanks!
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On 2014-6-9 10:41, Martin Sladecek wrote:
>>>>>>>>>>>> Oh, I see. So it's not a PopupWindow at all.
>>>>>>>>>>>> Events can pass only though parent-child hierarchy, so you can't
>>>>>>>>>>>> catch
>>>>>>>>>>>> an
>>>>>>>>>>>> Event in your "circular menu" pane and then pass it to some other
>>>>>>>>>>>> children
>>>>>>>>>>>> of the parent StackPane. The menu pane would have to be parent of
>>>>>>>>>>>> the
>>>>>>>>>>>> controls in the StackPane.
>>>>>>>>>>>> So again, you'd need RT-20184 to determine the target again by
>>>>>>>>>>>> temporarily
>>>>>>>>>>>> making the menu pane mouse transparent, doing Scene.pick and then
>>>>>>>>>>>> redirecting the Event by Event.fireEvent().
>>>>>>>>>>>>
>>>>>>>>>>>> But I think reworking you menu to be a PopupWindow should work.
>>>>>>>>>>>> The
>>>>>>>>>>>> transparent areas in the circular menu should pass mouse events
>>>>>>>>>>>> to
>>>>>>>>>>>> the
>>>>>>>>>>>> underlying window.
>>>>>>>>>>>>
>>>>>>>>>>>> -Martin
>>>>>>>>>>>>
>>>>>>>>>>>> On 06/09/2014 10:20 AM, Tom Eugelink wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>> Or to see in in action with a single java -jar statement,
>>>>>>>>>>>>> download
>>>>>>>>>>>>> the
>>>>>>>>>>>>> samples from.
>>>>>>>>>>>>> http://jfxtras.org/
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On 2014-6-9 10:13, Martin Sladecek wrote:
>>>>>>>>>>>>>> OK, so to avoid further confusion, you have a PopupWindow with
>>>>>>>>>>>>>> a
>>>>>>>>>>>>>> Pane
>>>>>>>>>>>>>> and you want to capture Events on the Pane and sent those
>>>>>>>>>>>>>> events to
>>>>>>>>>>>>>> the
>>>>>>>>>>>>>> underlying controls (in a parent window) if those events are
>>>>>>>>>>>>>> not
>>>>>>>>>>>>>> relevant to
>>>>>>>>>>>>>> that popup?
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>> -Martin
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On 06/09/2014 10:07 AM, Tom Eugelink wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Hm, maybe I chose bad words; I'm not using Canvas, but just a
>>>>>>>>>>>>>>> Pane.
>>>>>>>>>>>>>>> Since the Pane is only used to draw the menu on when it need
>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>> appear, I'm
>>>>>>>>>>>>>>> calling it the canvas pane, as in "what is painted on".
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On 2014-6-9 9:46, Martin Sladecek wrote:
>>>>>>>>>>>>>>>> Just looked at the code and it seems Canvas does pick on
>>>>>>>>>>>>>>>> bounds
>>>>>>>>>>>>>>>> independently of the pickOnBounds value. There's currently no
>>>>>>>>>>>>>>>> logic
>>>>>>>>>>>>>>>> for
>>>>>>>>>>>>>>>> picking only when over an opaque pixel ( worth filing a JIRA
>>>>>>>>>>>>>>>> issue
>>>>>>>>>>>>>>>> maybe?).
>>>>>>>>>>>>>>>> This makes Canvas to consume everything as it's always picked
>>>>>>>>>>>>>>>> instead of
>>>>>>>>>>>>>>>> some controls underneath.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Unfortunately, I can't think of any solution that would work
>>>>>>>>>>>>>>>> right
>>>>>>>>>>>>>>>> now. If we'd support Node picking
>>>>>>>>>>>>>>>> (https://javafx-jira.kenai.com/browse/RT-20184), it would be
>>>>>>>>>>>>>>>> possible to
>>>>>>>>>>>>>>>> "redirect" an unwanted event to a different event target on
>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>> mouse
>>>>>>>>>>>>>>>> position.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> -Martin
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On 06/09/2014 08:44 AM, Tom Eugelink wrote:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Yessss. It does not work on the canvas pane, I suspect
>>>>>>>>>>>>>>>>> because
>>>>>>>>>>>>>>>>> of
>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>> pickOnBounds, but it does work on the stackpane. Plus, I can
>>>>>>>>>>>>>>>>> register to the
>>>>>>>>>>>>>>>>> stack pane without claiming the onMouseClick/Press hook.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Many thanks!
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Tom
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> On 2014-6-9 8:29, Martin Sladecek wrote:
>>>>>>>>>>>>>>>>>> Hi Tom,
>>>>>>>>>>>>>>>>>> have you tried .addEventFilter() method? It receives the
>>>>>>>>>>>>>>>>>> Event
>>>>>>>>>>>>>>>>>> before the controls underneath the canvas, in the capturing
>>>>>>>>>>>>>>>>>> phase. If you
>>>>>>>>>>>>>>>>>> don't consume the Event, it should pass down to the
>>>>>>>>>>>>>>>>>> controls.
>>>>>>>>>>>>>>>>>> For more on the topic, see
>>>>>>>>>>>>>>>>>> http://docs.oracle.com/javafx/2/events/processing.htm or
>>>>>>>>>>>>>>>>>> http://parleys.com/play/514892290364bc17fc56c39f
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> -Martin
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> On 06/09/2014 08:19 AM, Tom Eugelink wrote:
>>>>>>>>>>>>>>>>>>> Hi all,
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Maybe someone has solved this already, so I thought I pop
>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>> question. Currently I'm working on CirclePopupMenu; a menu
>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>> is supposed
>>>>>>>>>>>>>>>>>>> to pop up on any place in a scene when a certain (usually
>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>> middle or
>>>>>>>>>>>>>>>>>>> right) mouse button is pressed.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Right now CirclePopupMenu requires a stackpane to which it
>>>>>>>>>>>>>>>>>>> binds
>>>>>>>>>>>>>>>>>>> itself. CirclePopupMenu initially places an empty "canvas"
>>>>>>>>>>>>>>>>>>> Pane
>>>>>>>>>>>>>>>>>>> on the stack
>>>>>>>>>>>>>>>>>>> pane, and will use that to render and position the menu
>>>>>>>>>>>>>>>>>>> when
>>>>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>>>>> needs to
>>>>>>>>>>>>>>>>>>> appear.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Also I need to monitor the mouse to detect if the menu
>>>>>>>>>>>>>>>>>>> should
>>>>>>>>>>>>>>>>>>> appear. In order to do that, I would like to use that
>>>>>>>>>>>>>>>>>>> canvas
>>>>>>>>>>>>>>>>>>> pane, but then
>>>>>>>>>>>>>>>>>>> any non relevant button clicks will not reach the
>>>>>>>>>>>>>>>>>>> underlying
>>>>>>>>>>>>>>>>>>> controls. In
>>>>>>>>>>>>>>>>>>> order to enable correct behavior I need to
>>>>>>>>>>>>>>>>>>> setPickOnBounds(false) on the
>>>>>>>>>>>>>>>>>>> pane, but then it does receive the mouse events anymore.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Is there any way to monitor mouse events but still pass
>>>>>>>>>>>>>>>>>>> them
>>>>>>>>>>>>>>>>>>> through to the underlying controls? In Swing I did
>>>>>>>>>>>>>>>>>>> something
>>>>>>>>>>>>>>>>>>> similar and
>>>>>>>>>>>>>>>>>>> used a system level mouse event hook.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Tom
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> PS: I'm not certain if the stackpane approach I've used is
>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>> best
>>>>>>>>>>>>>>>>>>> way to do this. It does work expect the mouse button
>>>>>>>>>>>>>>>>>>> problem.
>>>>>>>>>>>>>>>>>>> But any
>>>>>>>>>>>>>>>>>>> suggestions are welcome.
>>>>>>>>>>>>>>>>>>
>>>
>>




More information about the openjfx-dev mailing list