идея
Воспользуйтесь преимуществами декларативного шаблона проектирования JavafX / FXML и разрешите пользователям настраивать определенное представление без какого-либо кодирования, просто открывая его, например, с помощью SceneBuilder, чтобы переупорядочить макет или добавить новые элементы управления или даже изменить стиль в соответствии с потребностями пользователей.
Файл FXML + CSS могут быть размещены в любом месте, где они доступны через URL. Пользователь должен знать только интерфейс / методы назначенного класса контроллера внутри FXML.
Пульт дистанционного управления
Предполагая, что этот простой класс демонстрационного контроллера предоставляет методы для удаленного управления устройствами и отправки сообщений MQTT, пользователь может настроить свое собственное дистанционное управление.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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 .
Таким образом, в основном действия контроллера могут быть вызваны через:
|
1
|
onAction="#onTest". |
Ницца:
Если вы добавите:
|
1
|
<?language javascript?> |
в FXML также возможно передавать параметры посредством вызова JavaScript через экземпляр controller .
|
1
2
|
onAction=controller.onTest('OFF')onAction=controller.onSwitch('a',1,1,'ON') |
К сожалению, я не могу найти больше документации об этой функции, чем -> это , но каким-то образом это волшебным образом работает 😉 Можно даже передавать различные типы параметров.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
<?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> |
На основе этого примера пользователь может просто открыть FXMl с помощью SceneBuilder и добавить новую кнопку, вызывающую метод controller.onSwitch () для управления различными / новыми устройствами, установленными для домашней автоматизации.
FxmlUtils
Следующая версия ShichimiFX будет содержать новый класс Utilily для загрузки FXML, как показано в ExternalFXMLDemoController . Обратите внимание, что загруженная панель добавляется в центр externalPane (BorderPane) демонстрационного приложения через onLoadExternalFxml() :
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
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); } }} |
| Ссылка: | Как разрешить пользователям настраивать пользовательский интерфейс от нашего партнера JCG Йенса Детерса в блоге JavaFX Delight . |