monitor mouse events but not capture them

Tomas Mikula tomas.mikula at gmail.com
Tue Jun 10 17:07:51 UTC 2014


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