Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify context menu in JavaFX WebView

I'm trying to add some options to the context menu in a JavaFX WebView when the user right clicks a link, however I can't figure out how to do it.

I found I could add my own context menu using:

            final ContextMenu contextMenu = new ContextMenu();
            view.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent mouseEvent) {
                    System.out.println(mouseEvent.getEventType());
                    if(mouseEvent.isSecondaryButtonDown()) {
                        System.out.println("Secondary");
                        contextMenu.show(view, mouseEvent.getSceneX(), mouseEvent.getSceneY());
                    } else if (mouseEvent.isPrimaryButtonDown()) {
                        System.out.println("Primary");
                    } else if (mouseEvent.isMiddleButtonDown()) {
                        System.out.println("Middle");
                    }
                }
            });

            javafx.scene.control.MenuItem menuItem1 = new javafx.scene.control.MenuItem("View Source");
            menuItem1.setOnAction(new EventHandler<javafx.event.ActionEvent>() {
                @Override
                public void handle(javafx.event.ActionEvent actionEvent) {
                    System.out.println("Link: " + rightClickURL);
                    System.out.println("You clicked view source");
                }
            });

            contextMenu.getItems().add(menuItem1);

Unfortunately, when I do that both menus appear:

Two Context Menus

If I use view.setContextMenuEnabled(false); then the default menu disappears. Unfortunately doing that also prevents me from detecting which link was right clicked. Here is the code I'm using for that:

            engine.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
                @Override
                public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
                    if (newState == Worker.State.SUCCEEDED) {
                        EventListener listener = new EventListener() {

                            @Override
                            public void handleEvent(org.w3c.dom.events.Event evt) {
                                String domEventType = evt.getType();
                                if (domEventType.equals(EVENT_TYPE_CLICK)) {
                                    String href = ((Element)evt.getTarget()).getAttribute("href");

                                } else if (domEventType.equals(EVENT_TYPE_RIGHT_CLICK)) {
                                    String href = ((Element)evt.getTarget()).getAttribute("href");
                                    rightClickURL = href;
                                    System.out.println(href);
                                }
                            }
                        };

                        Document doc = engine.getDocument();
                        NodeList nodeList = doc.getElementsByTagName("a");
                        for (int i = 0; i < nodeList.getLength(); i++) {
                            ((EventTarget) nodeList.item(i)).addEventListener(EVENT_TYPE_CLICK, listener, false);
                            ((EventTarget) nodeList.item(i)).addEventListener(EVENT_TYPE_RIGHT_CLICK, listener, false);
                        }
                    }
                }
            });

So my question is this: how can I access the default ContextMenu so I can customize it? I've scoured the docs but cannot find any method that allows you to access the default ContextMenu. It seems like there must be a way to do this but I'm stumped as to how.

If customizing the default ContextMenu is not possible, does anyone know how I can show a custom context menu when right clicking a link and also capture which link was clicked? I've been trying to achieve this for days with absolutely no luck...

like image 682
facetoe Avatar asked Oct 03 '13 03:10

facetoe


1 Answers

Currently that's not possible. There is an open issue on JavaFX for that: https://javafx-jira.kenai.com/browse/RT-20306

If you just want to add a different context menu, then you could do that

 webView.setOnMouseClicked(new EventHandler<MouseEvent>() {

                @Override
                public void handle(MouseEvent mouse) {
                    if (mouse.getButton() == MouseButton.SECONDARY) {
                        menu = new ContextMenu();
                       //add some menu items here
                       menu.show(this, mouse.getScreenX(), mouse.getScreenY());
                    } else {
                        if (menu != null) {
                            menu.hide();
                        }
                    }
                }
            });
like image 132
Rasha Avatar answered Sep 18 '22 22:09

Rasha