关键是其中的逻辑结构设计:自定义的控件很简单:
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.*?> <!-- fx:root is used primarily when creating custom controls --> <fx:root type="javafx.scene.layout.VBox" xmlns:fx="http://javafx.com/fxml" stylesheets="customcontrol/customcontrol.css" styleClass="v-Box"> <TextField fx:id="textField"/> <Button fx:id="button" text="Click Me" onAction="#doSomething"/> </fx:root>
其中使用的CSS样式表:
.v-Box { -fx-spacing: 5; } .text-field { -fx-highlight-fill: linear-gradient(orange,orangered); }
Package-info:
/** * An implementation of custom control. * * @author HAN */ package customcontrol;
模型建立(充当Controller和Root):
package customcontrol; import java.io.IOException; import javafx.beans.property.StringProperty; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.control.Button; import javafx.scene.control.TextField; import javafx.scene.layout.VBox; /** * For custom control creation in XML,it is assured by the associated use of * <code>fxmlLoader.setController(this);</code> and * <code>fxmlLoader.setRoot(this);</code> * * @author HAN * */ public class CustomControl extends VBox { @FXML private TextField textField; @FXML private Button button; public CustomControl() { FXMLLoader fxmlLoader = new FXMLLoader(); fxmlLoader.setController(this); fxmlLoader.setRoot(this); fxmlLoader.setLocation(CustomControl.class.getResource("View.xml")); try { fxmlLoader.load(); } catch (IOException e) { e.printStackTrace(); } } public final String getTextFieldText() { return textFieldTextProperty().get(); } public final void setTextFieldText(String text) { textFieldTextProperty().set(text); } public StringProperty textFieldTextProperty() { return textField.textProperty(); } public final String getButtonText() { return buttonTextProperty().get(); } public final void setButtonText(String text) { buttonTextProperty().set(text); } public StringProperty buttonTextProperty() { return button.textProperty(); } @FXML private void doSomething() { System.out.println("The button was clicked!"); } }
在Java中的使用样例:
1.若此样例不使用自定义的CSS样式表,则默认为开发者定义的风格:
package customcontrol; import javafx.application.Application; import javafx.scene.Scene; import javafx.stage.Stage; public class UseInJava extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) throws Exception { CustomControl customControl = new CustomControl(); customControl.setTextFieldText("Hello!"); customControl.setButtonText("MyButton"); customControl.getStyleClass().add("custom-control"); Scene scene = new Scene(customControl); // scene.getStylesheets().add( // UseInJava.class.getResource("useinjava.css").toExternalForm()); stage.setScene(scene); stage.setTitle("Custom Control"); stage.setWidth(300); stage.setHeight(200); stage.show(); } }
2. 然而强大之处在于用户可以Override开发者定义的控件内部各自Region的风格:
package customcontrol; import javafx.application.Application; import javafx.scene.Scene; import javafx.stage.Stage; public class UseInJava extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) throws Exception { CustomControl customControl = new CustomControl(); customControl.setTextFieldText("Hello!"); customControl.setButtonText("MyButton"); customControl.getStyleClass().add("custom-control"); Scene scene = new Scene(customControl); scene.getStylesheets().add( UseInJava.class.getResource("useinjava.css").toExternalForm()); stage.setScene(scene); stage.setTitle("Custom Control"); stage.setWidth(300); stage.setHeight(200); stage.show(); } }
.custom-control .button { -fx-base: #99bcfd; } .custom-control .text-field { -fx-highlight-fill: linear-gradient(greenyellow,limegreen); }