element-ui
理念
利用JavafX / FXML的声明性设计模式,并允许用户仅通过使用例如SceneBuilder打开某个视图即可重新定制布局或添加新控件,甚至根据用户需要更改样式,从而无需任何编码即可自定义某个视图。
FXML文件+ CSS基本上可以放置在通过URL可以到达的任何地方。 用户必须只知道FXML内部分配的控制器类的接口/方法。
遥控器
假设此简单的演示控制器类提供了用于远程控制设备和发送MQTT消息的方法,则用户能够自定义自己的遥控器。
public class RemoteController{
@FXML
public void onTest(){
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setContentText("");
alert.setHeaderText("WORKS!");
alert.show();
}
public void onTest(String value){
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setHeaderText("WORKS!");
alert.setContentText(value);
alert.show();
}
public void onSwitch(String houseCode, int groudId, int deviceId, String command){
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setHeaderText("Switch!");
alert.setContentText(String.format("Command: send %s %d %d %s", houseCode, groudId, deviceId, command));
alert.show();
}
}
remote.fxml和remote.css
请注意引用的de.jensd.shichimifx.demo.ext.RemoteController
和remote.css
。
因此,基本上可以通过以下方式调用控制器动作:
onAction="#onTest".
不错:
如果添加:
<?language javascript?>
到FXML,也可以通过controller
-instance通过JavaScript调用传递参数。
onAction=controller.onTest('OFF')
onAction=controller.onSwitch('a',1,1,'ON')
不幸的是,除了-> this之外,我找不到有关此功能的更多文档,但是以某种方式它神奇地起作用了;-)。 甚至可以传递不同类型的参数。
<?xml version="1.0" encoding="UTF-8"?>
<?language javascript?>
<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox alignment="TOP_CENTER" prefHeight="400.0" prefWidth="600.0" spacing="20.0" styleClass="main-pane" stylesheets="@remote.css" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.jensd.shichimifx.demo.ext.RemoteController">
<children>
<Label styleClass="title-label" text="Universal Remote" />
<HBox alignment="CENTER_RIGHT" spacing="20.0">
<children>
<Label layoutX="228.0" layoutY="96.0" styleClass="sub-title-label" text="Light Frontdoor" />
<Button layoutX="43.0" layoutY="86.0" mnemonicParsing="false" onAction="#onTest" prefWidth="150.0" styleClass="button-on" text="ON" />
<Button layoutX="411.0" layoutY="86.0" mnemonicParsing="false" onAction="#onTest" prefWidth="150.0" styleClass="button-off" text="OFF" />
</children>
<padding>
<Insets left="10.0" right="10.0" />
</padding>
</HBox>
<HBox alignment="CENTER_RIGHT" spacing="20.0">
<children>
<Label layoutX="228.0" layoutY="96.0" styleClass="sub-title-label" text="Light Garden" />
<Button layoutX="43.0" layoutY="86.0" mnemonicParsing="false" onAction="controller.onTest('ON')" prefWidth="150.0" styleClass="button-on" text="ON" />
<Button layoutX="411.0" layoutY="86.0" mnemonicParsing="false" onAction="controller.onTest('OFF')" prefWidth="150.0" styleClass="button-off" text="OFF" />
</children>
<padding>
<Insets left="10.0" right="10.0" />
</padding>
</HBox>
<HBox alignment="CENTER_RIGHT" spacing="20.0">
<children>
<Label layoutX="228.0" layoutY="96.0" styleClass="sub-title-label" text="Light Garden" />
<Button layoutX="43.0" layoutY="86.0" mnemonicParsing="false" onAction="controller.onSwitch('a', 1,1,'ON')" prefWidth="150.0" styleClass="button-on" text="ON" />
<Button layoutX="411.0" layoutY="86.0" mnemonicParsing="false" onAction="controller.onTest('OFF')" prefWidth="150.0" styleClass="button-off" text="OFF" />
</children>
<padding>
<Insets left="10.0" right="10.0" />
</padding>
</HBox>
</children>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
</VBox>
基于此示例,用户可以使用SceneBuilder轻松打开FXMl,并添加新的Button来调用controller.onSwitch()方法,以控制为家庭自动化安装的不同/新设备。
FxmlUtils
的下一个版本ShichimiFX将包含新Utilily类负载FXML如图中ExternalFXMLDemoController
。 请注意,已加载的窗格通过onLoadExternalFxml()
添加到演示应用程序的externalPane
(BorderPane)的中心:
public class ExternalFXMLDemoController {
@FXML
private ResourceBundle resources;
@FXML
private BorderPane externalPane;
@FXML
private TextField fxmlFileNameTextField;
@FXML
private Button chooseFxmlFileButton;
@FXML
private Button loadFxmlFileButton;
private StringProperty fxmlFileName;
public void initialize() {
fxmlFileNameTextField.textProperty().bindBidirectional(fxmlFileNameProperty());
loadFxmlFileButton.disableProperty().bind(fxmlFileNameProperty().isEmpty());
}
public StringProperty fxmlFileNameProperty() {
if (fxmlFileName == null) {
fxmlFileName = new SimpleStringProperty("");
}
return fxmlFileName;
}
public String getFxmlFileName() {
return fxmlFileNameProperty().getValue();
}
public void setFxmlFileName(String fxmlFileName) {
this.fxmlFileNameProperty().setValue(fxmlFileName);
}
@FXML
public void chooseFxmlFile() {
FileChooser chooser = new FileChooser();
chooser.setTitle("Choose FXML file to load");
if (getFxmlFileName().isEmpty()) {
chooser.setInitialDirectory(new File(System.getProperty("user.home")));
} else {
chooser.setInitialDirectory(new File(getFxmlFileName()).getParentFile());
}
File file = chooser.showOpenDialog(chooseFxmlFileButton.getScene().getWindow());
if (file != null) {
setFxmlFileName(file.getAbsolutePath());
}
}
@FXML
public void onLoadExternalFxml() {
try {
Optional<URL> url = FxmlUtils.getFxmlUrl(Paths.get(getFxmlFileName()));
if (url.isPresent()) {
Pane pane = FxmlUtils.loadFxmlPane(url.get(), resources);
externalPane.setCenter(pane);
} else {
Alert alert = new Alert(Alert.AlertType.WARNING);
alert.setContentText(getFxmlFileName() + " could not be found!");
alert.show();
}
} catch (IOException ex) {
Dialogs.create().showException(ex);
}
}
}
翻译自: https://www.javacodegeeks.com/2015/01/how-to-allow-users-to-customize-the-ui.html
element-ui