Java语言程序设计 习题第十六章
16.2章节习题
16.1 如何创建一个具有一个节点但是没有文本的标签?
Label lb = new label();
16.2 如何在一个标签中将文本放在节点的右侧?
lb.setContentDisplay(ContentDispaly.LEFT);
16.3 如何在一个标签中显示多行文本?
使用\n
16.4 标签中的文本如何加下划线?
lb.setUnderline(true);
16.3章节习题
16.5 如何创建一个具有一段文本和一个节点的按钮?可以将所有Labeled的方法应用于Button上吗?
Button bt = new Button();
可以
16.6 程序清单16-2中为何getPane()方法是受保护的?为何数据域text是受保护的?
继承安全性
16.7 如何设置一个处理器用于处理按钮单击的动作?
button.setOnAction(handler);
16.4章节习题
16.8 如何检测一个复选框是否被选中?
chk.isSelected();
16.9 可以将用于Labeled的所有方法用于CheckBox?
可以
16.10 可否将一个复选框中 graphic 属性设置为一个节点?
可以
16.5章节习题
16.11 如何判断一个单选按钮是否被选中?
rb.isSelected();
16.12 可以将 Labeled 中所有的方法应用于 RadioButton 吗?
可以
16.13 可以将单选按钮的 graphic 属性设置为任何节点吗?
可以
16.14 如何将单选按钮分组?
使用ToggleGroup tg
16.6章节习题
16.15 可以禁用文本域的编辑功能吗?
可以
16.16 可以将TextlnputControl的所有方法应用于TextField之上吗?
可以
16.17 可以将文本域的graphic属性设置为一个节点吗?
不可以
16.18 如何将文本域里面的文本设置为右对齐?
tf.setAlignment(Pos.BASELINE_RIGHT);
16.7章节习题
16.19 如何创建一个具有10行、20列的文本区域?
taNote.setPrefColumnCount(20);
taNote.setPrefRowCount(10);
16.20 如何获得文本区域里面的文本?
ta.getText();
16.21 如何禁用一个文本区域里面的编辑功能?
setEditable(false);
16.22 在文本区域里面可以使用什么方法来将一行文本进行折行显示?
ta.setWrapText(true);
16.8章节习题
16.23 如何创建一个组合框并加人三个条目?
new ComboBox<>();
cbo.getItems().addAll(item1, item2, item3);
16.24 如何从一个组合框中获取一个条目?如何从一个组合框中获取一个选中条目?
cbo.getItems();
cbo.getValue();
16.25 如何得到一个组合框中的条目数?如何获得组合框中一个指定索引号的条目?
cbo.getItems().size();
cbo.getItems().get(i);
16.26 当选择一个新的条目时,ComboBox将触发什么事件?
ActionEvent
16.9章节习题
16.27 如何创建一个具有一个字符串数组的可观察的列表?
FXCollections.observableArrayList(arrayOfStrings);
16.28 如何设置一个列表视图的方向?
lv.setOrientation(Orientation.HORIZONTAL);
lv.setOrientation(Orientation.VERITCAL);
16.29 列表视图有什么可用的选择模式?什么是默认的选择模式?如何设置一个选择模式?
SelectionMode.MULTIPLE
SelectionMode.SINGLE
lv.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
16.30 如何获得选中的条目以及选中的下标?
lv.getSelectionModel().getSelectedItems();
lv.getSelectionModel().getSelectedIndices();
16.10章节习题
16.31 如何创建一个水平滚动条?如何创建一个垂直滚动条?
new ScrollBar() ;
setOrientation(Orientation.HORIZONTAL);
setOrientation(Orientation.VERTICAL);
16.32 如何编写代码,用以响应滚动条的 value 属性的改变?
sb.valueProperty().addListener(ov -> statements);
16.33 如何从滚动条获得值?如何从滚动条获得最大值?
sb.getValue();
sb.getMax();
16.11章节习题
16.34 如何创建一个水平滑动条?如何创建一个垂直滑动条?
new Slider();
setOrientation(Orientation.HORIZONTAL);
setOrientation(Orientation.VERTICAL);
16.35 如何添加一个监听器用于处理滑动条的属性值改变?
sl.valueProperty().addListener(ov -> statements);
16.36 如何获得滑动条上的值?如何获得滑动条上的最大值?
sl.getValue();
sl.getMax();
16.12章节习题
16.37 游戏开始时,whoseTurn中的值是什么?游戏结束时候.whoseTurn中的值是什么?
‘X’
Winner’s token
16.38 如果游戏尚未结束,当用户在一个空单元格上单击时,将发生什么?如果游戏已经结束,当用户在一个空单元格上单击时,又将发生什么?
当前值会被取代
什么也不会发生
16.39 程序如何判断是否已经有玩家获胜?程序如何判断是否所有的单元格都被填充?
是否三颗一样的棋子连在一起
isFull()方法
16.13章节习题
16.40 如何从一个URL创建一个Media对象? 如何创建一个MediaPlayer? 如何创建一个MediaView?
new Media(url);
new MediaPlayer(media);
new MediaView(mediaPlayer);
16.41 如果URL输人成cs.armstrong.edu/liang/common/sample.mp4,前面不包含http://,可以运行吗?
不可以
16.42 可否将一个Media置于多个MediaPlayer中?可否将一个MediaPlayer置于多个MediaView中?可否将一个MediaView置于多个Pane中?
前两个可以,最后一个不行
16.14章节习题
16.43 程序清单16-15中,哪行代码设置了初始图像图标,哪行代码播放音频?
ImageView imageView = new ImageView(images[currentIndex]);
mp[currentIndex].play();
16.44 程序淸单16-15中,当组合框中的新的国家被选择时,程序会做什么?
停止播放音频,设置新图片,播放新音频
编程练习题
*16.1(使用单选按钮)
编写一个GUI程序如图16-36a所示。可以使用按钮将消息进行左右移动,并且使用单选按钮来修改消息显示的颜色
package com.example.demo;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.RadioButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Test extends Application {
public BorderPane getPane() {
BorderPane borderPane = new BorderPane();
HBox hBoxRb = new HBox();
RadioButton rbRed = new RadioButton("Red");
RadioButton rbYellow = new RadioButton("Yellow");
RadioButton rbBlack = new RadioButton("Black");
RadioButton rbOrange = new RadioButton("Orange");
hBoxRb.getChildren().addAll(rbRed, rbYellow, rbBlack, rbOrange);
// 让面板内的节点居中对齐
hBoxRb.setAlignment(Pos.CENTER);
// 设置每个节点的间距
hBoxRb.setSpacing(5);
// 设置节点和面板之间的间距
hBoxRb.setPadding(new Insets(5, 5, 5, 5));
ToggleGroup group = new ToggleGroup();
rbRed.setToggleGroup(group);
rbYellow.setToggleGroup(group);
rbBlack.setToggleGroup(group);
rbOrange.setToggleGroup(group);
Pane pane = new Pane();
Text text = new Text(70, 45, "Programming is fun");
pane.getChildren().addAll(text);
pane.setStyle("-fx-border-color: Black");
HBox hBoxBt = new HBox();
Button btLeft = new Button("Left");
Button btRight = new Button("Right");
hBoxBt.getChildren().addAll(btLeft, btRight);
hBoxBt.setAlignment(Pos.CENTER);
hBoxBt.setSpacing(10);
hBoxBt.setPadding(new Insets(5, 5, 5, 5));
borderPane.setTop(hBoxRb);
borderPane.setCenter(pane);
borderPane.setBottom(hBoxBt);
btLeft.setOnAction(e -> {text.setX(text.getX() - 10);});
btRight.setOnAction(e -> {text.setX(text.getX() + 10);});
rbRed.setOnAction(e -> {
if (rbRed.isSelected())
text.setFill(Color.RED);
});
rbYellow.setOnAction(e -> {
if (rbYellow.isSelected())
text.setFill(Color.YELLOW);
});
rbBlack.setOnAction(e -> {
if (rbBlack.isSelected())
text.setFill(Color.BLACK);
});
rbOrange.setOnAction(e -> {
if (rbOrange.isSelected())
text.setFill(Color.ORANGE);
});
return borderPane;
}
@Override
public void start(Stage pStage) {
Scene scene = new Scene(getPane(), 250, 150);
pStage.setTitle("Test Program");
pStage.setScene(scene);
pStage.show();
}
}
输出结果:
*16.2 (选择几何图形)
编写一个绘制各种几何图形的程序,如图16-36b所示。用户从单选按钮中选择一个几何图形 ,并且使用复选框指定是否被填充
package com.example.demo;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Ellipse;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class Test extends Application {
public BorderPane getPane() {
BorderPane borderPane = new BorderPane();
HBox hBox = new HBox();
RadioButton rbCircle = new RadioButton("Circle");
RadioButton rbRec = new RadioButton("Rectangle");
RadioButton rbEllipse = new RadioButton("Ellipse");
CheckBox chkFill = new CheckBox("Fill");
hBox.getChildren().addAll(rbCircle, rbRec, rbEllipse, chkFill);
// 让面板内的节点居中对齐
hBox.setAlignment(Pos.CENTER);
// 设置每个节点的间距
hBox.setSpacing(5);
// 设置节点和面板之间的间距
hBox.setPadding(new Insets(5, 5, 5, 5));
ToggleGroup group = new ToggleGroup();
rbCircle.setToggleGroup(group);
rbRec.setToggleGroup(group);
rbEllipse.setToggleGroup(group);
StackPane pane = new StackPane();
pane.setStyle("-fx-border-color: Black");
Circle circle = new Circle(10);
circle.setFill(Color.TRANSPARENT);
circle.setStroke(Color.BLACK);
Rectangle rec = new Rectangle(30, 10);
rec.setFill(Color.TRANSPARENT);
rec.setStroke(Color.BLACK);
Ellipse ellipse = new Ellipse(10, 30);
ellipse.setFill(Color.TRANSPARENT);
ellipse.setStroke(Color.BLACK);
chkFill.setOnAction(e -> {
// 防止getChildren().get(0)越界
if (chkFill.isSelected() && (rbCircle.isSelected() || rbRec.isSelected() || rbEllipse.isSelected())) {
// 设置填充样式
pane.getChildren().get(0).setStyle("-fx-fill: Black");
}
else if (!chkFill.isSelected() && (rbCircle.isSelected() || rbRec.isSelected() || rbEllipse.isSelected()))
// 取消填充样式
pane.getChildren().get(0).setStyle(null);
});
rbCircle.setOnAction(e -> {
// 取消可能存在的填充样式
circle.setStyle(null);
// 取消可能存在的所有节点
pane.getChildren().clear();
// 每次重新点击一个按钮,就取消选择checkbox
chkFill.setSelected(false);
pane.getChildren().add(circle);
});
rbRec.setOnAction(e -> {
rec.setStyle(null);
pane.getChildren().clear();
chkFill.setSelected(false);
pane.getChildren().add(rec);
});
rbEllipse.setOnAction(e -> {
ellipse.setStyle(null);
pane.getChildren().clear();
chkFill.setSelected(false);
pane.getChildren().add(ellipse);
});
borderPane.setCenter(pane);
borderPane.setBottom(hBox);
return borderPane;
}
@Override
public void start(Stage pStage) {
Scene scene = new Scene(getPane(), 250, 150);
pStage.setTitle("Test Program");
pStage.setScene(scene);
pStage.show();
}
}
输出结果:
**16.3 (交通信号灯)
编写一个程序来模拟交通信号灯。程序可以让用户从红、黄、绿三种顔色灯中选择一种。当选择一个单选按钮后,相应的灯被打开,并且一次只能亮一种灯(如图16-37a所示)。程序开始时所有的灯都是不亮的
package com.example.demo;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class Test extends Application {
public BorderPane getPane() {
BorderPane borderPane = new BorderPane();
HBox hBox = new HBox();
RadioButton rbRed = new RadioButton("Red");
RadioButton rbYellow = new RadioButton("Yellow");
RadioButton rbGreen = new RadioButton("Green");
hBox.getChildren().addAll(rbRed, rbYellow, rbGreen);
// 让面板内的节点居中对齐
hBox.setAlignment(Pos.CENTER);
// 设置每个节点的间距
hBox.setSpacing(5);
// 设置节点和面板之间的间距
hBox.setPadding(new Insets(5, 5, 5, 5));
ToggleGroup group = new ToggleGroup();
rbRed.setToggleGroup(group);
rbYellow.setToggleGroup(group);
rbGreen.setToggleGroup(group);
StackPane stackPane = new StackPane();
GridPane gridPane = new GridPane();
Rectangle rec = new Rectangle(25, 80);
rec.setFill(Color.TRANSPARENT);
rec.setStroke(Color.BLACK);
Circle red = new Circle(10);
red.setFill(Color.TRANSPARENT);
red.setStroke(Color.BLACK);
Circle yellow = new Circle(10);
yellow.setFill(Color.TRANSPARENT);
yellow.setStroke(Color.BLACK);
Circle green = new Circle(10);
green.setFill(Color.TRANSPARENT);
green.setStroke(Color.BLACK);
gridPane.setAlignment(Pos.CENTER);
gridPane.setVgap(5);
gridPane.add(red, 0, 0);
gridPane.add(yellow, 0, 1);
gridPane.add(green, 0, 2);
stackPane.getChildren().addAll(gridPane, rec);
rbRed.setOnAction(e -> {
yellow.setFill(Color.TRANSPARENT);
green.setFill(Color.TRANSPARENT);
red.setFill(Color.RED);
});
rbYellow.setOnAction(e -> {
green.setFill(Color.TRANSPARENT);
red.setFill(Color.TRANSPARENT);
yellow.setFill(Color.YELLOW);
});
rbGreen.setOnAction(e -> {
yellow.setFill(Color.TRANSPARENT);
red.setFill(Color.TRANSPARENT);
green.setFill(Color.GREEN);
});
borderPane.setCenter(stackPane);
borderPane.setBottom(hBox);
return borderPane;
}
@Override
public void start(Stage pStage) {
Scene scene = new Scene(getPane(), 250, 150);
pStage.setTitle("Test Program");
pStage.setScene(scene);
pStage.show();
}
}
输出结果:
*16.4 (创建一个英里/公里的转换器)
编写一个程序来转换英里和公里,如图16-37b所示。如果在英里文本域Mile中输入一个值之后按下回车键,就会在公里文本域公里值。同样的,在公里文本域Kilometer中输入一个值之后按下回车键,就会在英里文本域Mile中显示对应的英里值
package com.example.demo;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class Test extends Application {
public VBox getPane() {
VBox vBox = new VBox();
TextField mile = new TextField();
TextField kilometer = new TextField();
Label lbMile = new Label("Mile", mile);
lbMile.setContentDisplay(ContentDisplay.RIGHT);
Label lbKilo = new Label("Kilometer", kilometer);
lbKilo.setContentDisplay(ContentDisplay.RIGHT);
vBox.getChildren().addAll(lbMile, lbKilo);
vBox.setAlignment(Pos.CENTER_RIGHT);
vBox.setSpacing(10);
vBox.setPadding(new Insets(5, 20, 5, 5));
mile.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER)
kilometer.setText("" + Double.parseDouble(mile.getText()) * 1.61);
});
kilometer.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER)
mile.setText("" + Double.parseDouble(kilometer.getText()) / 1.61);
});
mile.requestFocus();
kilometer.requestFocus();
return vBox;
}
@Override
public void start(Stage pStage) {
Scene scene = new Scene(getPane(), 250, 150);
pStage.setTitle("Test Program");
pStage.setScene(scene);
pStage.show();
}
}
输出结果:
*16.5 (转換數字)
编写一个程序,在十进制、十六进制和二进制间转换数字,如图16-37c所示。当在十进制值的文本域中输入一个十进制值并且按回车键,会在其他两个文本域中显示相应的十六进制和二进制数字。同理,也可以在其他文本域中输入值,然后进行相应转换
package com.example.demo;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class Test extends Application {
public VBox getPane() {
VBox vBox = new VBox();
TextField decimal = new TextField();
TextField hex = new TextField();
TextField binary = new TextField();
Label lbDecimal = new Label("Decimal", decimal);
lbDecimal.setContentDisplay(ContentDisplay.RIGHT);
Label lbHex = new Label("Hex", hex);
lbHex.setContentDisplay(ContentDisplay.RIGHT);
Label lbBinary = new Label("Binary", binary);
lbBinary.setContentDisplay(ContentDisplay.RIGHT);
vBox.getChildren().addAll(lbDecimal, lbHex, lbBinary);
vBox.setAlignment(Pos.CENTER_RIGHT);
vBox.setSpacing(10);
vBox.setPadding(new Insets(5, 20, 5, 5));
decimal.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
hex.setText("" + Integer.toHexString(Integer.parseInt(decimal.getText())));
binary.setText("" + Integer.toBinaryString(Integer.parseInt(decimal.getText())));
}
});
hex.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
decimal.setText("" + Integer.parseInt(hex.getText(), 16));
binary.setText("" + Integer.toBinaryString(Integer.parseInt(hex.getText(), 16)));
}
});
binary.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
decimal.setText("" + Integer.parseInt(binary.getText(), 2));
hex.setText("" + Integer.toHexString(Integer.parseInt(binary.getText(), 2)));
}
});
decimal.requestFocus();
hex.requestFocus();
binary.requestFocus();
return vBox;
}
@Override
public void start(Stage pStage) {
Scene scene = new Scene(getPane(), 250, 150);
pStage.setTitle("Test Program");
pStage.setScene(scene);
pStage.show();
}
}
输出结果:
*16.6 (演示TextField的属性)
编写一个程序,动态地设置文本域的水平对齐属性和列宽属性,如图16-38a所示
package com.example.demo;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class Test extends Application {
public VBox getPane() {
VBox vBox = new VBox();
HBox hBox1 = new HBox();
HBox hBox2 = new HBox();
TextField textField1 = new TextField();
Label lbTextField1 = new Label("Text Field", textField1);
lbTextField1.setContentDisplay(ContentDisplay.RIGHT);
RadioButton left = new RadioButton("Left");
RadioButton center = new RadioButton("center");
RadioButton right = new RadioButton("Right");
ToggleGroup group = new ToggleGroup();
left.setToggleGroup(group);
center.setToggleGroup(group);
right.setToggleGroup(group);
TextField textField2 = new TextField();
Label lbTextField2 = new Label("Column Size", textField2);
lbTextField2.setContentDisplay(ContentDisplay.RIGHT);
hBox1.getChildren().add(lbTextField1);
hBox1.setAlignment(Pos.CENTER);
hBox2.getChildren().addAll(left, center, right, lbTextField2);
hBox2.setPadding(new Insets(5, 5, 5, 5));
hBox2.setAlignment(Pos.CENTER);
hBox2.setSpacing(10);
vBox.getChildren().addAll(hBox1, hBox2);
left.setOnAction(e -> {
textField1.setAlignment(Pos.CENTER_LEFT);
});
center.setOnAction(e -> {
textField1.setAlignment(Pos.CENTER);
});
right.setOnAction(e -> {
textField1.setAlignment(Pos.CENTER_RIGHT);
});
textField2.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
textField1.setPrefWidth(Integer.parseInt(textField2.getText()));
}
});
return vBox;
}
@Override
public void start(Stage pStage) {
Scene scene = new Scene(getPane(), 500, 100);
pStage.setTitle("Test Program");
pStage.setScene(scene);
pStage.show();
}
}
输出结果:
*16.7 (设置时钟的时间)
编写一个程序,显示一个时钟,并通过在三个文本域中输入小时、分钟和秒 钟来设置时钟的时间,如图16-38b 所示。使用程序清单14-21的ClockPane改变时钟大小使其居于面板中央
Test.java
package com.example.demo;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
public class Test extends Application {
@Override
public void start(Stage primaryStage) {
BorderPane borderPane = new BorderPane();
StackPane stackPane = new StackPane();
HBox hBox = new HBox();
TextField hour = new TextField();
TextField minute = new TextField();
TextField second = new TextField();
hour.setPrefWidth(30);
minute.setPrefWidth(30);
second.setPrefWidth(30);
Label lbHour = new Label("Hour", hour);
Label lbMinute = new Label("Minute", minute);
Label lbSecond = new Label("Second", second);
lbHour.setContentDisplay(ContentDisplay.RIGHT);
lbMinute.setContentDisplay(ContentDisplay.RIGHT);
lbSecond.setContentDisplay(ContentDisplay.RIGHT);
hBox.getChildren().addAll(lbHour, lbMinute, lbSecond);
hBox.setAlignment(Pos.CENTER);
hBox.setSpacing(10);
ClockPane clock = new ClockPane(0, 0, 0);
stackPane.getChildren().add(clock);
hour.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER)
clock.setHour(Integer.parseInt(hour.getText()));
});
minute.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER)
clock.setMinute(Integer.parseInt(minute.getText()));
});
second.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER)
clock.setSecond(Integer.parseInt(second.getText()));
});
borderPane.setCenter(stackPane);
borderPane.setBottom(hBox);
Scene scene = new Scene(borderPane, 250, 250);
primaryStage.setTitle("DisplayClock"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
}
ClockPane.java
package com.example.demo;
import java.util.Calendar;
import java.util.GregorianCalendar;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.text.Text;
public class ClockPane extends Pane {
private int hour;
private int minute;
private int second;
/** Construct a default clock with the current time*/
public ClockPane() {
setCurrentTime();
}
/** Construct a clock with specified hour, minute, and second */
public ClockPane(int hour, int minute, int second) {
this.hour = hour;
this.minute = minute;
this.second = second;
}
/** Return hour */
public int getHour() {
return hour;
}
/** Set a new hour */
public void setHour(int hour) {
this.hour = hour;
paintClock();
}
/** Return minute */
public int getMinute() {
return minute;
}
/** Set a new minute */
public void setMinute(int minute) {
this.minute = minute;
paintClock();
}
/** Return second */
public int getSecond() {
return second;
}
/** Set a new second */
public void setSecond(int second) {
this.second = second;
paintClock();
}
/* Set the current time for the clock */
public void setCurrentTime() {
// Construct a calendar for the current date and time
Calendar calendar = new GregorianCalendar();
// Set current hour, minute and second
this.hour = calendar.get(Calendar.HOUR_OF_DAY);
this.minute = calendar.get(Calendar.MINUTE);
this.second = calendar.get(Calendar.SECOND);
paintClock(); // Repaint the clock
}
/** Paint the clock */
private void paintClock() {
// Initialize clock parameters
double clockRadius =
Math.min(getWidth(), getHeight()) * 0.8 * 0.5;
double centerX = getWidth() / 2;
double centerY = getHeight() / 2;
// Draw circle
Circle circle = new Circle(centerX, centerY, clockRadius);
circle.setFill(Color.WHITE);
circle.setStroke(Color.BLACK);
Text t1 = new Text(centerX - 5, centerY - clockRadius + 12, "12");
Text t2 = new Text(centerX - clockRadius + 3, centerY + 5, "9");
Text t3 = new Text(centerX + clockRadius - 10, centerY + 3, "3");
Text t4 = new Text(centerX - 3, centerY + clockRadius - 3, "6");
// Draw second hand
double sLength = clockRadius * 0.8;
double secondX = centerX + sLength *
Math.sin(second * (2 * Math.PI / 60));
double secondY = centerY - sLength *
Math.cos(second * (2 * Math.PI / 60));
Line sLine = new Line(centerX, centerY, secondX, secondY);
sLine.setStroke(Color.RED);
// Draw minute hand
double mLength = clockRadius * 0.65;
double xMinute = centerX + mLength *
Math.sin(minute * (2 * Math.PI / 60));
double minuteY = centerY - mLength *
Math.cos(minute * (2 * Math.PI / 60));
Line mLine = new Line(centerX, centerY, xMinute, minuteY);
mLine.setStroke(Color.BLUE);
// Draw hour hand
double hLength = clockRadius * 0.5;
double hourX = centerX + hLength *
Math.sin((hour % 12 + minute / 60.0) * (2 * Math.PI / 12));
double hourY = centerY - hLength *
Math.cos((hour % 12 + minute / 60.0) * (2 * Math.PI / 12));
Line hLine = new Line(centerX, centerY, hourX, hourY);
hLine.setStroke(Color.GREEN);
getChildren().clear();
getChildren().addAll(circle, t1, t2, t3, t4, sLine, mLine, hLine);
}
@Override
public void setWidth(double width) {
super.setWidth(width);
paintClock();
}
@Override
public void setHeight(double height) {
super.setHeight(height);
paintClock();
}
}
输出结果:
**16.8 (几何:两个圆相交吗?)
编写一个程序,让用户指定两个圆的位置和大小,并且显示两个圆是否相交,如图16-39a 所示。用户可以通过鼠标单击圆内部区域并且拖动圆。圆被拖动时,文本域中的圆心坐标被更新。
package com.example.demo;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.scene.Scene;
public class Test extends Application {
Text text = new Text(" ");
@Override
public void start(Stage primaryStage) {
// vBox是总面板,包括所有子面板
VBox vBox = new VBox();
// 创建通知面板,在顶部,告知用户两个圆是否相交
HBox circle_Intersect_Notice = new HBox();
circle_Intersect_Notice.getChildren().add(text);
circle_Intersect_Notice.setAlignment(Pos.CENTER);
circle_Intersect_Notice.setPadding(new Insets(5, 5, 5, 5));
// 创建圆形作图面板,用户可以在此面板生成圆形
Pane circle_Drawing = new Pane();
Circle circle1 = new Circle(50, 30, 10, Color.TRANSPARENT);
Circle circle2 = new Circle(200, 30, 20, Color.TRANSPARENT);
circle1.setStroke(Color.BLACK);
circle2.setStroke(Color.BLACK);
circle_Drawing.getChildren().addAll(circle1, circle2);
circle_Drawing.setPrefSize(200, 200);
// circle_Info是一个总面板,包括两个子面板,用来设置2个圆的圆心和半径
HBox circle_Info = new HBox();
// 子面板1用来设置圆1的信息
VBox sub1_circle_Info = new VBox();
Text circle1_Guide = new Text("Enter circle1 info:");
TextField circle1_X_Field = new TextField();
circle1_X_Field.setPrefWidth(50);
Label circle1_X_Label = new Label("Center X", circle1_X_Field);
circle1_X_Label.setContentDisplay(ContentDisplay.RIGHT);
TextField circle1_Y_Field = new TextField();
circle1_Y_Field.setPrefWidth(50);
Label circle1_Y_Label = new Label("Center Y", circle1_Y_Field);
circle1_Y_Label.setContentDisplay(ContentDisplay.RIGHT);
TextField circle1_Radius_Field = new TextField();
circle1_Radius_Field.setPrefWidth(50);
Label circle1_Radius_Label = new Label("Radius", circle1_Radius_Field);
circle1_Radius_Label.setContentDisplay(ContentDisplay.RIGHT);
sub1_circle_Info.getChildren().addAll(circle1_Guide, circle1_X_Label, circle1_Y_Label, circle1_Radius_Label);
sub1_circle_Info.setAlignment(Pos.CENTER_RIGHT);
sub1_circle_Info.setStyle("-fx-border-color: Black");
sub1_circle_Info.setPadding(new Insets(5, 5, 5, 5));
// 子面板2用来设置圆2的信息
VBox sub2_circle_Info = new VBox();
Text circle2_Guide = new Text("Enter circle2 info:");
TextField circle2_X_Field = new TextField();
circle2_X_Field.setPrefWidth(50);
Label circle2_X_Label = new Label("Center X", circle2_X_Field);
circle2_X_Label.setContentDisplay(ContentDisplay.RIGHT);
TextField circle2_Y_Field = new TextField();
circle2_Y_Field.setPrefWidth(50);
Label circle2_Y_Label = new Label("Center Y", circle2_Y_Field);
circle2_Y_Label.setContentDisplay(ContentDisplay.RIGHT);
TextField circle2_Radius_Field = new TextField();
circle2_Radius_Field.setPrefWidth(50);
Label circle2_Radius_Label = new Label("Radius", circle2_Radius_Field);
circle2_Radius_Label.setContentDisplay(ContentDisplay.RIGHT);
sub2_circle_Info.getChildren().addAll(circle2_Guide, circle2_X_Label, circle2_Y_Label, circle2_Radius_Label);
sub2_circle_Info.setAlignment(Pos.CENTER_RIGHT);
sub2_circle_Info.setStyle("-fx-border-color: Black");
sub2_circle_Info.setPadding(new Insets(5, 5, 5, 5));
// 把2个子面板汇总到总面板circle_Info
circle_Info.getChildren().addAll(sub1_circle_Info, sub2_circle_Info);
circle_Info.setAlignment(Pos.CENTER);
circle_Info.setSpacing(5);
// 表示重新画圆的面板,包含一个按钮
HBox redraw = new HBox();
Button redraw_Button = new Button("Redraw Circles");
redraw.getChildren().add(redraw_Button);
redraw.setAlignment(Pos.CENTER);
redraw.setPadding(new Insets(5, 5, 5, 5));
// 把所有子面板添加到总面板
vBox.getChildren().addAll(circle_Intersect_Notice, circle_Drawing, circle_Info, redraw);
// 鼠标拖动圆1
circle1.setOnMouseDragged(e -> {
circle1.setCenterX(e.getX());
circle1.setCenterY(e.getY());
circle1_X_Field.setText("" + e.getX());
circle1_Y_Field.setText("" + e.getY());
circle1_Radius_Field.setText("" + circle1.getRadius());
// 判断两个圆是否相交
areCirclesIntersecting(circle1, circle2);
});
// 鼠标拖动圆2
circle2.setOnMouseDragged(e -> {
circle2.setCenterX(e.getX());
circle2.setCenterY(e.getY());
circle2_X_Field.setText("" + e.getX());
circle2_Y_Field.setText("" + e.getY());
circle2_Radius_Field.setText("" + circle2.getRadius());
areCirclesIntersecting(circle1, circle2);
});
// 键盘输入圆1信息
circle1_X_Field.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
circle1.setCenterX(Double.parseDouble(circle1_X_Field.getText()));
areCirclesIntersecting(circle1, circle2);
}
});
circle1_Y_Field.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
circle1.setCenterY(Double.parseDouble(circle1_Y_Field.getText()));
areCirclesIntersecting(circle1, circle2);
}
});
circle1_Radius_Field.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
circle1.setRadius(Double.parseDouble(circle1_Radius_Field.getText()));
areCirclesIntersecting(circle1, circle2);
}
});
// 键盘输入圆2信息
circle2_X_Field.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
circle2.setCenterX(Double.parseDouble(circle2_X_Field.getText()));
areCirclesIntersecting(circle1, circle2);
}
});
circle2_Y_Field.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
circle2.setCenterY(Double.parseDouble(circle2_Y_Field.getText()));
areCirclesIntersecting(circle1, circle2);
}
});
circle2_Radius_Field.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
circle2.setRadius(Double.parseDouble(circle2_Radius_Field.getText()));
areCirclesIntersecting(circle1, circle2);
}
});
redraw_Button.setOnAction(e -> {
text.setText("Two circles intersect? No");
circle1.setCenterX(50);
circle1.setCenterY(30);
circle1.setRadius(10);
circle2.setCenterX(200);
circle2.setCenterY(30);
circle2.setRadius(20);
circle1_X_Field.setText(null);
circle1_Y_Field.setText(null);
circle1_Radius_Field.setText(null);
circle2_X_Field.setText(null);
circle2_Y_Field.setText(null);
circle2_Radius_Field.setText(null);
});
Scene scene = new Scene(vBox, 250, 250);
primaryStage.setTitle("Test Program"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
public void areCirclesIntersecting(Circle circle1, Circle circle2) {
double R = circle1.getRadius();
double r = circle2.getRadius();
double x1 = circle1.getCenterX();
double y1 = circle1.getCenterY();
double x2 = circle2.getCenterX();
double y2 = circle2.getCenterY();
double d = Math.pow(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2), 0.5);
if (d > Math.abs(R - r) && d < R + r) {
text.setText("Two circles intersect? Yes");
} else
text.setText("Two circles intersect? No");
}
}
输出结果:
**16.9 (几何:两个矩形相交吗?)
编写一个程序,让用户指定两个矩形的位置和大小,并且显示两个矩形是否相交,如图16-39b所示。用户可以通过鼠标单击矩形内部区域并且拖动矩形。矩形被拖动时,文本域中的矩形中心坐标被更新。
package com.example.demo;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.scene.Scene;
public class Test extends Application {
Text text = new Text("Two rectangles intersect? No");
@Override
public void start(Stage primaryStage) {
// vBox是总面板,包括所有子面板
VBox vBox = new VBox();
// 创建通知面板,在顶部,告知用户两个矩形是否相交
HBox rec_Intersect_Notice = new HBox();
rec_Intersect_Notice.getChildren().add(text);
rec_Intersect_Notice.setAlignment(Pos.CENTER);
rec_Intersect_Notice.setPadding(new Insets(5, 5, 5, 5));
// 创建矩形作图面板,用户可以在此面板生成矩形
Pane rec_Drawing = new Pane();
Rectangle rec1 = new Rectangle(30, 20, 30, 20);
Rectangle rec2 = new Rectangle(150, 20, 40, 30);
rec1.setFill(Color.TRANSPARENT);
rec2.setFill(Color.TRANSPARENT);
rec1.setStroke(Color.BLACK);
rec2.setStroke(Color.BLACK);
rec_Drawing.getChildren().addAll(rec1, rec2);
rec_Drawing.setPrefSize(200, 200);
// rec_Info是一个总面板,包括两个子面板,用来设置2个矩形的信息
HBox rec_Info = new HBox();
// 子面板1用来设置矩形1的信息
VBox sub1_rec_Info = new VBox();
Text rec1_Guide = new Text("Enter rectangle 1 info:");
TextField rec1_X_Field = new TextField();
rec1_X_Field.setPrefWidth(50);
Label rec1_X_Label = new Label("X", rec1_X_Field);
rec1_X_Label.setContentDisplay(ContentDisplay.RIGHT);
TextField rec1_Y_Field = new TextField();
rec1_Y_Field.setPrefWidth(50);
Label rec1_Y_Label = new Label("Y", rec1_Y_Field);
rec1_Y_Label.setContentDisplay(ContentDisplay.RIGHT);
TextField rec1_Width_Field = new TextField();
rec1_Width_Field.setPrefWidth(50);
Label rec1_Width_Label = new Label("Width", rec1_Width_Field);
rec1_Width_Label.setContentDisplay(ContentDisplay.RIGHT);
TextField rec1_Height_Field = new TextField();
rec1_Height_Field.setPrefWidth(50);
Label rec1_Height_Label = new Label("Height", rec1_Height_Field);
rec1_Height_Label.setContentDisplay(ContentDisplay.RIGHT);
sub1_rec_Info.getChildren().addAll(rec1_Guide, rec1_X_Label, rec1_Y_Label, rec1_Width_Label, rec1_Height_Label);
sub1_rec_Info.setAlignment(Pos.CENTER_RIGHT);
sub1_rec_Info.setStyle("-fx-border-color: Black");
sub1_rec_Info.setPadding(new Insets(5, 5, 5, 5));
// 子面板2用来设置矩形2的信息
VBox sub2_rec_Info = new VBox();
Text rec2_Guide = new Text("Enter rectangle 2 info:");
TextField rec2_X_Field = new TextField();
rec2_X_Field.setPrefWidth(50);
Label rec2_X_Label = new Label("X", rec2_X_Field);
rec2_X_Label.setContentDisplay(ContentDisplay.RIGHT);
TextField rec2_Y_Field = new TextField();
rec2_Y_Field.setPrefWidth(50);
Label rec2_Y_Label = new Label("Y", rec2_Y_Field);
rec2_Y_Label.setContentDisplay(ContentDisplay.RIGHT);
TextField rec2_Width_Field = new TextField();
rec2_Width_Field.setPrefWidth(50);
Label rec2_Width_Label = new Label("Width", rec2_Width_Field);
rec2_Width_Label.setContentDisplay(ContentDisplay.RIGHT);
TextField rec2_Height_Field = new TextField();
rec2_Height_Field.setPrefWidth(50);
Label rec2_Height_Label = new Label("Height", rec2_Height_Field);
rec2_Height_Label.setContentDisplay(ContentDisplay.RIGHT);
sub2_rec_Info.getChildren().addAll(rec2_Guide, rec2_X_Label, rec2_Y_Label, rec2_Width_Label, rec2_Height_Label);
sub2_rec_Info.setAlignment(Pos.CENTER_RIGHT);
sub2_rec_Info.setStyle("-fx-border-color: Black");
sub2_rec_Info.setPadding(new Insets(5, 5, 5, 5));
// 把2个子面板汇总到总面板rec_Info
rec_Info.getChildren().addAll(sub1_rec_Info, sub2_rec_Info);
rec_Info.setAlignment(Pos.CENTER);
rec_Info.setSpacing(5);
// 表示重新画矩形的面板,包含一个按钮
HBox redraw = new HBox();
Button redraw_Button = new Button("Redraw Rectangles");
redraw.getChildren().add(redraw_Button);
redraw.setAlignment(Pos.CENTER);
redraw.setPadding(new Insets(5, 5, 5, 5));
// 把所有子面板添加到总面板
vBox.getChildren().addAll(rec_Intersect_Notice, rec_Drawing, rec_Info, redraw);
// 鼠标拖动矩形1
rec1.setOnMouseDragged(e -> {
rec1.setX(e.getX());
rec1.setY(e.getY());
rec1_X_Field.setText("" + e.getX());
rec1_Y_Field.setText("" + e.getY());
rec1_Width_Field.setText("" + rec1.getWidth());
rec1_Height_Field.setText("" + rec1.getHeight());
// 判断两个矩形是否相交
areRecsIntersecting(rec1, rec2);
});
// 鼠标拖动矩形2
rec2.setOnMouseDragged(e -> {
rec2.setX(e.getX());
rec2.setY(e.getY());
rec2_X_Field.setText("" + e.getX());
rec2_Y_Field.setText("" + e.getY());
rec2_Width_Field.setText("" + rec2.getWidth());
rec2_Height_Field.setText("" + rec2.getHeight());
areRecsIntersecting(rec1, rec2);
});
// 键盘输入矩形1信息
rec1_X_Field.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
rec1.setX(Double.parseDouble(rec1_X_Field.getText()));
areRecsIntersecting(rec1, rec2);
}
});
rec1_Y_Field.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
rec1.setY(Double.parseDouble(rec1_Y_Field.getText()));
areRecsIntersecting(rec1, rec2);
}
});
rec1_Width_Field.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
rec1.setWidth(Double.parseDouble(rec1_Width_Field.getText()));
areRecsIntersecting(rec1, rec2);
}
});
rec1_Height_Field.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
rec1.setHeight(Double.parseDouble(rec1_Height_Field.getText()));
areRecsIntersecting(rec1, rec2);
}
});
// 键盘输入矩形2信息
rec2_X_Field.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
rec2.setX(Double.parseDouble(rec2_X_Field.getText()));
areRecsIntersecting(rec1, rec2);
}
});
rec2_Y_Field.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
rec2.setY(Double.parseDouble(rec2_Y_Field.getText()));
areRecsIntersecting(rec1, rec2);
}
});
rec2_Width_Field.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
rec2.setWidth(Double.parseDouble(rec2_Width_Field.getText()));
areRecsIntersecting(rec1, rec2);
}
});
rec2_Height_Field.setOnKeyPressed(e -> {
if (e.getCode() == KeyCode.ENTER) {
rec2.setHeight(Double.parseDouble(rec2_Height_Field.getText()));
areRecsIntersecting(rec1, rec2);
}
});
redraw_Button.setOnAction(e -> {
text.setText("Two rectangles intersect or inside? No");
rec1.setX(30);
rec1.setY(20);
rec1.setWidth(30);
rec1.setHeight(20);
rec2.setX(150);
rec2.setY(20);
rec2.setWidth(40);
rec2.setHeight(30);
rec1_X_Field.setText(null);
rec1_Y_Field.setText(null);
rec2_X_Field.setText(null);
rec2_Y_Field.setText(null);
rec1_Width_Field.setText(null);
rec1_Height_Field.setText(null);
rec2_Width_Field.setText(null);
rec2_Height_Field.setText(null);
});
Scene scene = new Scene(vBox, 300, 250);
primaryStage.setTitle("Test Program"); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
public void areRecsIntersecting(Rectangle rec1, Rectangle rec2) {
double x1 = rec1.getX();
double y1 = rec1.getY();
double x2 = rec2.getX();
double y2 = rec2.getY();
double width1 = rec1.getWidth();
double width2 = rec2.getWidth();
double height1 = rec1.getHeight();
double height2 = rec2.getHeight();
double maxX1 = x1 + width1;
double minX1 = x1;
double maxY1 = y1 + height1;
double minY1 = y1;
double maxX2 = x2 + width2;
double minX2 = x2;
double maxY2 = y2 + height2;
double minY2 = y2;
if (maxX1 <= minX2 || minX1 >= maxX2 || maxY1 <= minY2 || minY1 >= maxY2) {
text.setText("Two rectangles intersect or inside? No");
} else {
text.setText("Two rectangles intersect or inside? Yes");
}
}
}
输出结果:
**16.10 (文本浏览器)
编写一个程序在文本区域中显示一个文本文件,如图 16-40a 所示。用户在文本域中输人一个文件名,然后单击View按钮;在文本区域中会显示这个文件
package com.example.demo;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Test extends Application {
private TextField fileNameField;
private TextArea contentArea;
@Override
public void start(Stage primaryStage) {
// 创建输入文件名的TextField
fileNameField = new TextField();
// 创建按钮
Button viewButton = new Button("View");
// 创建文本显示区域
contentArea = new TextArea();
contentArea.setEditable(false);
// 创建HBox,并将文本域和按钮添加到HBox中
HBox inputBox = new HBox(fileNameField, viewButton);
inputBox.setSpacing(10);
inputBox.setPadding(new Insets(5, 5, 5, 5));
inputBox.setAlignment(Pos.CENTER);
// 创建边界布局,并将输入框放置在底部,文本显示区域放置在中间
BorderPane root = new BorderPane();
root.setBottom(inputBox);
root.setCenter(contentArea);
// 点击按钮
viewButton.setOnAction(e -> viewFileContent());
Scene scene = new Scene(root, 250, 200);
primaryStage.setTitle("File Viewer");
primaryStage.setScene(scene);
primaryStage.show();
}
private void viewFileContent() {
String fileName = fileNameField.getText().trim();
if (!fileName.isEmpty()) {
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
StringBuilder content = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
content.append(line).append("\n");
}
contentArea.setText(content.toString());
} catch (IOException e) {
contentArea.setText("Error: " + e.getMessage());
}
} else {
contentArea.setText("Please enter a file name.");
}
}
}
输出结果: