原文: http://zetcode.com/gui/javafx/controls/

控件是应用的基本构建块。 Control是场景图中的一个可由用户操纵的节点。 它以对用户一致且可预测的方式支持常见的用户交互。 JavaFX 具有广泛的内置控件。 在本章中,我们涵盖五个控件:LabelCheckBoxChoiceBoxSliderProgressBar。 还简要提到了ImageViewTextField控件。

Label

Label是不可编辑的文本控件。 标签可以使用省略号或截断符来调整字符串的大小以使其适合。

LabelEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import javafx.geometry.Insets;
  4. import javafx.scene.Scene;
  5. import javafx.scene.control.Label;
  6. import javafx.scene.layout.HBox;
  7. import javafx.stage.Stage;
  8. /**
  9. * ZetCode JavaFX tutorial
  10. *
  11. * This program shows lyrics in a Label
  12. * control.
  13. *
  14. * Author: Jan Bodnar
  15. * Website: zetcode.com
  16. * Last modified: June 2015
  17. */
  18. public class LabelEx extends Application {
  19. String lyrics = "It's way too late to think of\n"
  20. + "Someone I would call now\n"
  21. + "And neon signs got tired\n"
  22. + "Red eye flights help the stars out\n"
  23. + "I'm safe in a corner\n"
  24. + "Just hours before me\n"
  25. + "\n"
  26. + "I'm waking with the roaches\n"
  27. + "The world has surrendered\n"
  28. + "I'm dating ancient ghosts\n"
  29. + "The ones I made friends with\n"
  30. + "The comfort of fireflies\n"
  31. + "Long gone before daylight\n"
  32. + "\n"
  33. + "And if I had one wishful field tonight\n"
  34. + "I'd ask for the sun to never rise\n"
  35. + "If God leant his voice for me to speak\n"
  36. + "I'd say go to bed, world\n"
  37. + "\n"
  38. + "I've always been too late\n"
  39. + "To see what's before me\n"
  40. + "And I know nothing sweeter than\n"
  41. + "Champaign from last New Years\n"
  42. + "Sweet music in my ears\n"
  43. + "And a night full of no fears\n"
  44. + "\n"
  45. + "But if I had one wishful field tonight\n"
  46. + "I'd ask for the sun to never rise\n"
  47. + "If God passed a mic to me to speak\n"
  48. + "I'd say stay in bed, world\n"
  49. + "Sleep in peace";
  50. @Override
  51. public void start(Stage stage) {
  52. initUI(stage);
  53. }
  54. private void initUI(Stage stage) {
  55. HBox root = new HBox();
  56. root.setPadding(new Insets(10));
  57. Label lbl = new Label(lyrics);
  58. root.getChildren().add(lbl);
  59. Scene scene = new Scene(root);
  60. stage.setTitle("No sleep");
  61. stage.setScene(scene);
  62. stage.show();
  63. }
  64. public static void main(String[] args) {
  65. launch(args);
  66. }
  67. }

该示例显示了 Cardigans 的歌曲的歌词。

  1. String lyrics = "It's way too late to think of\n"
  2. + "Someone I would call now\n"
  3. + "And neon signs got tired\n"
  4. + "Red eye flights help the stars out\n"
  5. ...

该字符串由多行文本组成。

  1. HBox root = new HBox();
  2. root.setPadding(new Insets(10));

标签控件放置在HBox中。 我们在盒子周围放了一些填充物。

  1. Label lbl = new Label(lyrics);

创建一个Label控件。 它以字符串作为唯一参数。

  1. root.getChildren().add(lbl);

标签已添加到容器中。

labelFor属性

labelFor属性指定在按下助记符时将键盘焦点发送到的节点。

LabelForEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import javafx.geometry.HPos;
  4. import javafx.geometry.Insets;
  5. import javafx.scene.Scene;
  6. import javafx.scene.control.Label;
  7. import javafx.scene.control.TextField;
  8. import javafx.scene.layout.GridPane;
  9. import javafx.stage.Stage;
  10. /**
  11. * ZetCode JavaFX tutorial
  12. *
  13. * This program uses the labelFor property to
  14. * send focus to a specified text field.
  15. *
  16. * Author: Jan Bodnar
  17. * Website: zetcode.com
  18. * Last modified: June 2015
  19. */
  20. public class LabelForEx extends Application {
  21. @Override
  22. public void start(Stage stage) {
  23. initUI(stage);
  24. }
  25. private void initUI(Stage stage) {
  26. GridPane root = new GridPane();
  27. root.setVgap(10);
  28. root.setHgap(5);
  29. root.setPadding(new Insets(10));
  30. Label lbl1 = new Label("_Name:");
  31. Label lbl2 = new Label("_Address:");
  32. Label lbl3 = new Label("_Occupation:");
  33. TextField field1 = new TextField();
  34. TextField field2 = new TextField();
  35. TextField field3 = new TextField();
  36. lbl1.setLabelFor(field1);
  37. lbl1.setMnemonicParsing(true);
  38. lbl2.setLabelFor(field2);
  39. lbl2.setMnemonicParsing(true);
  40. lbl3.setLabelFor(field3);
  41. lbl3.setMnemonicParsing(true);
  42. root.add(lbl1, 0, 0);
  43. root.add(field1, 2, 0);
  44. root.add(lbl2, 0, 1);
  45. root.add(field2, 2, 1);
  46. root.add(lbl3, 0, 2);
  47. root.add(field3, 2, 2);
  48. GridPane.setHalignment(lbl1, HPos.RIGHT);
  49. GridPane.setHalignment(lbl2, HPos.RIGHT);
  50. GridPane.setHalignment(lbl3, HPos.RIGHT);
  51. Scene scene = new Scene(root);
  52. stage.setTitle("TextField");
  53. stage.setScene(scene);
  54. stage.show();
  55. }
  56. public static void main(String[] args) {
  57. launch(args);
  58. }
  59. }

该示例使用labelFor属性和助记符将焦点转移到指定的文本字段。

  1. GridPane root = new GridPane();
  2. root.setVgap(10);
  3. root.setHgap(5);
  4. root.setPadding(new Insets(10));

我们的应用是一个典型的基于表单的程序。 GridPane非常适合此。 我们在控件周围以及控件之间设置了一些空间。

  1. Label lbl1 = new Label("_Name:");
  2. Label lbl2 = new Label("_Address:");
  3. Label lbl3 = new Label("_Occupation:");

创建了三个Labels。 下划线字符位于助记键之前。

  1. TextField field1 = new TextField();
  2. TextField field2 = new TextField();
  3. TextField field3 = new TextField();

TextField是用于编辑单行未格式化文本的控件。 每个文本字段都放置在一个标签控件旁边。

  1. lbl1.setLabelFor(field1);

setLabelFor()设置按下助记符时将焦点转移到的目标节点。

  1. lbl1.setMnemonicParsing(true);

默认情况下,未为标签设置助记符。 我们必须使用setMnemonicParsing()方法启用它们。

基本的 JavaFX 控件 - 图1

图:labelFor属性

在某些平台上,必须按无鼠标修饰符(通常为 Alt )以显示下划线。 在图中,通过按 Alt + A 将焦点转移到中间文本字段。

CheckBox

CheckBox是三态选择控制框,在选中时显示对勾或勾号。 默认情况下,控件具有两种状态:选中和未选中。 setAllowIndeterminate()使能第三种状态:不确定。

CheckBoxEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import javafx.event.ActionEvent;
  4. import javafx.geometry.Insets;
  5. import javafx.scene.Scene;
  6. import javafx.scene.control.CheckBox;
  7. import javafx.scene.layout.HBox;
  8. import javafx.stage.Stage;
  9. /**
  10. * ZetCode JavaFX tutorial
  11. *
  12. * This program presents the
  13. * CheckBox control.
  14. *
  15. * Author: Jan Bodnar
  16. * Website: zetcode.com
  17. * Last modified: June 2015
  18. */
  19. public class CheckBoxEx extends Application {
  20. @Override
  21. public void start(Stage stage) {
  22. initUI(stage);
  23. }
  24. private void initUI(Stage stage) {
  25. HBox root = new HBox();
  26. root.setPadding(new Insets(10, 0, 0, 10));
  27. CheckBox cbox = new CheckBox("Show title");
  28. cbox.setSelected(true);
  29. cbox.setOnAction((ActionEvent event) -> {
  30. if (cbox.isSelected()) {
  31. stage.setTitle("CheckBox");
  32. } else {
  33. stage.setTitle("");
  34. }
  35. });
  36. root.getChildren().add(cbox);
  37. Scene scene = new Scene(root, 300, 200);
  38. stage.setTitle("CheckBox");
  39. stage.setScene(scene);
  40. stage.show();
  41. }
  42. public static void main(String[] args) {
  43. launch(args);
  44. }
  45. }

该示例根据是否选中该复选框来显示或隐藏窗口的标题。

  1. CheckBox cbox = new CheckBox("Show title");

创建一个CheckBox控件。 指定的文本为其标签。

  1. cbox.setSelected(true);

由于默认情况下窗口的标题是可见的,因此我们使用setSelected()方法检查控件。

  1. cbox.setOnAction((ActionEvent event) -> {
  2. if (cbox.isSelected()) {
  3. stage.setTitle("CheckBox");
  4. } else {
  5. stage.setTitle("");
  6. }
  7. });

使用setOnAction()方法,设置复选框的操作,该操作在触发复选框时被调用。 我们用isSelected()方法确定其状态。 根据当前状态,我们使用setTitle()方法显示或隐藏窗口标题。

基本的 JavaFX 控件 - 图2

图:CheckBox

请注意复选框文本周围的蓝色矩形。 它表示此控件具有键盘焦点。 可以使用 Space 键选择和取消选中该复选框。

滑杆

Slider是一种控件,它使用户可以通过在有限间隔内滑动旋钮来以图形方式选择一个值。 滑块可以选择显示刻度线和标签,以指示不同的滑块位置值。

SliderEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import javafx.beans.value.ChangeListener;
  4. import javafx.beans.value.ObservableValue;
  5. import javafx.geometry.Insets;
  6. import javafx.geometry.Pos;
  7. import javafx.scene.Scene;
  8. import javafx.scene.control.Slider;
  9. import javafx.scene.image.Image;
  10. import javafx.scene.image.ImageView;
  11. import javafx.scene.layout.HBox;
  12. import javafx.stage.Stage;
  13. /**
  14. * ZetCode JavaFX tutorial
  15. *
  16. * This program uses a Slider control to
  17. * manipulate the images of an ImageView.
  18. *
  19. * Author: Jan Bodnar
  20. * Website: zetcode.com
  21. * Last modified: June 2015
  22. */
  23. public class SliderEx extends Application {
  24. private ImageView iview;
  25. private Image muteImg;
  26. private Image minImg;
  27. private Image maxImg;
  28. private Image medImg;
  29. @Override
  30. public void start(Stage stage) {
  31. initUI(stage);
  32. }
  33. private void initUI(Stage stage) {
  34. HBox root = new HBox(10);
  35. root.setAlignment(Pos.CENTER);
  36. root.setPadding(new Insets(15));
  37. loadImages();
  38. iview = new ImageView(muteImg);
  39. Slider slider = new Slider(0, 100, 0);
  40. slider.valueProperty().addListener(new MyChangeListener());
  41. Scene scene = new Scene(root);
  42. root.getChildren().addAll(slider, iview);
  43. stage.setTitle("Slider");
  44. stage.setScene(scene);
  45. stage.show();
  46. }
  47. private void loadImages() {
  48. muteImg = new Image("file:mute.png");
  49. minImg = new Image("file:min.png");
  50. maxImg = new Image("file:max.png");
  51. medImg = new Image("file:med.png");
  52. }
  53. private class MyChangeListener implements ChangeListener<Number> {
  54. @Override
  55. public void changed(ObservableValue<? extends Number> observable,
  56. Number oldValue, Number newValue) {
  57. Double value = newValue.doubleValue();
  58. if (value == 0) {
  59. iview.setImage(muteImg);
  60. } else if (value > 0 && value <= 30) {
  61. iview.setImage(minImg);
  62. } else if (value > 30 && value < 80) {
  63. iview.setImage(medImg);
  64. } else {
  65. iview.setImage(maxImg);
  66. }
  67. }
  68. }
  69. public static void main(String[] args) {
  70. launch(args);
  71. }
  72. }

