0
votes

I couldn't really explain the question in the title.

What I want to do is that when a right mouse-press (not click!) is performed on a element a ContextMenu shows up (this part is easy). The problem is that when I (still holding the mouse button) move my cursor over the items they do not get highlighted and when I release the mouse button the MenuItem does not get selected. The ContextMenu does not seem to be aware of the cursor until I release the button from the press that opened it.

Basically a right mouse-press shows a ContextMenu and releasing the button over a MenuItem should select it. What I am talking about is available in basically every single program (browsers, IDEs, etc.).

var contextMenu = new ContextMenu();
var mi1 = new MenuItem("Item 1");
mi1.setOnAction(e -> System.out.println("Item 1"));
var mi2 = new MenuItem("Item 2");
mi2.setOnAction(e -> System.out.println("Item 2"));
contextMenu.getItems().addAll(mi1, mi2);

node.setOnMousePressed(e -> {
    if (e.getButton() == MouseButton.SECONDARY)
        contextMenu.show(node, e.getScreenX(), e.getScreenY());
});
1
Are you wanting to open the ContextMenu with the right mouse button, then while the mouse button is still pressed, release it over a MenuItem to fire it? - Dustin R
@DustinR Exactly! I also want the MenuItem to be highlighted ("focused") when the cursor is over it but that's not as important as the firing. - Nand
why do you want to confuse your users? the open mouse gesture for opening a context menu is OS dependent .. - kleopatra
It's like that on basically all Linux-based OSes, Windows and Mac. It shouldn't confuse anybody, just introduce more convenience because it works like other parts of the OS. - Nand
I used "hacky" methods of casting and looking up elements and while it seems a bit off, it works as I want it to and is far better than nothing. Might publish my solution if I can make it good enough. - Nand

1 Answers

0
votes

If you want to show the ContextMenu when the right mouse button is clicked, the following will work.

        node.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
            // If the menu is already open, then close it to avoid multiple
            if (cm.isShowing()) {
                cm.hide();
            }
            if (e.isSecondaryButtonDown()) {
                cm.show(stage);
            }
        });

As for then moving the mouse to a MenuItem and releasing the already pressed secondary mouse button to activate the MenuItem, this doesn't seem to be supported.

The MenuItem's onAction is called by default even if the MouseButton is the secondary MouseButton, so unless you implement your own control, then this will be the best you can get.

I've included a complete runnable example of the behavior that I've described below:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;

public class Main extends Application {

    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        Button buttonTest = new Button("Right-Click me!");
        stage.setScene(new Scene(buttonTest));
        stage.show();

        ContextMenu cm = new ContextMenu();
        MenuItem miTest = new MenuItem("Test");
        miTest.setOnAction(e -> new
                Alert(Alert.AlertType.INFORMATION,"Test").showAndWait());
        cm.getItems().add(miTest);
        buttonTest.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
            if (cm.isShowing()) {
                cm.hide();
            }
            if (e.isSecondaryButtonDown()) {
                cm.show(stage);
                e.consume();
            }
        });
    }
}

Note: If you can give an example of an application that exhibits this behavior, maybe I could look into it further and see if there's an equivalent implementation in JavaFX. You mention IDEs, browsers, etc. but I'm unable to reproduce what I think you're describing.