您的位置:首页 > 编程语言 > Java开发

(翻译)第七回 JavaFX2.0和Swing的集成

2011-11-02 00:27 435 查看
原文地址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的数据改变引起的.

反之.


改变JavaFX的数据来回应Swing数据的改变

记住JavaFX的数据只能通过javaFX用户线程访问。不论何时要改变JavaFX 数据都要把你的代码用一个Runnable 对象包围起来并调用
Platform.runLater
 方法。见Example 2 .

Example 2
jbutton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Platform.runLater(new Runnable() {
@Override
public void run() {
fxlabel.setText("Swing button clicked!");
}
});
}
});



改变Swing数据来回应JavaFX 数据的改变

记住Swing数据的改变要通过EDT。确保你的代码实现了EDT,把它用Runnable 对象环绕并调用
SwingUtilities.invokeLater
 方法。见Example 3 .

Example 3
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
//Code to change Swing data.
}
});



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 查看。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息