在本章中,我们将继续介绍基本的 JavaFX 控件。 我们提出了DatePicker,MenuBar,ColorPicker,RadioButton和TabPane控件。
日期选择器
DatePicker是用于选择日期的控件。
DatePickerEx.java
package com.zetcode;import java.time.LocalDate;import javafx.application.Application;import javafx.geometry.Insets;import javafx.scene.Scene;import javafx.scene.control.DatePicker;import javafx.scene.control.Label;import javafx.scene.layout.VBox;import javafx.stage.Stage;/*** ZetCode JavaFX tutorial** This program shows a date chosen from* a DatePicker in a label.** Author: Jan Bodnar* Website: zetcode.com* Last modified: June 2015*/public class DatePickerEx extends Application {@Overridepublic void start(Stage stage) {initUI(stage);}private void initUI(Stage stage) {VBox root = new VBox(15);root.setPadding(new Insets(10));Label lbl = new Label("...");DatePicker datePicker = new DatePicker();datePicker.setOnAction(e -> {LocalDate date = datePicker.getValue();lbl.setText(date.toString());});root.getChildren().addAll(datePicker, lbl);Scene scene = new Scene(root, 350, 200);stage.setTitle("Date picker");stage.setScene(scene);stage.show();}public static void main(String[] args) {launch(args);}}
该示例使用DatePicker控件选择和显示日期。 日期显示在标签控件中。
DatePicker datePicker = new DatePicker();
创建一个DatePicker控件的实例。
datePicker.setOnAction(e -> {LocalDate date = datePicker.getValue();lbl.setText(date.toString());});
getValue()方法将选择的日期作为LocalDate返回。 所选日期通过setText()方法设置到标签控件。

图:DatePicker
菜单栏
MenuBar由Menu对象组成,这些对象包含MenuItem对象,即应用的命令。 传统上,它位于应用窗口的顶部。
MenuBarEx.java
package com.zetcode;import javafx.application.Application;import javafx.application.Platform;import javafx.event.ActionEvent;import javafx.event.EventHandler;import javafx.scene.Scene;import javafx.scene.control.Alert;import javafx.scene.control.Alert.AlertType;import javafx.scene.control.Menu;import javafx.scene.control.MenuBar;import javafx.scene.control.MenuItem;import javafx.scene.control.SeparatorMenuItem;import javafx.scene.layout.HBox;import javafx.stage.Stage;/*** ZetCode JavaFX tutorial** This program creates a MenuBar with one* menu and four menu items.** Author: Jan Bodnar* Website: zetcode.com* Last modified: June 2015*/public class MenuBarEx extends Application {@Overridepublic void start(Stage stage) {initUI(stage);}private void initUI(Stage stage) {HBox root = new HBox();MenuBar mbar = new MenuBar();mbar.prefWidthProperty().bind(stage.widthProperty());MyMenuHandler handler = new MyMenuHandler();Menu fileMenu = new Menu("File");mbar.getMenus().add(fileMenu);MenuItem nmi = new MenuItem("New");nmi.setOnAction(handler);fileMenu.getItems().add(nmi);MenuItem omi = new MenuItem("Open");omi.setOnAction(handler);fileMenu.getItems().add(omi);MenuItem smi = new MenuItem("Save");smi.setOnAction(handler);fileMenu.getItems().add(smi);fileMenu.getItems().add(new SeparatorMenuItem());MenuItem emi = new MenuItem("Exit");emi.setOnAction((ActionEvent event) -> {Platform.exit();});fileMenu.getItems().add(emi);root.getChildren().add(mbar);Scene scene = new Scene(root, 300, 250);stage.setTitle("MenuBar");stage.setScene(scene);stage.show();}private class MyMenuHandler implements EventHandler<ActionEvent> {@Overridepublic void handle(ActionEvent event) {doShowMessageDialog(event);}private void doShowMessageDialog(ActionEvent event) {MenuItem mi = (MenuItem) event.getSource();String item = mi.getText();Alert alert = new Alert(AlertType.INFORMATION);alert.setTitle("Information dialog");alert.setHeaderText("Menu item selection information");alert.setContentText(item + " menu item selected");alert.showAndWait();}}public static void main(String[] args) {launch(args);}}
该示例在菜单栏中包含一个菜单。 菜单包含四个菜单项和一个分隔符。
MenuBar mbar = new MenuBar();mbar.prefWidthProperty().bind(stage.widthProperty());
MenuBar控件已创建。 在水平框内,它足够大以显示其单个菜单。 通过将其绑定到舞台的widthProperty,菜单栏从左向右拉伸。
MyMenuHandler handler = new MyMenuHandler();
将创建一个菜单处理器。 它由三个菜单项共享。
Menu fileMenu = new Menu("File");mbar.getMenus().add(fileMenu);
文件Menu已创建并添加到菜单栏。
MenuItem nmi = new MenuItem("New");nmi.setOnAction(handler);fileMenu.getItems().add(nmi);
新建MenuItem已创建并添加到“文件”菜单中。 菜单项的处理器是通过setOnAction()方法设置的。
fileMenu.getItems().add(new SeparatorMenuItem());
SeparatorMenuItem是水平分隔符,用于在视觉上分隔相关菜单项。
emi.setOnAction((ActionEvent event) -> {Platform.exit();});
退出菜单项通过Platform.exit()方法调用终止应用。
private class MyMenuHandler implements EventHandler<ActionEvent> {@Overridepublic void handle(ActionEvent event) {doShowMessageDialog(event);}...}
选择带有此处理器的菜单项时,将调用EventHandler的handle()方法。 该方法调用doShowMessageDialog()方法,该方法显示一个消息对话框。
private void doShowMessageDialog(ActionEvent event) {MenuItem mi = (MenuItem) event.getSource();String item = mi.getText();Alert alert = new Alert(AlertType.INFORMATION);alert.setTitle("Information dialog");alert.setHeaderText("Menu item selection information");alert.setContentText(item + " menu item selected");alert.showAndWait();}
doShowMessageDialog()方法使用Alert控件创建一个信息对话框。 从事件源,我们确定菜单项的名称,该菜单项用于创建内容文本。

