2016-04-25 8 views
1

フォーマットされた入力でチャットを作成しようとしていますが、私の問題は、デフォルトでJavaFX HTMLEditorにリンクを張ることができないということです。ハイパーリンク。 私の問題は、1:エディタ内のハイパーリンクがクリック可能で、エディタがリンクを開くとリンクが開き、問題番号2:WebViewでリンクをクリックすると外部ブラウザで開かないwebView自体の内部にあるので、HTMLEditorがWebViewを使用しているので、実際は同じ問題です。 誰も "修正"する方法を知っていますか?JavaFX HTMLEditorハイパーリンク

答えて

1

JavaFXのWebViewは、その下にjava.net.URLConnectionを使用しているので、デフォルトのブラウザでurlを開くOSに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を使用して他のすべてのクラスのための機能を無効にします。私は負荷作業員の位置と状態を試して問題を簡単に解決しました。

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); 
    } 
}); 
:Platform.runLaterなしのロード労働者のキャンセルは、JDKのバージョン8u66上のJVMをクラッシュしたことに注意してください
関連する問題