monitor mouse events but not capture them

Tom Eugelink tbee at tbee.org
Tue Jun 10 13:52:13 UTC 2014


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