图:MenuBar
颜色选择器
ColorPicker是用于选择颜色值的内置对话框。 它允许用户从标准调色板中选择一种颜色或定义一种自定义颜色。
ColorPickerEx.java
package com.zetcode;import javafx.application.Application;import javafx.event.ActionEvent;import javafx.geometry.Insets;import javafx.geometry.Pos;import javafx.scene.Scene;import javafx.scene.control.ColorPicker;import javafx.scene.layout.HBox;import javafx.scene.text.Font;import javafx.scene.text.Text;import javafx.stage.Stage;/*** ZetCode JavaFX tutorial** This program uses the ColorPicker* dialog to choose a colour value.** Author: Jan Bodnar* Website: zetcode.com* Last modified: June 2015*/public class ColorPickerEx extends Application {@Overridepublic void start(Stage stage) {initUI(stage);}private void initUI(Stage stage) {HBox root = new HBox(25);root.setAlignment(Pos.BASELINE_CENTER);root.setPadding(new Insets(10));Text txt = new Text("ZetCode");Font font = Font.font(20);txt.setFont(font);ColorPicker cp = new ColorPicker();cp.setOnAction((ActionEvent event) -> {txt.setFill(cp.getValue());});root.getChildren().addAll(cp, txt);Scene scene = new Scene(root, 300, 250);stage.setTitle("ColorPicker");stage.setScene(scene);stage.show();}public static void main(String[] args) {launch(args);}}
在示例中,我们有一个ColorPicker和一个Text控件。 从颜色选择器中选择的颜色用于设置文本控件的前景色。
Text txt = new Text("ZetCode");Font font = Font.font(20);txt.setFont(font);
创建一个Text控件。 我们扩大其字体以获得更好的可见性。
ColorPicker cp = new ColorPicker();cp.setOnAction((ActionEvent event) -> {txt.setFill(cp.getValue());});
创建ColorPicker并设置事件处理器。 使用ColorPicker的getValue()方法检索当前选择的颜色。 使用setFill()方法可以更改文本控件的前景色。

