简体   繁体   中英

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:

两个上下文菜单

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...

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();
                        }
                    }
                }
            });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM