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文件。