monitor mouse events but not capture them
Tomas Mikula
tomas.mikula at gmail.com
Tue Jun 10 13:38:37 UTC 2014
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