Detect mouse hovering over a Tooltip - javafx

In relation to this question I would like to know if it is possible to trigger an event if the mouse is hovering over a Tooltip. I know this method node.setOnMouseEntered() but this applies only to instances of Node (Tooltip does not extend Node).

Get the scene from the Tooltip and register the event handlers there:
Tooltip tooltip = new Tooltip("Something");
Scene tooltipScene = tooltip.getScene();
tooltipScene.setOnMouseEntered(evt -> {
System.out.println("enter");
});
tooltipScene.setOnMouseExited(evt -> {
System.out.println("exit");
});

tooltip.getGraphic() will allow you to get a tooltip as a node.

Related

JavaFX wait for enter

Essentially, what I'm trying to do is something like to a text-based RPG using JavaFX. Right now, to display some text, I've got this:
final IntegerProperty i = new SimpleIntegerProperty(0);
Timeline timeline = new Timeline();
KeyFrame keyFrame = new KeyFrame(
Duration.millis(70),
event -> {
if (i.get() > info.getText().length()) {
timeline.stop();
} else {
text.setText(info.getText().substring(0, i.get()));
i.set(i.get() + 1);
}
});
timeline.getKeyFrames().add(keyFrame);
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
timeline.setOnFinished(a -> {
hb_start.getChildren().clear();
hb_start.getChildren().addAll(start_left,start_right);
hb_start.setAlignment(Pos.CENTER);
});
Because the length of the animation depends on the size of the text, the cyclecount is set to indefinite. Unless there's some other way I'm missing to make the animation play once and then stop, I'd like it so that when you press enter (or some other key that I decide on later) for it to call timeline.stop(); but I can't figure out how to add any sort of listener. Trying to implement keyListenerseems to come with all sorts of stuff that I don't need, and it also doesn't work with a TextField, and instead wants a JTextField, which might be fine, except that I don't have a clue how to do anything with Swing.
Currently, the text is being displayed in aTextFlow from the text of Text. I'm assuming the listener would be added to the TextFlow, or even the scene itself, honestly, I'm at a loss for what to do. It sounds simple, but I can't seem to figure it out.
KeyListener is a AWT class, not a JavaFX class. Unless you're embedding a Swing component in your JavaFX application or a JavaFX node in a Swing application, you should use JavaFX's equivalent EventHandler<KeyEvent> instead. Furthermore there is no need to include a TextField (or Swing's JTextField) in your application just for the sake of receiving key events. You could add the listener directly to the Scene:
final KeyCode stopKey = KeyCode.ENTER;
EventHandler<KeyEvent> handler = event -> {
if (event.getCode() == stopKey) {
timeline.stop();
}
};
scene.setOnKeyPressed(handler);
Note that events can be consumed by nodes before they reach the scene, e.g. by a TextField that has the focus. In this case you could make sure you get the event by registering a the listener as a event filter instead:
// scene.setOnKeyPressed(handler);
scene.addEventFilter(KeyEvent.KEY_PRESSED, handler);

JavaFX textarea listeners

Is it possible to turn off arrow key listeners in TextArea when it has focus. I am reffering mostly to moving scrollpane with them when there is more text than space in area. I'm trying to avoid this.
Thanks for suggestion.
You could use an event filter. Filters receive events during the event capturing phase (1st, down the scene graph) of event processing, whereas handlers are triggered during the event bubbling phase (2nd, up the scene graph). Have a look at this snippet:
TextArea textArea = new TextArea();
textArea.addEventFilter(KeyEvent.ANY, event -> {
KeyCode code = event.getCode();
boolean isArrowKey = code == KeyCode.UP || code == KeyCode.RIGHT
|| code == KeyCode.DOWN || code == KeyCode.LEFT;
if (isArrowKey) {
event.consume();
}
});
The consume() method stops further propagation of the event. As a result, no (key event) listener will be triggered. But this also disables the ability to navigate through the arrow keys—is that really what you want?
EDIT: in regards to your comment, this answer states:
The behavior for controlling the scroll bars is internally coded in the TextAreaSkin (which in Java 8 is not part of the public JavaFX API). You could copy or subclass the TextAreaSkin to customize its behavior and then attach your customized skin to your node. This is really the "proper" way to customize internal control behavior in the way in which you wish.

JavaFX tooltip causes MouseOut

Simply put I only show buttons when I am hovered on the AnchorPane. I wanted a tooltip for a button, but when the mouse hovers on the tooltip this causes me to leave the anchorpane and everything disappears.
Any ideas? Using the stage for hovering to show or not doesn't seem to ever cause the buttons to hide.
//this is an AnchorPane
this.addEventHandler(MouseEvent.MOUSE_EXITED, new EventHandler<MouseEvent>(){
#Override
public void handle(MouseEvent event) {
//Doesn't help: if(!micTooltip.isShowing() && !screenTooltip.isShowing())
showButtons(false);
}
});
similarly the mouse entered shows the buttons. And a tooltip is bound to the buttons.
Try this:
ObservableBooleanValue hover = this.hoverProperty()
.or(micTooltip.getScene().getRoot().hoverProperty())
.or(screenTooltip.getScene().getRoot().hoverProperty());
hover.addListener((obs, wasHovering, isNowHovering) -> showButtons(isNowHovering));
Depending on the exact behavior you need, you might want
hover = this.hoverProperty().or(micTooltip.showingProperty()) ;
etc
You might also find it more convenient to use bindings instead of the listener:
this.getChildren().forEach(button -> button.visibleProperty().bind(hover));
(assuming you want all contents of the anchor pane to appear and disappear on mouseover/out; this line needs to be called after you add the content, obviously).

how to stop getting mouse click events in flex

I have made a hierarchy in which there is a main page, using add element i have attached a component mxml of type group. There is a single button on main page when clicked it should add children of type group in that group type mxml component along with two buttons. Now using one of buttons i am attaching another component mxml type group. the problem is even they overlap i can still excess the children groups of first group component mxml. how can i stop this mouse events to happen.
I think those kind of events usually bubble up to parent components.
You can try using the following code in your mouse click event listener to stop further propagation:
private function onMouseClicked(event: MouseEvent): void {
event.stopPropagation();
... do whatever you wanted when smth was clicked ...
}
By setting enabled, mouseChildren, mouseEnabled to false, you will disable the entire component and it's children. example below
private var myPreviousGroupComponent:Group = null;
function addNewGroup():void
{
if(myPreviousGroupComponent != null)
{
myPreviousGroupComponent.enabled = false;
myPreviousGroupComponent.mouseChildren = false;
myPreviousGroupComponent.mouseEnabled = false;
}
var newGroup:Group = new Group();
addElement(newGroup);
myPreviousGroupComponent = newGroup;
}

Flex - Display a panel at the point where mouse is clicked

I would like to create a component(extending from spark Panel), which upon a buttonclick should show up next to the button(something like a bubble popping up or like the small box opening up when hovering up on profile links in facebook/twitter).
I tried to create a component that implements mx.core.IToolTip and provided the methods required by the interface.
And on the toolTipCreate event, set this component as the tooltip.
This works to an extent. When I bring the mouse over the button, the panel appears as the tooltip and goes away when i move the mouse away.
What I need is, the panel should appear next to the button when click on it and should go away only when I click outside the panel or click the close button present inside the panel.
Can you please provide me your suggestions on how to proceed further?
Thanks
//on the first click...
addChild( mouseX , mouseY );
//or
component.x = mouseX;
component.y = mouseY;
//then tween alpha or make visible
component.visible = true;
//for the click outside , assuming parent is not null
if( event.currentTarget == this.stage || event.currentTarget == this.parent)
component.visible = false;

Resources