The push and hold event can be easily simulated in JavaFX, as in this question.
Once you get the initial event, all you need to do is call the ContextMenu from the TextField. Since TextField.getContextMenu()
won't return the default one, you can either provide your own or try to get the default one.
Getting the default one is a little bit more tricky, since it is part of the TextFieldBehavior
class. It contains this method public void contextMenuRequested(ContextMenuEvent e);
, so all you need to do is provide a ContextMenuEvent
, and fire the event from the TextField.
This is a quick implementation:
public class BasicView extends View {
public BasicView(String name) {
super(name);
TextField textField = new TextField();
addPressAndHoldHandler(textField, Duration.seconds(1), event -> {
Bounds bounds = textField.localToScreen(textField.getBoundsInLocal());
textField.fireEvent(new ContextMenuEvent(ContextMenuEvent.CONTEXT_MENU_REQUESTED,
0, 0, bounds.getMinX() + 10, bounds.getMaxY() + 10, false, null));
});
setCenter(new VBox(15.0, new Label("Push and hold for ContextMenu"), textField));
}
private void addPressAndHoldHandler(Node node, Duration holdTime, EventHandler<MouseEvent> handler) {
class Wrapper<T> {
T content;
}
Wrapper<MouseEvent> eventWrapper = new Wrapper<>();
PauseTransition holdTimer = new PauseTransition(holdTime);
holdTimer.setOnFinished(event -> handler.handle(eventWrapper.content));
node.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
eventWrapper.content = event;
holdTimer.playFromStart();
});
node.addEventHandler(MouseEvent.MOUSE_RELEASED, event -> holdTimer.stop());
node.addEventHandler(MouseEvent.DRAG_DETECTED, event -> holdTimer.stop());
}
@Override
protected void updateAppBar(AppBar appBar) {
appBar.setTitleText("Push and Hold");
}
}
On Desktop this is what you'll get:
The good news is you don't need to modify the ContextMenu for Android, JavaFX has a custom one:
Note the different menu items will change automatically based on the context, as in the Desktop popup.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…