登录面板是JavaFX,运行在SWT Shell里面。
1. 无侵入式使用FXCanvas
在需要放JavaFX控件的地方,构造一个FXCanvas,然后放入JavaFX控件。
FXCanvas fxCanvas = new FXCanvas(swtComposite, SWT.NONE); LoginPaneFx loginPane = new LoginPaneFx(); fxCanvas.setScene(new Scene(loginPane));
注意:
FXML文件的根节点,要使用<fx:root/>格式,LoginPaneFx必须继承FXML根节点的对象(此处是GridPane)。代码中调用FXMLLoader的setRoot()方法,完成LoginPaneFx和FXML根节点的绑定。
<fx:root type="GridPane" xmlns:fx="http://javafx.com/fxml/1"> ...... </fx:root>
LoginPaneFx 代码
public class LoginPaneFx extends GridPane {
@FXML
private TextField nameTxt;
public LoginPaneFx() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("LoginPaneFx.fxml"));
loader.setRoot(this);
loader.setController(this);
loader.load();
} catch (Exception e) {
e.printStackTrace();
}
}
}
优点:
LoginPaneFx是一个JavaFX的独立控件,可以复用。
缺点:
如果程序中有很多JavaFX控件需要集成,每次都要手动构造FXCanvas,产生冗余代码。
2. 侵入式封装FXCanvas
注意:
FXML文件的根节点,不能使用<fx:root/>格式,因为Controller要继承SWT的Composite。Load FXML时,不可再调用setRoot()方法。
<GridPane xmlns:fx="http://javafx.com/fxml/1"> ...... </GridPane>
CompositeFx 封装抽象类
public abstract class CompositeFx extends Composite {
public CompositeFx(Composite parent, int style) {
super(parent, style);
this.setLayout(new FillLayout());
try {
FXCanvas fxCanvas = new FXCanvas(this, SWT.NONE);
FXMLLoader loader = new FXMLLoader(getFxmlURL());
loader.setController(this);
fxCanvas.setScene(new Scene(loader.load()));
} catch(Exception e) {
e.printStackTrace();
}
}
/**
* Get the URL of a FXML file.
*
* @return a FXML's URL.
*/
protected abstract URL getFxmlURL();
}
LoginComposite 代码
public class LoginComposite extends CompositeFx {
@FXML
private TextField nameTxt;
public LoginComposite(Composite parent, int style) {
super(parent, style);
// Other logic
}
@Override
protected URL getFxmlURL() {
return getClass().getResource("LoginPaneFx.fxml");
}
}
此处LoginComposite是一个SWT的Composite,只需要复写getFxmlURL()方法,使用时几乎不知道JavaFX的存在。
优点:
隐藏FXCanvas和FXMLLoader等相关代码,在大量需要嵌入JavaFX控件时,减少了冗余代码。
缺点:
Controller继承自SWT的Composite,硬性绑定,只能使用在SWT程序中,不能被其它JavaFX程序复用。