有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JavaFX HTMLEditor超链接

我正在尝试使用格式化输入进行聊天,我的问题是,默认情况下,您无法将链接放入JavaFX HTMLEditor,因此我添加了一个按钮,用超链接替换所选文本。 我的问题是1:编辑器中的超链接是可点击的,如果你点击它,它会导致编辑器打开链接,问题2:当我在webView中点击链接时,它不会在外部浏览器中打开,而是在webView内部打开,所以实际上这是一个相同的问题,因为HTMLEditor正在使用webView。 有人知道如何“修复”吗


共 (1) 个答案

  1. # 1 楼答案

    由于JavaFX中的WebView在下面使用java.net.URLConnection,因此可以使用其内置机制来提供自定义处理程序,该处理程序将创建一个连接,该连接将url委托给将在默认浏览器中打开url的操作系统。下面是一个例子:

    import java.io.IOException;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.net.URLConnection;
    import java.net.URLStreamHandler;
    
    import javafx.application.Application;
    import javafx.application.HostServices;
    import javafx.scene.Scene;
    import javafx.scene.web.HTMLEditor;
    import javafx.scene.web.WebView;
    import javafx.stage.Stage;
    
    public class HTMLEditorSample extends Application {
    
      @Override
      public void start(Stage stage) {
    
        stage.setTitle("HTMLEditor Sample");
        stage.setWidth(400);
        stage.setHeight(300);
        final HTMLEditor htmlEditor = new HTMLEditor();
    
        htmlEditor.setPrefHeight(245);
        Scene scene = new Scene(htmlEditor);
        stage.setScene(scene);
        stage.show();
    
        URL.setURLStreamHandlerFactory(protocol -> {
    
          if (protocol.startsWith("http")) {
            return new CustomUrlHandler();
          }
    
          return null;
        });
    
        WebView webview = (WebView) htmlEditor.lookup(".web-view");
        webview.getEngine().load("http://google.com");
    
      }
    
      public static void main(String[] args) {
        launch(args);
      }
    
      public class CustomUrlHandler extends URLStreamHandler {
    
        @Override
        protected URLConnection openConnection(URL u) throws IOException {
          return new HostServicesUrlConnection(u, getHostServices());
        }
      }
    
      public class HostServicesUrlConnection extends HttpURLConnection {
    
        private URL urlToOpen;
        private HostServices hostServices;
    
        protected HostServicesUrlConnection(URL u, HostServices hostServices) {
          super(u);
          this.urlToOpen= u;
          this.hostServices = hostServices;
        }
    
        @Override
        public void disconnect() {
          // do nothing
        }
    
        @Override
        public boolean usingProxy() {
          return false;
        }
    
        @Override
        public void connect() throws IOException {
          hostServices.showDocument(urlToOpen.toExternalForm());
        }
    
        @Override
        public InputStream getInputStream() throws IOException {
          return new InputStream() {
    
            @Override
            public int read() throws IOException {
              return 0;
            }
          };
        }
    
      }
    }
    

    更新:

    之前的解决方案将覆盖使用URLConnection的所有其他类的功能,这可能不是您想要的。我通过使用load worker的位置和状态找到了一个更简单的解决方案。请注意,在没有平台的情况下取消load worker。runLater在JDK版本8u66上使JVM崩溃:

    webview.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
    
      @Override
      public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
        Platform.runLater(() -> {
          webview.getEngine().getLoadWorker().cancel();
        });
      }
    });
    
    webview.getEngine().locationProperty().addListener(new ChangeListener<String>() {
    
      @Override
      public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
        getHostServices().showDocument(newValue);
      }
    });