本文内容转载自JavaFXChina,部分内容或代码有修改。本文我只列举了部分较为常用的组件,完整的组件文档可以去JavaFXChina学习。本站其余组件相关的知识我也会在整个javafx基础都涉及一遍后再新开文章更新。本文使用到的图片等资源可以去这里下载,完整项目点击这里下载。如果运行失败,检查编译之后的目录中是否存在对应静态资源。本文的重点是了解各种组件,与布局相关的知识暂时只需要了解,后面会单独学习布局相关内容。
- 标签(label)
label可以用来展示文字,图片等信息。具体用法参考下方代码和注释。
public class TestUI extends Application {
Label label3 = new Label("A label that needs to be wrapped");
@Override
public void start(Stage stage) {
stage.setTitle("Label Sample");
stage.setWidth(420);
stage.setHeight(180);
Image image = new Image(getClass().getResourceAsStream("/labels.jpg"));
Label label1 = new Label("Search");//参数为文字内容
label1.setGraphic(new ImageView(image));//显示图片
label1.setFont(new Font("Arial", 30));//设置字体
label1.setTextFill(Color.web("#0076a3"));//文字颜色
label1.setTextAlignment(TextAlignment.JUSTIFY);//对齐方向
Label label2 = new Label("Values");
label2.setFont(Font.font("Cambria", 32));
label2.setRotate(270);//顺时针旋转270度
label2.setTranslateY(50);//Y轴移动
label3.setWrapText(true);//启用文本折叠换行
label3.setTranslateY(50);
label3.setPrefWidth(100);
label3.setOnMouseEntered((MouseEvent e) -> {//鼠标移入事件
label3.setScaleX(1.5);//X方向缩放倍数
label3.setScaleY(1.5);//Y方向缩放倍数
});
label3.setOnMouseExited((MouseEvent e) -> {//鼠标移出事件
label3.setScaleX(1);
label3.setScaleY(1);
});
HBox hbox = new HBox();
hbox.setSpacing(10);//内部组件之间的距离
hbox.getChildren().add((label1));
hbox.getChildren().add(label2);
hbox.getChildren().add(label3);
Scene scene = new Scene(new Group());
((Group) scene.getRoot()).getChildren().add(hbox);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
- 按钮(button)
按钮可以有文字和图标。
public class TestButton extends Application {
private static final Color color = Color.web("#464646");
Button button3 = new Button("Decline");
DropShadow shadow = new DropShadow();
Label label = new Label();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Button Sample");
stage.setWidth(300);//设置宽度
stage.setHeight(190);//设置高度
scene.getStylesheets().add("/button.css");//使用css
label.setFont(Font.font("Times New Roman", 22));//字体
label.setTextFill(color);//颜色
Image imageDecline = new Image(getClass().getResourceAsStream("/not.png"));
Image imageAccept = new Image(getClass().getResourceAsStream("/ok.png"));
VBox vbox = new VBox();
vbox.setLayoutX(20);
vbox.setLayoutY(20);
HBox hbox1 = new HBox();
HBox hbox2 = new HBox();
Button button1 = new Button("Accept", new ImageView(imageAccept));//创建有图标和文字的按钮
button1.getStyleClass().add("button1");//新增class叫button1,类似html的class="button1"
button1.setOnAction((ActionEvent e) -> {
label.setText("Accepted");
});
Button button2 = new Button("Accept");
button2.setOnAction((ActionEvent e) -> {//按钮点击触发
label.setText("Accepted");
});
button3.setOnAction((ActionEvent e) -> {
label.setText("Declined");
});
button3.addEventHandler(MouseEvent.MOUSE_ENTERED, (MouseEvent e) -> {//鼠标移入触发
button3.setEffect(shadow);
});
button3.addEventHandler(MouseEvent.MOUSE_EXITED, (MouseEvent e) -> {//鼠标移除触发
button3.setEffect(null);
});
hbox1.getChildren().add(button2);
hbox1.getChildren().add(button3);
hbox1.getChildren().add(label);
hbox1.setSpacing(10);
hbox1.setAlignment(Pos.BOTTOM_CENTER);
Button button4 = new Button();
button4.setGraphic(new ImageView(imageAccept));
button4.setOnAction((ActionEvent e) -> {
label.setText("Accepted");
});
Button button5 = new Button();
button5.setGraphic(new ImageView(imageDecline));
button5.setOnAction((ActionEvent e) -> {
label.setText("Declined");
});
hbox2.getChildren().add(button4);
hbox2.getChildren().add(button5);
hbox2.setSpacing(25);
vbox.getChildren().add(button1);
vbox.getChildren().add(hbox1);
vbox.getChildren().add(hbox2);
vbox.setSpacing(10);
((Group)scene.getRoot()).getChildren().add(vbox);
stage.setScene(scene);
stage.show();
}
}
- 单选按钮(RadioButton)
public class TestRadioButton extends Application {
final ImageView icon = new ImageView();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Radio Button Sample");
stage.setWidth(250);
stage.setHeight(150);
final ToggleGroup group = new ToggleGroup();
RadioButton rb1 = new RadioButton("Home");//创建一个文字内容为Home的单选按钮
rb1.setToggleGroup(group);//放入同一个group中的单选按钮不能同时选中
rb1.setUserData("Home");//设置该单选按钮绑定的值,值可以和显示内容不一样
RadioButton rb2 = new RadioButton("Calendar");
rb2.setToggleGroup(group);
rb2.setUserData("Calendar");
RadioButton rb3 = new RadioButton("Contacts");
rb3.setToggleGroup(group);
rb3.setUserData("Contacts");
group.selectedToggleProperty().addListener(//单选按钮选择之后触发
(ObservableValue<? extends Toggle> ov, Toggle old_toggle,
Toggle new_toggle) -> {
if (group.getSelectedToggle() != null) {
final Image image = new Image(//根据选择的不同按钮获取对应的值,计算出不同图片路径,用以展示。
Objects.requireNonNull(getClass().getClassLoader().getResourceAsStream(
group.getSelectedToggle().getUserData().toString() +
".jpg"
))
);
icon.setImage(image);
}
});
HBox hbox = new HBox();
VBox vbox = new VBox();
vbox.getChildren().add(rb1);
vbox.getChildren().add(rb2);
vbox.getChildren().add(rb3);
vbox.setSpacing(10);
hbox.getChildren().add(vbox);
hbox.getChildren().add(icon);
hbox.setSpacing(50);
hbox.setPadding(new Insets(20, 10, 10, 20));
((Group) scene.getRoot()).getChildren().add(hbox);
stage.setScene(scene);
stage.show();
}
}
- 开关按钮(ToggleButton)
开关按钮和单选按钮区别:在点击已经被选中的开关按钮时可以取消选中,而单选按钮不行。
public class TestToggleButton extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
stage.setTitle("Toggle Button Sample");
stage.setWidth(250);
stage.setHeight(180);
Rectangle rect = new Rectangle();//矩形框
rect.setHeight(50);//高度
rect.setFill(Color.WHITE);//内部填充颜色
rect.setStroke(Color.DARKGRAY);//边框颜色
rect.setStrokeWidth(2);//边框宽度
rect.setArcHeight(10);//边角变圆
rect.setArcWidth(10);//边角变圆
final ToggleGroup group = new ToggleGroup();
//点击开关按钮时触发,每次点击都会触发
group.selectedToggleProperty().addListener(
//oldToggle之前被选中的,newToggle之后被选中的
(observableValue, oldToggle, newToggle) -> {
if (newToggle == null) {
rect.setFill(Color.WHITE);
} else {
rect.setFill((Color) group.getSelectedToggle().getUserData());
}
});
ToggleButton tb1 = new ToggleButton("Minor");
tb1.setToggleGroup(group);
tb1.setUserData(Color.LIGHTGREEN);
tb1.setSelected(true);
tb1.getStyleClass().add("toggle-button1");
ToggleButton tb2 = new ToggleButton("Major");
tb2.setToggleGroup(group);
tb2.setUserData(Color.LIGHTBLUE);
tb2.getStyleClass().add("toggle-button2");
ToggleButton tb3 = new ToggleButton("Critical");
tb3.setToggleGroup(group);
tb3.setUserData(Color.SALMON);
tb3.getStyleClass().add("toggle-button3");
HBox hbox = new HBox();
hbox.getChildren().addAll(tb1, tb2, tb3);
VBox vbox = new VBox();
vbox.getChildren().add(new Label("Priority:"));
vbox.getChildren().add(hbox);
vbox.getChildren().add(rect);
vbox.setPadding(new Insets(20, 10, 10, 20));
Scene scene = new Scene(new Group(vbox));
stage.setScene(scene);
scene.getStylesheets().add("/ToggleButton.css");
stage.show();
rect.setWidth(hbox.getWidth());
}
}
- 复选框(Checkbox)
public class TestCheckbox extends Application {
Rectangle rect = new Rectangle(90, 30);
final String[] names = new String[]{"Security", "Project", "Chart"};
final Image[] images = new Image[names.length];
final ImageView[] icons = new ImageView[names.length];
final CheckBox[] cbs = new CheckBox[names.length];
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Checkbox Sample");
stage.setWidth(250);
stage.setHeight(150);
rect.setArcHeight(10);
rect.setArcWidth(10);
rect.setFill(Color.rgb(41, 41, 41));
for (int i = 0; i < names.length; i++) {
final Image image = images[i] = new Image(Objects.requireNonNull(getClass().getClassLoader().getResourceAsStream(names[i] + ".png")));
final ImageView icon = icons[i] = new ImageView();
final CheckBox cb = cbs[i] = new CheckBox(names[i]);
//每次勾选或取消勾选触发
cb.selectedProperty().addListener((observableValue, old_val, new_val) -> icon.setImage(new_val ? image : null));
}
VBox vbox = new VBox();
vbox.getChildren().addAll(cbs);
vbox.setSpacing(5);
HBox hbox = new HBox();
hbox.getChildren().addAll(icons);
hbox.setPadding(new Insets(0, 0, 0, 5));
StackPane stack = new StackPane();
stack.getChildren().add(rect);
stack.getChildren().add(hbox);
StackPane.setAlignment(rect, Pos.TOP_CENTER);
HBox root = new HBox();
root.getChildren().add(vbox);
root.getChildren().add(stack);
root.setSpacing(40);
root.setPadding(new Insets(20, 10, 10, 20));
((Group) scene.getRoot()).getChildren().add(root);
stage.setScene(scene);
stage.show();
}
}
- 选择框(ChoiceBox)
类似html中的下拉框
public class TestChoiceBox extends Application {
Rectangle rect = new Rectangle(150, 30);
final Label label = new Label("Hello");
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
scene.setFill(Color.ALICEBLUE);
stage.setScene(scene);
stage.show();
stage.setTitle("ChoiceBox Sample");
stage.setWidth(300);
stage.setHeight(200);
label.setFont(Font.font("Arial", 25));
label.setLayoutX(40);
final String[] greetings = new String[]{"Hello", "Hola", "Привет", "你好",
"こんにちは"};
final ChoiceBox<String> choiceBox = new ChoiceBox<>(FXCollections.observableArrayList(
"English", "Español", "Русский", "简体中文", "日本語")
);
choiceBox.getSelectionModel().selectedIndexProperty().addListener(//选择的内容变化时触发
(ObservableValue<? extends Number> observableValue, Number old_val, Number new_val) -> {
label.setText(greetings[new_val.intValue()]);
});
choiceBox.setTooltip(new Tooltip("Select the language"));//鼠标移动到下拉框上会显示该提示
choiceBox.setValue("English");//设置初始值
HBox hb = new HBox();
hb.getChildren().addAll(choiceBox, label);
hb.setSpacing(30);
hb.setAlignment(Pos.CENTER);
hb.setPadding(new Insets(10, 0, 0, 10));
((Group) scene.getRoot()).getChildren().add(hb);
}
}
- 文本框(TextField)
public class TestTextField extends Application {
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group(), 300, 150);
stage.setScene(scene);
stage.setTitle("Text Field Sample");
//创建GridPane容器
GridPane grid = new GridPane();
grid.setPadding(new Insets(10, 10, 10, 10));
grid.setVgap(5);
grid.setHgap(5);
scene.setRoot(grid);
//定义Name Text Field
final TextField name = new TextField();
name.setPromptText("Enter your first name.");
GridPane.setConstraints(name, 0, 0);
grid.getChildren().add(name);
//定义Last Name Text Field
final TextField lastName = new TextField();
lastName.setPromptText("Enter your last name.");
GridPane.setConstraints(lastName, 0, 1);
grid.getChildren().add(lastName);
//定义Comment Text Field
final TextField comment = new TextField();
comment.setPromptText("Enter your comment.");
GridPane.setConstraints(comment, 0, 2);
grid.getChildren().add(comment);
//定义Submit Button
Button submit = new Button("Submit");
GridPane.setConstraints(submit, 1, 0);
grid.getChildren().add(submit);
//定义Reset Button
Button clear = new Button("Reset");
GridPane.setConstraints(clear, 1, 1);
grid.getChildren().add(clear);
final Label label = new Label();
GridPane.setConstraints(label, 0, 3);
GridPane.setColumnSpan(label, 2);
grid.getChildren().add(label);
submit.setOnAction((ActionEvent e) -> {
if ((comment.getText() != null && !comment.getText().isEmpty())) {
label.setText(name.getText() + " " +
lastName.getText() + ", "
+ "thank you for your comment!");
} else {
label.setText("You have not left a comment.");
}
});
clear.setOnAction((ActionEvent e) -> {
name.clear();
lastName.clear();
comment.clear();
label.setText(null);
});
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
- 密码框(PasswordField)
和文本框类似,可以通过getText()获取输入的内容。
public class TestPasswordFiled extends Application {
final Label message = new Label("");
@Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root, 260, 80);
stage.setScene(scene);
stage.setTitle("Password Field Sample");
VBox vb = new VBox();
vb.setPadding(new Insets(10, 0, 0, 10));
vb.setSpacing(10);
HBox hb = new HBox();
hb.setSpacing(10);
hb.setAlignment(Pos.CENTER_LEFT);
Label label = new Label("Password");
final PasswordField passwordField = new PasswordField();
passwordField.setText("Your password");
passwordField.setOnAction((ActionEvent e) -> {
if (!passwordField.getText().equals("T2f$Ay!")) {
message.setText("Your password is incorrect!");
message.setTextFill(Color.rgb(210, 39, 30));
} else {
message.setText("Your password has been confirmed");
message.setTextFill(Color.rgb(21, 117, 84));
}
passwordField.clear();
});
hb.getChildren().addAll(label, passwordField);
vb.getChildren().addAll(hb, message);
scene.setRoot(vb);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
- 滚动条(ScrollBar)
public class TestScrollBar extends Application {
final ScrollBar scrollBar = new ScrollBar();
final Image[] images = new Image[5];
final ImageView[] pics = new ImageView[5];
final VBox vb = new VBox();
DropShadow shadow = new DropShadow();
@Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root, 180, 180);
scene.setFill(Color.BLACK);
stage.setScene(scene);
stage.setTitle("Scrollbar");
root.getChildren().addAll(vb, scrollBar);
shadow.setColor(Color.GREY);
shadow.setOffsetX(2);
shadow.setOffsetY(2);
vb.setLayoutX(5);
vb.setSpacing(10);
scrollBar.setLayoutX(scene.getWidth() - scrollBar.getWidth());
scrollBar.setMin(0);
scrollBar.setOrientation(Orientation.VERTICAL);
scrollBar.setPrefHeight(180);
scrollBar.setMax(360);
for (int i = 0; i < 5; i++) {
images[i] = new Image(Objects.requireNonNull(getClass().getClassLoader().getResourceAsStream("fw" + (i + 1) + ".jpg")));
final ImageView pic = pics[i] = new ImageView(images[i]);
pic.setEffect(shadow);
vb.getChildren().add(pics[i]);
}
scrollBar.valueProperty().addListener(
//滚动时触发
(ObservableValue<? extends Number> observableValue, Number old_val, Number new_val) -> {
vb.setLayoutY(-new_val.doubleValue());
});
stage.setResizable(false);//不可修改窗口大小
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
- 滚动面板(ScrollPane)
public class TestScrollPane extends Application {
final ScrollPane scrollPane = new ScrollPane();
final Image[] images = new Image[5];
final ImageView[] pics = new ImageView[5];
final VBox vb = new VBox();
final Label fileName = new Label();
final String[] imageNames = new String[]{"fw1.jpg", "fw2.jpg", "fw3.jpg", "fw4.jpg", "fw5.jpg"};
@Override
public void start(Stage stage) {
VBox box = new VBox();
Scene scene = new Scene(box, 180, 180);
stage.setScene(scene);
stage.setTitle("ScrollPaneSample");
box.getChildren().addAll(scrollPane, fileName);
VBox.setVgrow(scrollPane, Priority.ALWAYS);
fileName.setLayoutX(30);
fileName.setLayoutY(160);
Image roses = new Image(getClass().getResourceAsStream("/roses.jpg"));
scrollPane.setContent(new ImageView(roses));
scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);//禁止横向滚动
scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);//允许纵向滚动
for (int i = 0; i < 5; i++) {
images[i] = new Image(getClass().getResourceAsStream("/" + imageNames[i]));
pics[i] = new ImageView(images[i]);
pics[i].setFitWidth(100);
pics[i].setPreserveRatio(true);
vb.getChildren().add(pics[i]);
}
scrollPane.setVmax(440);
scrollPane.setPrefSize(115, 150);
scrollPane.setContent(vb);
scrollPane.vvalueProperty().addListener((ObservableValue<? extends Number> ov,
Number old_val, Number new_val) -> {
fileName.setText(imageNames[(new_val.intValue() - 1) / 100]);
});
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
- 列表视图(ListView)
public class TestListView extends Application {
ListView<String> listView = new ListView<>();
ObservableList<String> data = FXCollections.observableArrayList(
"chocolate", "salmon", "gold", "coral", "darkorchid",
"darkgoldenrod", "lightsalmon", "black", "rosybrown", "blue",
"blueviolet", "brown");
final Label label = new Label();
@Override
public void start(Stage stage) {
VBox box = new VBox();
Scene scene = new Scene(box, 200, 200);
stage.setScene(scene);
stage.setTitle("ListViewSample");
box.getChildren().addAll(listView, label);
VBox.setVgrow(listView, Priority.ALWAYS);
label.setLayoutX(10);
label.setLayoutY(115);
label.setFont(Font.font("Verdana", 20));
listView.setItems(data);
//自定义列表单元的实现类
listView.setCellFactory(stringListView -> new ColorRectCell());
listView.getSelectionModel().selectedItemProperty().addListener(//选项改变时触发
(ObservableValue<? extends String> observableValue, String old_val, String new_val) -> {
label.setText(new_val);
label.setTextFill(Color.web(new_val));
});
stage.show();
}
static class ColorRectCell extends ListCell<String> {
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
Rectangle rect = new Rectangle(100, 20);
if (item != null) {
rect.setFill(Color.web(item));
//Cell Factory产生ListCell对象。每个Cell与一个单独的数据项(Data Item)关联,
// 并且会展示List View中的一行。通过setGraphic方法展现的Cell内容可以是其它的控件,文本、形状或图片。
// 在本例中,List Cell展现了矩形。
setGraphic(rect);
} else {
setGraphic(null);
}
}
}
public static void main(String[] args) {
launch(args);
}
}
- 表格视图(TableView)
public class TestTableView extends Application {
private final TableView<Person> table = new TableView<>();
private final ObservableList<Person> data =
FXCollections.observableArrayList(
new Person("Jacob", "Smith", "jacob.smith@example.com"),
new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
new Person("Ethan", "Williams", "ethan.williams@example.com"),
new Person("Emma", "Jones", "emma.jones@example.com"),
new Person("Michael", "Brown", "michael.brown@example.com"));
final HBox hb = new HBox();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws IOException {
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
stage.setWidth(450);
stage.setHeight(550);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
table.setEditable(true);
TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));
firstNameCol.setCellFactory(TextFieldTableCell.<Person>forTableColumn());
firstNameCol.setOnEditCommit(//编辑提交后会触发,修改内容后按回车键可提交
(CellEditEvent<Person, String> t) -> {
((Person) t.getTableView().getItems().get(t.getTablePosition().getRow())).setFirstName(t.getNewValue());
});
TableColumn<Person, String> lastNameCol =
new TableColumn<>("Last Name");
lastNameCol.setMinWidth(100);
lastNameCol.setCellValueFactory(
new PropertyValueFactory<>("lastName"));
lastNameCol.setCellFactory(TextFieldTableCell.<Person>forTableColumn());
lastNameCol.setOnEditCommit(
(CellEditEvent<Person, String> t) -> {
((Person) t.getTableView().getItems().get(
t.getTablePosition().getRow())
).setLastName(t.getNewValue());
});
TableColumn<Person, String> emailCol = new TableColumn<>("Email");
emailCol.setMinWidth(200);
emailCol.setCellValueFactory(
new PropertyValueFactory<>("email"));
emailCol.setCellFactory(TextFieldTableCell.<Person>forTableColumn());
emailCol.setOnEditCommit(
(CellEditEvent<Person, String> t) -> {
((Person) t.getTableView().getItems().get(
t.getTablePosition().getRow())
).setEmail(t.getNewValue());
});
table.setItems(data);
//把firstName和lastName字段合并为一个字段
TableColumn<Person, String> nameCol = new TableColumn<>("Name");
nameCol.getColumns().addAll(firstNameCol, lastNameCol);
table.getColumns().addAll(nameCol, emailCol);
final TextField addFirstName = new TextField();
addFirstName.setPromptText("First Name");
addFirstName.setMaxWidth(firstNameCol.getPrefWidth());
final TextField addLastName = new TextField();
addLastName.setMaxWidth(lastNameCol.getPrefWidth());
addLastName.setPromptText("Last Name");
final TextField addEmail = new TextField();
addEmail.setMaxWidth(emailCol.getPrefWidth());
addEmail.setPromptText("Email");
final Button addButton = new Button("Add");
addButton.setOnAction((ActionEvent e) -> {//点击按钮触发
data.add(new Person(addFirstName.getText(), addLastName.getText(), addEmail.getText()));
addFirstName.clear();
addLastName.clear();
addEmail.clear();
});
hb.getChildren().addAll(addFirstName, addLastName, addEmail, addButton);
hb.setSpacing(3);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(label, table, hb);
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private final SimpleStringProperty email;
private Person(String fName, String lName, String email) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String fName) {
lastName.set(fName);
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
}
}
- 组合框(ComboBox)
public class TestComboBox extends Application {
public static void main(String[] args) {
launch(args);
}
final Button button = new Button("Send");
final Label notification = new Label();
final TextField subject = new TextField("");
final TextArea text = new TextArea("");
String address = " ";
@Override
public void start(Stage stage) {
stage.setTitle("ComboBoxSample");
Scene scene = new Scene(new Group(), 500, 270);
final ComboBox emailComboBox = new ComboBox();
emailComboBox.getItems().addAll(
"jacob.smith@example.com",
"isabella.johnson@example.com",
"ethan.williams@example.com",
"emma.jones@example.com",
"michael.brown@example.com"
);
emailComboBox.setPromptText("Email address");
emailComboBox.setEditable(true);
emailComboBox.setOnAction((Event ev) -> {
address = emailComboBox.getSelectionModel().getSelectedItem().toString();
});
final ComboBox priorityComboBox = new ComboBox();
priorityComboBox.getItems().addAll(
"Highest",
"High",
"Normal",
"Low",
"Lowest"
);
priorityComboBox.setValue("Normal");
priorityComboBox.setCellFactory(
new Callback<ListView<String>, ListCell<String>>() {
@Override
public ListCell<String> call(ListView<String> param) {
final ListCell<String> cell = new ListCell<String>() {
{
super.setPrefWidth(100);
}
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (item != null) {
setText(item);
if (item.contains("High")) {
setTextFill(Color.RED);
} else if (item.contains("Low")) {
setTextFill(Color.GREEN);
} else {
setTextFill(Color.BLACK);
}
} else {
setText(null);
}
}
};
return cell;
}
});
button.setOnAction((ActionEvent e) -> {
if (emailComboBox.getValue() != null && !emailComboBox.getValue().toString().isEmpty()) {
notification.setText("Your message was successfully sent" + " to " + address);
emailComboBox.setValue("");
if (priorityComboBox.getValue() != null && !priorityComboBox.getValue().toString().isEmpty()) {
priorityComboBox.setValue(null);
}
subject.clear();
text.clear();
} else {
notification.setText("You have not selected a recipient!");
}
});
GridPane grid = new GridPane();
grid.setVgap(4);
grid.setHgap(10);
grid.setPadding(new Insets(5, 5, 5, 5));
grid.add(new Label("To: "), 0, 0);
grid.add(emailComboBox, 1, 0);
grid.add(new Label("Priority: "), 2, 0);
grid.add(priorityComboBox, 3, 0);
grid.add(new Label("Subject: "), 0, 1);
grid.add(subject, 1, 1, 3, 1);
grid.add(text, 0, 2, 4, 1);
grid.add(button, 0, 3);
grid.add(notification, 1, 3, 3, 1);
Group root = (Group) scene.getRoot();
root.getChildren().add(grid);
stage.setScene(scene);
stage.show();
}
}
- 分隔符(Separator)
public class TestSeparator extends Application {
Label caption = new Label("Weather Forecast");
Label friday = new Label("Friday");
Label saturday = new Label("Saturday");
Label sunday = new Label("Sunday");
@Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root, 350, 150);
stage.setScene(scene);
stage.setTitle("Separator Sample");
GridPane grid = new GridPane();
grid.setPadding(new Insets(10, 10, 10, 10));
grid.setVgap(2);
grid.setHgap(5);
scene.setRoot(grid);
scene.getStylesheets().add("Separator.css");
Image cloudImage = new Image(getClass().getResourceAsStream("/cloud.jpg"));
Image sunImage = new Image(getClass().getResourceAsStream("/sun.jpg"));
caption.setFont(Font.font("Verdana", 20));
GridPane.setConstraints(caption, 0, 0);
GridPane.setColumnSpan(caption, 8);
grid.getChildren().add(caption);
final Separator sepHor = new Separator();
sepHor.setValignment(VPos.CENTER);//纵向对齐方式
GridPane.setConstraints(sepHor, 0, 1);
GridPane.setColumnSpan(sepHor, 7);
grid.getChildren().add(sepHor);
friday.setFont(Font.font("Verdana", 18));
GridPane.setConstraints(friday, 0, 2);
GridPane.setColumnSpan(friday, 2);
grid.getChildren().add(friday);
final Separator sepVert1 = new Separator();
sepVert1.setOrientation(Orientation.VERTICAL);
sepVert1.setValignment(VPos.CENTER);
sepVert1.setPrefHeight(80);
GridPane.setConstraints(sepVert1, 2, 2);
GridPane.setRowSpan(sepVert1, 2);
grid.getChildren().add(sepVert1);
saturday.setFont(Font.font("Verdana", 18));
GridPane.setConstraints(saturday, 3, 2);
GridPane.setColumnSpan(saturday, 2);
grid.getChildren().add(saturday);
final Separator sepVert2 = new Separator();
sepVert2.setOrientation(Orientation.VERTICAL);
sepVert2.setValignment(VPos.CENTER);
sepVert2.setPrefHeight(80);
GridPane.setConstraints(sepVert2, 5, 2);
GridPane.setRowSpan(sepVert2, 2);
grid.getChildren().add(sepVert2);
sunday.setFont(Font.font("Verdana", 18));
GridPane.setConstraints(sunday, 6, 2);
GridPane.setColumnSpan(sunday, 2);
grid.getChildren().add(sunday);
final ImageView cloud = new ImageView(cloudImage);
GridPane.setConstraints(cloud, 0, 3);
grid.getChildren().add(cloud);
final Label t1 = new Label("16");
t1.setFont(Font.font("Verdana", 20));
GridPane.setConstraints(t1, 1, 3);
grid.getChildren().add(t1);
final ImageView sun1 = new ImageView(sunImage);
GridPane.setConstraints(sun1, 3, 3);
grid.getChildren().add(sun1);
final Label t2 = new Label("18");
t2.setFont(Font.font("Verdana", 20));
GridPane.setConstraints(t2, 4, 3);
grid.getChildren().add(t2);
final ImageView sun2 = new ImageView(sunImage);
GridPane.setConstraints(sun2, 6, 3);
grid.getChildren().add(sun2);
final Label t3 = new Label("20");
t3.setFont(Font.font("Verdana", 20));
GridPane.setConstraints(t3, 7, 3);
grid.getChildren().add(t3);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
- 超链接(Hyperlink)
显示效果和web的a标签类似,在点击之后的和未点击时都有不同的显示效果,用法和按钮类似。
public class TestHyperlink extends Application {
final static String[] imageFiles = new String[]{
"product.png",
"education.png",
"partners.png",
"support.png"
};
final static String[] captions = new String[]{
"Products",
"Education",
"Partners",
"Support"
};
final ImageView selectedImage = new ImageView();
final Hyperlink[] hpls = new Hyperlink[captions.length];
final Image[] images = new Image[imageFiles.length];
public static void main(String[] args) {
launch(TestHyperlink.class, args);
}
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Hyperlink Sample");
stage.setWidth(300);
stage.setHeight(200);
selectedImage.setLayoutX(100);
selectedImage.setLayoutY(10);
for (int i = 0; i < captions.length; i++) {
final Hyperlink hpl = hpls[i] = new Hyperlink(captions[i]);
final Image image = images[i] = new Image(Objects.requireNonNull(getClass().getClassLoader().getResourceAsStream(imageFiles[i])));
hpl.setOnAction((ActionEvent e) -> {//链接点击之后触发
selectedImage.setImage(image);
});
}
final Button button = new Button("Refresh links");
button.setOnAction((ActionEvent e) -> {
for (int i = 0; i < captions.length; i++) {
hpls[i].setVisited(false);
selectedImage.setImage(null);
}
});
VBox vbox = new VBox();
vbox.getChildren().addAll(hpls);
vbox.getChildren().add(button);
vbox.setSpacing(5);
((Group) scene.getRoot()).getChildren().addAll(vbox, selectedImage);
stage.setScene(scene);
stage.show();
}
}
- 提示信息(Tooltip)
鼠标移动到加了提示信息的组件上会有提示。
public class TestTooltip extends Application {
final static String[] rooms = new String[]{
"Accommodation (BB)",
"Half Board",
"Late Check-out",
"Extra Bed"
};
final static Integer[] rates = new Integer[]{
100, 20, 10, 30
};
final CheckBox[] cbs = new CheckBox[rooms.length];
final Label total = new Label("Total: $0");
Integer sum = 0;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Tooltip Sample");
stage.setWidth(330);
stage.setHeight(150);
total.setFont(new Font("Arial", 20));
for (int i = 0; i < rooms.length; i++) {
final CheckBox cb = cbs[i] = new CheckBox(rooms[i]);
final Integer rate = rates[i];
final Tooltip tooltip = new Tooltip("$" + rates[i].toString());
tooltip.setFont(new Font("Arial", 16));
cb.setTooltip(tooltip);
cb.selectedProperty().addListener(
(ObservableValue<? extends Boolean> ov, Boolean old_val, Boolean new_val) -> {
if (cb.isSelected()) {
sum = sum + rate;
} else {
sum = sum - rate;
}
total.setText("Total: $" + sum.toString());
}
);
}
VBox vbox = new VBox();
vbox.getChildren().addAll(cbs);
vbox.setSpacing(5);
HBox root = new HBox();
root.getChildren().add(vbox);
root.getChildren().add(total);
root.setSpacing(40);
root.setPadding(new Insets(20, 10, 10, 20));
((Group) scene.getRoot()).getChildren().add(root);
stage.setScene(scene);
stage.show();
}
}
- 带有标题的面板(TitledPane)和可折叠面板(Accordion)
TitledPane创建的面板是可以折叠和打开的,把多个TitledPane放在同一个Accordion中时,最多只能展开其中一个,展开其中一个会关闭其余展开的。
public class TestTitledPane extends Application {
final String[] imageNames = new String[]{"Apples", "Flowers", "Leaves"};
final Image[] images = new Image[imageNames.length];
final ImageView[] pics = new ImageView[imageNames.length];
final TitledPane[] tps = new TitledPane[imageNames.length];
final Label label = new Label("N/A");
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
stage.setTitle("TitledPane");
Scene scene = new Scene(new Group(), 450, 250);
TitledPane gridTitlePane = new TitledPane();
GridPane grid = new GridPane();
grid.setVgap(4);
grid.setPadding(new Insets(5, 5, 5, 5));
grid.add(new Label("First Name: "), 0, 0);
grid.add(new TextField(), 1, 0);
grid.add(new Label("Last Name: "), 0, 1);
grid.add(new TextField(), 1, 1);
grid.add(new Label("Email: "), 0, 2);
grid.add(new TextField(), 1, 2);
grid.add(new Label("Attachment: "), 0, 3);
grid.add(label, 1, 3);
gridTitlePane.setText("Grid");
gridTitlePane.setContent(grid);
final Accordion accordion = new Accordion();
for (int i = 0; i < imageNames.length; i++) {
images[i] = new Image(getClass().getResourceAsStream("/" + imageNames[i] + ".jpg"));
pics[i] = new ImageView(images[i]);
tps[i] = new TitledPane(imageNames[i], pics[i]);
}
accordion.getPanes().addAll(tps);
//折叠面板,折叠和展开时触发
accordion.expandedPaneProperty().addListener(
(ObservableValue<? extends TitledPane> ov, TitledPane old_val, TitledPane new_val) -> {
if (new_val != null) {
label.setText(accordion.getExpandedPane().getText()
+ ".jpg");
}
});
HBox hbox = new HBox(10);
hbox.setPadding(new Insets(20, 0, 0, 20));
hbox.getChildren().setAll(gridTitlePane, accordion);
Group root = (Group) scene.getRoot();
root.getChildren().add(hbox);
stage.setScene(scene);
stage.show();
}
}
- 菜单(Menu)
public class TestMenu extends Application {
final PageData[] pages = new PageData[]{
new PageData("Apple",
"The apple is the pomaceous fruit of the apple tree, species Malus "
+ "domestica in the rose family (Rosaceae). It is one of the most "
+ "widely cultivated tree fruits, and the most widely known of "
+ "the many members of genus Malus that are used by humans. "
+ "The tree originated in Western Asia, where its wild ancestor, "
+ "the Alma, is still found today.",
"Malus domestica"),
new PageData("Hawthorn",
"The hawthorn is a large genus of shrubs and trees in the rose family,"
+ "Rosaceae, native to temperate regions of the Northern Hemisphere "
+ "in Europe, Asia and North America. The name hawthorn was "
+ "originally applied to the species native to northern Europe, "
+ "especially the Common Hawthorn C. monogyna, and the unmodified "
+ "name is often so used in Britain and Ireland.",
"Crataegus monogyna"),
new PageData("Ivy",
"The ivy is a flowering plant in the grape family (Vitaceae) native to "
+ " eastern Asia in Japan, Korea, and northern and eastern China. "
+ "It is a deciduous woody vine growing to 30 m tall or more given "
+ "suitable support, attaching itself by means of numerous small "
+ "branched tendrils tipped with sticky disks.",
"Parthenocissus tricuspidata"),
new PageData("Quince",
"The quince is the sole member of the genus Cydonia and is native to "
+ "warm-temperate southwest Asia in the Caucasus region. The "
+ "immature fruit is green with dense grey-white pubescence, most "
+ "of which rubs off before maturity in late autumn when the fruit "
+ "changes color to yellow with hard, strongly perfumed flesh.",
"Cydonia oblonga")
};
final String[] viewOptions = new String[]{
"Title",
"Binomial name",
"Picture",
"Description"
};
final Entry<String, Effect>[] effects = new Entry[]{
new SimpleEntry<>("Sepia Tone", new SepiaTone()),
new SimpleEntry<>("Glow", new Glow()),
new SimpleEntry<>("Shadow", new DropShadow())
};
final ImageView pic = new ImageView();
final Label name = new Label();
final Label binName = new Label();
final Label description = new Label();
private int currentIndex = -1;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
stage.setTitle("Menu Sample");
Scene scene = new Scene(new VBox(), 400, 350);
scene.setFill(Color.OLDLACE);
name.setFont(new Font("Verdana Bold", 22));
binName.setFont(new Font("Arial Italic", 10));
pic.setFitHeight(150);
pic.setPreserveRatio(true);
description.setWrapText(true);
description.setTextAlignment(TextAlignment.JUSTIFY);
shuffle();
MenuBar menuBar = new MenuBar();
// --- Graphical elements
final VBox vbox = new VBox();
vbox.setAlignment(Pos.CENTER);
vbox.setSpacing(10);
vbox.setPadding(new Insets(0, 10, 0, 10));
vbox.getChildren().addAll(name, binName, pic, description);
// --- Menu File
Menu menuFile = new Menu("File");
MenuItem add = new MenuItem("Shuffle", new ImageView(new Image("/new.png")));
add.setOnAction((ActionEvent t) -> {
shuffle();
vbox.setVisible(true);
});
MenuItem clear = new MenuItem("Clear");
clear.setAccelerator(KeyCombination.keyCombination("Ctrl+X"));
clear.setOnAction((ActionEvent t) -> {
vbox.setVisible(false);
});
MenuItem exit = new MenuItem("Exit");
exit.setOnAction((ActionEvent t) -> {
System.exit(0);
});
menuFile.getItems().addAll(add, clear, new SeparatorMenuItem(), exit);
// --- Menu Edit
Menu menuEdit = new Menu("Edit");
Menu menuEffect = new Menu("Picture Effect");
final ToggleGroup groupEffect = new ToggleGroup();
for (Entry<String, Effect> effect : effects) {
RadioMenuItem itemEffect = new RadioMenuItem(effect.getKey());
itemEffect.setUserData(effect.getValue());
itemEffect.setToggleGroup(groupEffect);
menuEffect.getItems().add(itemEffect);
}
final MenuItem noEffects = new MenuItem("No Effects");
noEffects.setDisable(true);
noEffects.setOnAction((ActionEvent t) -> {
pic.setEffect(null);
groupEffect.getSelectedToggle().setSelected(false);
noEffects.setDisable(true);
});
groupEffect.selectedToggleProperty().addListener(
(ObservableValue<? extends Toggle> ov, Toggle old_toggle,
Toggle new_toggle) -> {
if (groupEffect.getSelectedToggle() != null) {
Effect effect =
(Effect) groupEffect.getSelectedToggle().getUserData();
pic.setEffect(effect);
noEffects.setDisable(false);
} else {
noEffects.setDisable(true);
}
});
menuEdit.getItems().addAll(menuEffect, noEffects);
// --- Menu View
Menu menuView = new Menu("View");
CheckMenuItem titleView = createMenuItem("Title", name);
CheckMenuItem binNameView = createMenuItem("Binomial name", binName);
CheckMenuItem picView = createMenuItem("Picture", pic);
CheckMenuItem descriptionView = createMenuItem(
"Decsription", description);
menuView.getItems().addAll(titleView, binNameView, picView,
descriptionView);
menuBar.getMenus().addAll(menuFile, menuEdit, menuView);
// --- Context Menu
final ContextMenu cm = new ContextMenu();
MenuItem cmItem1 = new MenuItem("Copy Image");
cmItem1.setOnAction((ActionEvent e) -> {
Clipboard clipboard = Clipboard.getSystemClipboard();
ClipboardContent content = new ClipboardContent();
content.putImage(pic.getImage());
clipboard.setContent(content);
});
cm.getItems().add(cmItem1);
pic.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent e) -> {
if (e.getButton() == MouseButton.SECONDARY)
cm.show(pic, e.getScreenX(), e.getScreenY());
});
((VBox) scene.getRoot()).getChildren().addAll(menuBar, vbox);
stage.setScene(scene);
stage.show();
}
private void shuffle() {
int i = currentIndex;
while (i == currentIndex) {
i = (int) (Math.random() * pages.length);
}
pic.setImage(pages[i].image);
name.setText(pages[i].name);
binName.setText("(" + pages[i].binNames + ")");
description.setText(pages[i].description);
currentIndex = i;
}
private static CheckMenuItem createMenuItem(String title, final Node node) {
CheckMenuItem cmi = new CheckMenuItem(title);
cmi.setSelected(true);
cmi.selectedProperty().addListener(
(ObservableValue<? extends Boolean> ov, Boolean old_val,
Boolean new_val) -> {
node.setVisible(new_val);
});
return cmi;
}
private class PageData {
public String name;
public String description;
public String binNames;
public Image image;
public PageData(String name, String description, String binNames) {
this.name = name;
this.description = description;
this.binNames = binNames;
image = new Image(Objects.requireNonNull(getClass().getClassLoader().getResourceAsStream(name + ".jpg")));
}
}
}
暂时学习上面的组件即可,下面的UI组件用到再学习,我最后会再另开文章更新:
- 树视图(TreeView)
- 树表视图(TreeTableView)
- 滑块(Slider)
- 进度条和进度指示器(ProgressBarandProgressIndicator)
- HTML编辑器(HTMLEditor)
- 颜色选择器(ColorPicker)
- 日期选择器(DatePicker)
- 分页控件(PaginationControl)
- 文件选择框(FileChooser)
- 自定义UI控件(CustomizationofUIControls)
- 嵌入式平台的UI控件(UIControlsontheEmbeddedPlatforms)
Q.E.D.