原文地址http://download.oracle.com/javafx/2.0/swing/jfxpub-swing.htm
JavaFX 2.0 發佈版引入了JFXPanel類,它位於
javafx.embed.swing
包中,使你能夠將JavaFX內容綁定進Swing
程序。
本文教你怎麼將JavaFX內容加進Swing 程序中並指導你如何在一個同時具備Swing 和JavaFX 的應用中正確使用線程。
添加JavaFX到Swing組件
要達到本文的目的,你要創建一個JFrame
組件,並添加一個JFXPanel
對象,JFXPanel組件的圖形場景要包含JavaFX
內容。
和所有的Swing程序一樣,你要在 Event Dispatch Thread (事件調度線程EDT)上創建圖形用戶接口(GUI) 。Example 1 展示了initAndShowGUI
方法,它創建了一個JFrame
組件並添加了JFXPanel
對象。創建JFXPanel
類的實例會在後臺開始JavaFX
運行時。GUI 創建後,調用initFX
方法在JavaFX線程上創建JavaFX場景。
Example 1
public class Test { private static void initAndShowGUI() { // This method is invoked on the EDT thread JFrame frame = new JFrame("FX"); final JFXPanel fxPanel = new JFXPanel(); frame.add(fxPanel); frame.setVisible(true); Platform.runLater(new Runnable() { @Override public void run() { initFX(fxPanel); } }); } private static void initFX(JFXPanel fxPanel) { // This method is invoked on the JavaFX thread Scene scene = createScene(); fxPanel.setScene(scene); } private static Scene createScene() { //Code to create the JavaFX scene } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { initAndShowGUI(); } }); } }
JavaFX-Swing的互操作性和線程
由於JavaFX和Swing的數據存在與一個程序中,你可能遇到以下互操作的情況:
-
一個JavaFX的數據改變是由Swing的數據改變引起的.
-
反之.
SwingBrowser2: 一個集成了JavaFX組件的Swing應用
通過SwingBrowser2
可以看到 Swing - JavaFX是怎麼互操作的,它爲瀏覽器提供了常用的基本功能。你可以在它的地址欄中鍵入一個URL 來查看應用窗口加載的頁面。你可以通過點頁面鏈接去到新頁面、返回前一頁、打開標籤頁、加入書籤、全頁面檢索。 Figure 1是該應用的窗口。
Figure 1 The SwingBrowser2 application window
Description of "Figure 1 The SwingBrowser2 application window"
初始化Swing數據
你可以從一個NB工程中的側邊欄點鏈接來下載swingbrowser2.zip
文件。解壓到本地並從Netbeans IDE中運行爲工程。確保你的NetBeans IDE版本是支持的。
SwingBrowser2打開後,它的GUI創建就在
EDT上。通過邊欄的鏈接查看 Main.java
文件。
應用的頂層窗口是一個 JFrame
組件,包含了很多Swing 組件,比如一個tabbed面板,一個menu,幾個text field、button,還有一個要顯示JavaFX內容的JFX 面板。
加載 JavaFX內容
剛開始運行,JFX面板包含一個空的WebView
對象。當在地址欄輸入一個URL後, AddressBar.java中的
action
listener 就開始加載頁面。代碼見Example 4 .
Example 4
txtURL.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { browser.load(txtURL.getText()); } });
Browser.java文件中的load
方法驗證URL並調用call方法,見
Example 5 .
Example 5
public void load(String str) { if (str != null { str = str.trim(); if (str.isEmpty()) return; String url = toURL(str); if (url == null) { url = toURL("http://" + str); } if (url != null) { Platform.runLater (new Runnable() { @Override public void run () { call(url); } } } private static String toURL(String str) { try { return new URL(str).toExternalForm(); } catch (MalformedURLException exception) { return null; } }
JavaFX數據應該只能在JavaFX線程上訪問。call方法驗證了線程並確保特點URL的頁面被加載在
JavaFX線程上。Callback.java
文件中有完整代碼。Example
6 是表明了實現方案的代碼塊。
Example 6
public final void call(final String value) { if (Platform.isFXApplicationThread()) { callImpl(value); } else { Platform.runLater(new Runnable() { @Override public void run() { callImpl(value); } }); } } protected void callImpl(String value) { getEngine().load(value); }
更新Swing數據
當 WebView
組件加載了新頁面後,頁面標題就從JavaFX數據中取回並傳遞給Swing GUI。然後頁面標題就顯示在標籤頁上並加入應用標題。 TabbedBrowser.java
中有完整代碼。Example
7 是表明了實現方案的代碼塊。
Example 7
public WebPane addNewTab(final String url, boolean selected) { ... final WebPane wp = new WebPane(url); wp.getBrowser().getEngine().titleProperty().addListener( new javafx.beans.value.ChangeListener<String>() { @Override public void changed(ObservableValue<? extends String> observable, String oldValue, final String title) { EventQueue.invokeLater(new Runnable() { @Override public void run() { setTitleAt(indexOfComponent(wp), title); setToolTipTextAt(indexOfComponent(wp), title); if (getSelectedComponent() == wp) { setWindowTitle(title); } } )}; } )}; }
想了解怎麼部署二者的整合應用,到 Deploying JavaFX Applications 查看。