图:ColorPicker
RadioButton
RadioButton通常用于创建互斥的项目系列。 当放置在ToggleGroup中时,只能选择一个RadioButton。 选择RadioButton时,将发送ActionEvent。
RadioButtonEx.java
package com.zetcode;import javafx.application.Application;import javafx.beans.value.ChangeListener;import javafx.beans.value.ObservableValue;import javafx.geometry.Insets;import javafx.scene.Scene;import javafx.scene.control.Label;import javafx.scene.control.RadioButton;import javafx.scene.control.Toggle;import javafx.scene.control.ToggleGroup;import javafx.scene.layout.AnchorPane;import javafx.scene.layout.VBox;import javafx.stage.Stage;/*** ZetCode JavaFX tutorial** This program presents the RadioButton* control.** Author: Jan Bodnar* Website: zetcode.com* Last modified: June 2015*/public class RadioButtonEx extends Application {private final double BORDER = 10d;private Label lbl2;@Overridepublic void start(Stage stage) {initUI(stage);}private void initUI(Stage stage) {AnchorPane root = new AnchorPane();VBox vbox = new VBox(10);vbox.setPadding(new Insets(10));Label lbl1 = new Label("Difficulty");lbl2 = new Label("");lbl2.setStyle("-fx-background-color:wheat; -fx-padding: 0 0 0 5");lbl2.prefWidthProperty().bind(stage.widthProperty().subtract(2*BORDER));ToggleGroup tg = new ToggleGroup();tg.selectedToggleProperty().addListener(new MyToggleListener());RadioButton rb1 = new RadioButton("Easy");rb1.setToggleGroup(tg);rb1.setSelected(true);RadioButton rb2 = new RadioButton("Medium");rb2.setToggleGroup(tg);RadioButton rb3 = new RadioButton("Hard");rb3.setToggleGroup(tg);vbox.getChildren().addAll(lbl1, rb1, rb2, rb3);root.getChildren().addAll(vbox, lbl2);AnchorPane.setTopAnchor(vbox, BORDER);AnchorPane.setBottomAnchor(lbl2, BORDER);AnchorPane.setLeftAnchor(lbl2, BORDER);Scene scene = new Scene(root, 300, 250);stage.setTitle("RadioButton");stage.setScene(scene);stage.show();}private class MyToggleListener implements ChangeListener<Toggle> {@Overridepublic void changed(ObservableValue<? extends Toggle> observable,Toggle oldValue, Toggle newValue) {RadioButton rb = (RadioButton) newValue;String txt = rb.getText();lbl2.setText(txt);}}public static void main(String[] args) {launch(args);}}
该示例具有三个单选按钮。 通过将它们放在切换组中,一次只能选择其中之一。
Label lbl1 = new Label("Difficulty");
此标签提供对单选按钮的描述。
lbl2 = new Label("");lbl2.setStyle("-fx-background-color:wheat; -fx-padding: 0 0 0 5");lbl2.prefWidthProperty().bind(stage.widthProperty().subtract(2*BORDER));
该标签显示当前选中的单选按钮的文本标签。 其样式是使用setStyle()方法定制的。 标签将被放大以达到舞台宽度减去指定边框的宽度。
ToggleGroup tg = new ToggleGroup();tg.selectedToggleProperty().addListener(new MyToggleListener());
创建ToggleGroup并将监听器添加到其selectedToggleProperty。
RadioButton rb1 = new RadioButton("Easy");
创建一个RadioButton控件。
rb1.setToggleGroup(tg);
setToggleGroup()方法将单选按钮设置为切换组。
rb1.setSelected(true);
setSelected()选择单选按钮。
private class MyToggleListener implements ChangeListener<Toggle> {@Overridepublic void changed(ObservableValue<? extends Toggle> observable,Toggle oldValue, Toggle newValue) {RadioButton rb = (RadioButton) newValue;String txt = rb.getText();lbl2.setText(txt);}}
在监听器对象内部,我们使用getText()方法获取单选按钮的文本标签,并使用setText()方法将其设置为标签。

图:RadioButton
TabPane
TabPane是允许在一组Tabs之间切换的控件。 一次只显示一个标签。 TabPane中的选项卡可以位于窗口的四个侧面中的任何一个。 默认面是顶面。
TabPaneEx.java
package com.zetcode;import javafx.application.Application;import javafx.scene.Scene;import javafx.scene.control.Tab;import javafx.scene.control.TabPane;import javafx.scene.layout.StackPane;import javafx.scene.paint.Color;import javafx.scene.shape.Circle;import javafx.scene.shape.Line;import javafx.scene.shape.Rectangle;import javafx.stage.Stage;/*** ZetCode JavaFX tutorial** This program presents the TabPane control.** Author: Jan Bodnar* Website: zetcode.com* Last modified: June 2015*/public class TabPaneEx extends Application {@Overridepublic void start(Stage stage) {initUI(stage);}private void initUI(Stage stage) {StackPane root = new StackPane();TabPane tabPane = new TabPane();Tab tab1 = new Tab();tab1.setText("Rectangle");tab1.setContent(new Rectangle(100, 100, Color.LIGHTSTEELBLUE));Tab tab2 = new Tab();tab2.setText("Line");tab2.setContent(new Line(0, 0, 100, 100));Tab tab3 = new Tab();tab3.setText("Circle");tab3.setContent(new Circle(0, 0, 50));tabPane.getSelectionModel().select(1);tabPane.getTabs().addAll(tab1, tab2, tab3);root.getChildren().add(tabPane);Scene scene = new Scene(root, 300, 250);stage.setTitle("TabPane");stage.setScene(scene);stage.show();}public static void main(String[] args) {launch(args);}}
该示例包含带有三个选项卡的TabPane控件。 每个选项卡均包含几何形状。 应用启动时,将选择第二个选项卡。
TabPane tabPane = new TabPane();
创建一个TabPane控件。
Tab tab1 = new Tab();tab1.setText("Rectangle");tab1.setContent(new Rectangle(100, 100, Color.LIGHTSTEELBLUE));
创建了Tab。 它的文本标签是用setText()方法设置的。 内容通过setContent()方法设置。
tabPane.getSelectionModel().select(1);
TabPane's选择模型处理选项卡的选择。 模型的select()方法选择第二个选项卡。
tabPane.getTabs().addAll(tab1, tab2, tab3);
选项卡将插入选项卡窗格。 使用getTabs()方法检索选项卡的内部列表。

图:TabPane
在本章中,我们将继续介绍基本的 JavaFX 控件。
