我正在尝试使用格式化输入进行聊天,我的问题是您无法在默认情况下将链接放入JavaFX HTMLEditor,因此我添加了一个按钮,用超链接重新选择所选文本。 我的问题是1:编辑器中的超链接是可点击的,如果你点击它就会导致编辑器打开链接而问题2:当我点击webView中的链接时,它不会在外部浏览器中打开但是在里面因为HTMLEditor使用webView,所以它实际上是相同的问题。 有谁知道如何“修复”那个?
答案 0 :(得分: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的其他每个类的功能,这可能不是您想要的。通过使用加载工作程序的位置和状态,我找到了一个更容易解决问题的方法。请注意,在没有Platform.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);
}
});