8 JavaFX与SWT的互操作性
本文介绍如何将JavaFX场景图添加到标准小部件工具包(SWT)应用程序中,以及如何使SWT和JavaFX控件互操作。
介绍
如果您开发SWT应用程序,您就会知道SWT使用本地操作系统控件,很难配置为使用高级GUI功能,如动画。通过将JavaFX与SWT集成,您可以快速为SWT应用程序添加亮点。您只需要使用javafx.embed.swt包中的FXCanvas类。javafx.embed.swt包可以在jfxswt.jar中找到,该文件位于JDK_Home/jre/lib/目录中。FXCanvas是一个常规的SWT画布,可以在任何出现SWT画布的地方使用。就是这么简单。
在本文中,您将看到如何创建一个交互式的SWT按钮和JavaFX按钮,如图8-1所示。
当用户单击任一按钮时,另一个按钮的文本会发生变化,如图8-2和图8-3所示。这个示例展示了SWT代码和JavaFX代码如何互操作。
将JavaFX内容添加到SWT组件中
在JavaFX中,创建和操作JavaFX类的Java代码运行在JavaFX用户线程中。在SWT中,创建和操作SWT小部件的代码运行在事件循环线程中。当JavaFX嵌入到SWT中时,这两个线程是相同的。这意味着在一个工具包中调用另一个工具包中定义的方法没有限制。
示例8-1显示了创建SWT按钮和JavaFX按钮的代码,如图8-1所示。如代码所示,您可以使用FXCanvas类中的setScene()方法将JavaFX内容设置到FXCanvas中。为了强制SWT根据新的JavaFX内容重新布局画布,首先调整JavaFX内容的大小。为此,获取包含JavaFX内容的JavaFX窗口,并调用sizeToScene()。当JavaFX嵌入到SWT中时,为FXCanvas设置了新的首选大小,使得SWT能够以与其他SWT控件相同的方式调整嵌入的JFX内容的大小。
JavaFX以层次化场景图的形式构建内容,放置在一个场景中。在示例8-1中的代码将JavaFX按钮放置在一个带有图8-4中所示的场景图中,并在代码示例的注释中进行了描述。
示例8-1 纯SWT和JavaFX按钮的Java代码
import javafx.embed.swt.FXCanvas;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.paint.Color;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
public class TwoButtons {
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
final RowLayout layout = new RowLayout();
shell.setLayout(layout);
/* 创建SWT按钮 */
final org.eclipse.swt.widgets.Button swtButton =
new org.eclipse.swt.widgets.Button(shell, SWT.PUSH);
swtButton.setText("SWT按钮");
/* 创建FXCanvas */
final FXCanvas fxCanvas = new FXCanvas(shell, SWT.NONE) {
@Override
public Point computeSize(int wHint, int hHint, boolean changed) {
getScene().getWindow().sizeToScene();
int width = (int) getScene().getWidth();
int height = (int) getScene().getHeight();
return new Point(width, height);
}
};
/* 创建JavaFX Group节点 */
Group group = new Group();
/* 创建JavaFX按钮 */
final Button jfxButton = new Button("JavaFX按钮");
/* 分配CSS ID ipad-dark-grey */
jfxButton.setId("ipad-dark-grey");
/* 将按钮作为Group节点的子节点添加 */
group.getChildren().add(jfxButton);
/* 创建Scene实例并将group节点设置为根节点 */
Scene scene = new Scene(group, Color.rgb(
shell.getBackground().getRed(),
shell.getBackground().getGreen(),
shell.getBackground().getBlue()));
/* 添加外部样式表 */
scene.getStylesheets().add("twobuttons/Buttons.css");
fxCanvas.setScene(scene);
/* 添加监听器 */
swtButton.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
jfxButton.setText("JavaFX按钮:来自SWT的问候");
shell.layout();
}
});
jfxButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
swtButton.setText("SWT按钮:来自JavaFX的问候");
shell.layout();
}
});
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
按钮样式基于Jasper Potts的博客,位于以下位置:http://fxexperience.com/2011/12/styling-fx-buttons-with-css/
在IDE中创建SWT-JavaFX应用程序
在IDE中创建SWT-JavaFX应用程序只需要将以下库添加到您的项目中:
-
swt.jar,从SWT zip下载中获取,下载地址:http://eclipse.org/swt -
jfxswt.jar,从JDK_HOME/jre/lib目录中获取:-
例如,在Windows上默认的JDK安装中,完整路径为:
C:\Program Files\Java\jdk1.8.0\jre\lib
-
注意:
请确保所有的JAR文件都是与您的环境要求相匹配的32位或64位。
打包SWT-JavaFX应用程序
如何打包SWT-JavaFX应用程序取决于JavaFX是否与JDK捆绑(7u6及更高版本)或安装在不同的位置(对于JDK 7u6之前的版本)。
当JavaFX与JDK捆绑在一起时打包应用程序
如果您使用的是NetBeans IDE 7.2或更高版本,则无需特殊处理即可打包应用程序,只需按照在IDE中创建SWT-JavaFX应用程序中描述的添加库的步骤进行即可。您只需执行Clean and Build操作,即可在项目的/dist目录中生成一个可双击的JAR文件。

