2016-04-25 89 views
1

我試圖讓一種具有格式化輸入聊天的,我的問題是,你是不是能夠把鏈接到JavaFX的HTML編輯在默認情況下,所以我增加了一個按鈕,用repalces選定的文本超鏈接。 我的問題是,1:在編輯器中的超鏈接是可點擊的,並且會導致編輯器打開鏈接,如果您點擊它並且問題2:當我點擊webView中的鏈接時,它不會在外部瀏覽器中打開,但是在webView本身內部,所以它實際上是相同的問題,因爲HTMLEditor正在使用webView。有沒有人知道如何「修復」?JavaFX的HTML編輯超鏈接

回答

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

    } 
} 

UPDATE:

以前的解決方案將覆蓋對於使用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); 
    } 
});