在代码示例中,我们显示了SliderImageView控件。 通过拖动滑块的旋钮,我们可以更改标签控件上的图像。

  1. root.setAlignment(Pos.CENTER);

滑块和图像视图在行中居中。

  1. iview = new ImageView(muteImg);

ImageView显示加载了Image类的图像。

  1. Slider slider = new Slider(0, 100, 0);

将使用指定的最小值,最大值和当前值创建一个Slider控件。

  1. slider.valueProperty().addListener(new MyChangeListener());

监听器已添加到滑块的值更改中。

  1. Double value = newValue.doubleValue();
  2. if (value == 0) {
  3. iview.setImage(muteImg);
  4. } else if (value > 0 && value <= 30) {
  5. iview.setImage(minImg);
  6. } else if (value > 30 && value < 80) {
  7. iview.setImage(medImg);
  8. } else {
  9. iview.setImage(maxImg);
  10. }

基于滑块的当前值,我们将适当的图像设置为图像视图。

  1. private void loadImages() {
  2. muteImg = new Image("file:mute.png");
  3. minImg = new Image("file:min.png");
  4. maxImg = new Image("file:max.png");
  5. medImg = new Image("file:med.png");
  6. }

loadImages()方法从磁盘加载图像。

基本的 JavaFX 控件 - 图3

图:Slider

选择框

ChoiceBox用于向用户显示一小组预定义的选项。 当用户单击该框时,将显示一个选择列表。 一次只能选择一个选项。 未显示此列表时,将显示当前选择的选项。 ChoiceBox项目选择由SelectionModel处理。

ChoiceBoxEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import javafx.beans.value.ObservableValue;
  4. import javafx.collections.FXCollections;
  5. import javafx.geometry.Insets;
  6. import javafx.scene.Scene;
  7. import javafx.scene.control.ChoiceBox;
  8. import javafx.scene.control.Label;
  9. import javafx.scene.control.SingleSelectionModel;
  10. import javafx.scene.layout.VBox;
  11. import javafx.stage.Stage;
  12. /**
  13. * ZetCode JavaFX tutorial
  14. *
  15. * This program uses a ChoiceBox. The chosen
  16. * item is shown in a label.
  17. *
  18. * Author: Jan Bodnar
  19. * Website: zetcode.com
  20. * Last modified: June 2015
  21. */
  22. public class ChoiceBoxEx extends Application {
  23. @Override
  24. public void start(Stage stage) {
  25. initUI(stage);
  26. }
  27. private void initUI(Stage stage) {
  28. VBox root = new VBox(35);
  29. root.setPadding(new Insets(10));
  30. Label lbl = new Label();
  31. ChoiceBox chbox = new ChoiceBox(FXCollections.observableArrayList(
  32. "Ubuntu", "Redhat", "Arch", "Debian", "Mint"));
  33. SingleSelectionModel model = chbox.getSelectionModel();
  34. model.selectedItemProperty().addListener((ObservableValue observable,
  35. Object oldValue, Object newValue) -> {
  36. lbl.setText(newValue.toString());
  37. });
  38. root.getChildren().addAll(chbox, lbl);
  39. Scene scene = new Scene(root, 300, 250);
  40. stage.setTitle("ChoiceBox");
  41. stage.setScene(scene);
  42. stage.show();
  43. }
  44. public static void main(String[] args) {
  45. launch(args);
  46. }
  47. }

在我们的示例中,我们有一个选择框和一个标签。 选择框包含一个字符串列表,这些字符串表示 Linux 发行版的名称。 从选择框中选择的项目显示在标签中。

  1. Label lbl = new Label();

Label显示了从选择框中选择的当前项目。

  1. ChoiceBox chbox = new ChoiceBox(FXCollections.observableArrayList(
  2. "Ubuntu", "Redhat", "Arch", "Debian", "Mint"));

创建了ChoiceBox。 它以可观察的数组列表作为参数。

  1. SingleSelectionModel model = chbox.getSelectionModel();
  2. model.selectedItemProperty().addListener((ObservableValue observable,
  3. Object oldValue, Object newValue) -> {
  4. lbl.setText(newValue.toString());
  5. });

要实现监听器,我们需要使用getSelectionModel()方法获得选择模型。 该模型包含可观察的selectedItem属性。 在处理器方法内部,我们获取选定的值并将其设置为标签。

基本的 JavaFX 控件 - 图4

图:ChoiceBox

进度条

ProgressBar是一个控件,用于指示带有完成条的特定任务的处理。

ProgressBarEx.java

  1. package com.zetcode;
  2. import javafx.animation.KeyFrame;
  3. import javafx.animation.KeyValue;
  4. import javafx.animation.Timeline;
  5. import javafx.application.Application;
  6. import javafx.event.ActionEvent;
  7. import javafx.geometry.Insets;
  8. import javafx.geometry.Pos;
  9. import javafx.scene.Scene;
  10. import javafx.scene.control.Button;
  11. import javafx.scene.control.ProgressBar;
  12. import javafx.scene.layout.HBox;
  13. import javafx.stage.Stage;
  14. import javafx.util.Duration;
  15. /**
  16. * ZetCode JavaFX tutorial
  17. *
  18. * This program presents the ProgressBar control.
  19. *
  20. * Author: Jan Bodnar
  21. * Website: zetcode.com
  22. * Last modified: June 2015
  23. */
  24. public class ProgressBarEx extends Application {
  25. @Override
  26. public void start(Stage stage) {
  27. initUI(stage);
  28. }
  29. private void initUI(Stage stage) {
  30. HBox root = new HBox(15);
  31. root.setAlignment(Pos.CENTER);
  32. root.setPadding(new Insets(10));
  33. ProgressBar pbar = new ProgressBar(0);
  34. pbar.setPrefWidth(150);
  35. KeyFrame frame1 = new KeyFrame(Duration.ZERO,
  36. new KeyValue(pbar.progressProperty(), 0));
  37. KeyFrame frame2 = new KeyFrame(Duration.seconds(3),
  38. new KeyValue(pbar.progressProperty(), 1));
  39. Timeline task = new Timeline(frame1, frame2);
  40. Button btn = new Button("Start");
  41. btn.setOnAction((ActionEvent actionEvent) -> {
  42. task.playFromStart();
  43. });
  44. root.getChildren().addAll(pbar, btn);
  45. Scene scene = new Scene(root);
  46. stage.setTitle("ProgressBar");
  47. stage.setScene(scene);
  48. stage.show();
  49. }
  50. public static void main(String[] args) {
  51. launch(args);
  52. }
  53. }

该示例由进度条和按钮组成。 该按钮将启动进度条,并对其进行动画处理几秒钟。

  1. ProgressBar pbar = new ProgressBar(0);

构造器使用给定的进度值创建一个新的ProgressBar

  1. KeyFrame frame1 = new KeyFrame(Duration.ZERO,
  2. new KeyValue(pbar.progressProperty(), 0));
  3. KeyFrame frame2 = new KeyFrame(Duration.seconds(3),
  4. new KeyValue(pbar.progressProperty(), 1));
  5. Timeline task = new Timeline(frame1, frame2);

此代码创建一个简单的动画任务。 动画由两个帧组成。 动画属性定义为KeyValues

  1. Button btn = new Button("Start");
  2. btn.setOnAction((ActionEvent actionEvent) -> {
  3. task.playFromStart();
  4. });

触发后,该按钮调用playFromStart()方法,该方法从初始位置开始向前播放动画。

基本的 JavaFX 控件 - 图5

图:ProgressBar

在 JavaFX 教程的这一部分中,我们介绍了基本的 JavaFX 控件。