文章目录
- 前言
- 一、基础知识
- 二、命令执行小工具
前言
继续JavaFX的学习,本章主要是设置窗口和使用布局面板布置场景的基础知识和实现一个命令执行的小工具。
一、基础知识
1)启动 JavaFX 应用程序时,会自动创建一个称为主阶段的阶段。此阶段通过 primaryStage 参数传递给应用程序的 start 方法,然后可以使用主要阶段通过添加包含一个或多个控件或其他用户界面节点的场景来创建应用程序的用户界面。
@Override
public void start(Stage primaryStage){ }
2)下面是Stage 类方法的一些细节:
不让用户调整舞台大小,使用 setResizable 方法设置为 false
primaryStage.setResizable(false);
最大化窗口中显示舞台,使用setMaximized()方法,最大化的窗口仍然具有标题栏、窗口边框以及最小化等装饰
primaryStage.setMaximized(true);
3)JavaFX程序的主阶段或其他阶段只能显示一个场景,但是可以创建多个场景然后根据需求切换。假如开发一个程序想让用户在编辑视图和页面预览视图之间切换,可以创建两个不同的场景,每个场景对应一个视图,然后要切换视图,只需要调用stage的setScene方法来切换就好。
4)HBox 布局就是水平一行的布局方式,如下所示:
package sample;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
// 创建三个将要放置在HBox中的节点
Button btn1 = new Button("First button");
Button btn2 = new Button("Second button");
Button btn3 = new Button("Third button");
// 调用构造方法初始化对象 然后实例化对象时将节点作为参数传递
HBox hbox = new HBox(btn1, btn2, btn3);
primaryStage.setTitle("HBox布局");
primaryStage.setScene(new Scene(hbox,500,50));
primaryStage.show();
}
}
5)最初为空的状态下创建 HBox 控件,然后再添加控件,可以这样写:
package sample;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
// 调用构造函数创建布局窗口
HBox hbox = new HBox();
// 用于设置每个节点的距离 单位为像素
hbox.setSpacing(15);
// 在布局窗口的四周添加空间 可以使用setPadding()方法 此方法将 Insets 类型的对象作为参数
// 此处统一设置为 15 像素
hbox.setPadding(new Insets(15));
// 还可以设置成不同的像素
//hbox.setPadding(new Insets(20, 10, 20, 10));
// 创建四个将要放置在HBox中的节点
TextField motto = new TextField();
Button btn1 = new Button("保存座右铭");
Button btn2 = new Button("删除座右铭");
Button btn3 = new Button("发布座右铭");
// 每个面板包含一个列表用于容纳面板中的节点 可用getChildren 方法获取
// 此处调用 getChildren 方法 该方法返回面板中的节点列表
// 使用addAll() 方法把这四个控件节点添加到面板中。
hbox.getChildren().addAll(motto, btn1, btn2, btn3);
primaryStage.setTitle("HBox布局");
primaryStage.setScene(new Scene(hbox,600,50));
primaryStage.show();
}
}
6)调整控件的大小。
package sample;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
// 调用构造函数创建布局窗口
HBox hbox = new HBox();
// 创建四个将要放置在HBox中的节点
TextField motto = new TextField();
Button btn1 = new Button("保存座右铭");
Button btn2 = new Button("删除座右铭");
Button btn3 = new Button("发布座右铭");
// 调整控件大小 setPrefWidth:宽度 setMaxHeight:高度
motto.setPrefWidth(200);
motto.setMaxHeight(100);
btn1.setPrefWidth(150);
btn1.setMaxHeight(80);
btn2.setPrefWidth(100);
btn2.setMaxHeight(60);
btn3.setPrefWidth(50);
btn3.setMaxHeight(40);
// 每个面板包含一个列表用于容纳面板中的节点 可用getChildren 方法获取
// 此处调用 getChildren 方法 该方法返回面板中的节点列表
// 使用addAll() 方法把这四个控件节点添加到面板中。
hbox.getChildren().addAll(motto, btn1, btn2, btn3);
primaryStage.setTitle("HBox布局");
primaryStage.setScene(new Scene(hbox,600,50));
primaryStage.show();
}
}
7)创建三个按钮和一个间隔,将所有三个按钮的边距设置为 10 像素,然后将三个按钮和间隔添加到 HBox,使前两个按钮出现在 HBox 的左侧,第三个按钮出现在右侧。
package sample;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
// 创建三个将要放置在HBox中的节点
Button btn1 = new Button("保存座右铭");
Button btn2 = new Button("删除座右铭");
Button btn3 = new Button("发布座右铭");
// 调用构造函数创建间隔节点
Region spacer = new Region();
// 设置按钮的四周的页边距
HBox.setMargin(btn1, new Insets(15));
HBox.setMargin(btn2, new Insets(15));
HBox.setMargin(btn3, new Insets(15));
// 在HBox中水平增长UI控件,可以使用静态HBox.setHgrow()方法。
// 第一个参数为间隔节点的参数 第二个参数默认就好
HBox.setHgrow(spacer, Priority.ALWAYS);
HBox hbox = new HBox(10, btn1, btn2, spacer, btn3);
primaryStage.setTitle("HBox布局");
primaryStage.setScene(new Scene(hbox,600,50));
primaryStage.show();
}
}
8)VBox 布局就是垂直一列的布局方式,其他的东西和HBox一样就不再来一遍了。如下所示:
package sample;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
// 创建三个将要放置在VBox中的节点
Button btn1 = new Button("保存座右铭");
Button btn2 = new Button("删除座右铭");
Button btn3 = new Button("发布座右铭");
// 调用构造方法初始化对象 然后实例化对象时将节点作为参数传递
VBox vbox = new VBox(btn1, btn2, btn3);
primaryStage.setTitle("HBox布局");
primaryStage.setScene(new Scene(vbox,600,200));
primaryStage.show();
}
}
9)让三个按钮有相同的宽度并且居中对其。
package sample;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
// 创建三个将要放置在VBox中的节点
Button btn1 = new Button("保存座右铭");
Button btn2 = new Button("座右铭");
Button btn3 = new Button("发布座右铭");
btn1.setMaxWidth(100);
btn2.setMaxWidth(100);
btn3.setMaxWidth(100);
// 调用构造方法初始化对象 然后实例化对象时将节点作为参数传递
VBox vbox = new VBox(btn1, btn2, btn3);
// setAlignment 方法,设置 VBox或者HBox中子节点的对齐方式。
// 可让你的控制窗口中包含的节点相互对齐。
vbox.setAlignment(Pos.CENTER);
primaryStage.setTitle("HBox布局");
primaryStage.setScene(new Scene(vbox,600,200));
primaryStage.show();
}
}
10)流布局分为水平流布局和垂直流布局,可以使用 FlowPane 类来创建流布局,水平流布局就是按钮一行满了自动换下一行,满了再换下一行,直到所有的节点都已放置。
package sample;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
// 创建五个将要放置在VBox中的节点
Button btn1 = new Button("First button");
Button btn2 = new Button("Second button");
Button btn3 = new Button("button");
Button btn4 = new Button("fourth button");
Button btn5 = new Button("fifth button");
// 创建一个空的水平流布局,水平和垂直间隙都设置为0 并填充指定的子节点
// Orientation.HORIZONTAL代表水平方向 Orientation.VERTICAL代表垂直方向
FlowPane vbox = new FlowPane(Orientation.HORIZONTAL, btn1, btn2, btn3, btn4, btn5);
// 创建一个空的水平流布局,水平和垂直间隙都设置为10 并填充指定的子节点
//FlowPane vbox = new FlowPane(Orientation.HORIZONTAL,10,10, btn1, btn2, btn3, btn4, btn5);
primaryStage.setTitle("HBox布局");
primaryStage.setScene(new Scene(vbox,600,200));
primaryStage.show();
}
}
11)BorderPane布局也可以说是边框布局,分为五个区域:上、左、中、右和下,这些区域可以是任意大小,如果应用不需要某个区域,你可以不定义它,然后窗格就不会给这个区域分配空间。
border pane可用于这种经典的外观:top:工具栏,bottom:状态栏,left:导航栏,right:附加信息,center:工作区。
package sample;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
// 创建五个将要放置在BorderPane中的节点
Button btnTop = new Button("Top");
Button btnLeft = new Button("Left");
Button btnCenter = new Button("Center");
Button btnRight = new Button("Right");
Button btnBottom = new Button("Bottom");
// 调用构造方法初始化对象 然后实例化对象时将节点作为参数传递
// 参数的对应的顺序顺序是 中间 上 右 下 左
BorderPane bp = new BorderPane(btnCenter,btnTop,btnRight,btnBottom,btnLeft);
// setAlignment 方法,设置BorderPane中子节点的对齐方式。
// 可让你的控制窗口中包含的节点相互对齐 CENTER 设置成中心节点
bp.setAlignment(btnTop,Pos.CENTER);
bp.setAlignment(btnLeft,Pos.CENTER);
bp.setAlignment(btnCenter,Pos.CENTER);
bp.setAlignment(btnRight,Pos.CENTER);
bp.setAlignment(btnBottom,Pos.CENTER);
primaryStage.setTitle("BorderPane布局");
primaryStage.setScene(new Scene(bp,600,200));
primaryStage.show();
}
}
12)在BorderPane布局中加入HBox布局。
package sample;
import javafx.application.Application;
import javafx.geometry.Insets;
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;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
// 调用构造函数创建布局窗口
HBox hbox = new HBox();
// 用于设置每个节点的距离 单位为像素
hbox.setSpacing(15);
// 在布局窗口的四周添加空间 可以使用setPadding()方法 此方法将 Insets 类型的对象作为参数
// 此处统一设置为 15 像素
hbox.setPadding(new Insets(15));
// 创建四个将要放置在HBox中的节点
TextField textline = new TextField(); // 文本行节点
TextArea textfield = new TextArea(); // 文本域节点
Button btn1 = new Button("执行命令"); // 按钮一:执行命令按钮节点
Button btn2 = new Button("清空命令"); // 按钮二:清空命令按钮节点
// 每个面板包含一个列表用于容纳面板中的节点 可用getChildren 方法获取
// 此处调用 getChildren 方法 该方法返回面板中的节点列表
// 使用addAll() 方法把这四个控件节点添加到面板中。
hbox.getChildren().addAll(textline, textfield, btn1, btn2);
// 创建空的BorderPane布局
BorderPane root =new BorderPane();
// 在BorderPane布局中调用setTop方法将hbox布局放置在顶部 textfield也类似
root.setTop(hbox);
root.setCenter(textfield);
primaryStage.setTitle("命令执行小工具");
primaryStage.setScene(new Scene(root,600,400));
primaryStage.show();
}
}
二、命令执行小工具
package sample;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
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.InputStreamReader;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
// 调用构造函数创建布局窗口
HBox hbox = new HBox();
// 用于设置每个节点的距离 单位为像素
hbox.setSpacing(15);
// 在布局窗口的四周添加空间 可以使用setPadding()方法 此方法将 Insets 类型的对象作为参数
// 此处统一设置为 15 像素
hbox.setPadding(new Insets(15));
// 创建四个将要放置在HBox中的节点
TextField textline = new TextField(); // 文本行节点
TextArea textfield = new TextArea(); // 文本域节点
Button btn1 = new Button("执行命令"); // 按钮一:执行命令按钮节点
Button btn2 = new Button("清空命令"); // 按钮二:清空命令按钮节点
// 每个面板包含一个列表用于容纳面板中的节点 可用getChildren 方法获取
// 此处调用 getChildren 方法 该方法返回面板中的节点列表
// 使用addAll() 方法把这四个控件节点添加到面板中。
hbox.getChildren().addAll(textline, textfield, btn1, btn2);
// 编写逻辑代码处也可以在Controller文件中编写本文直接在Main中编写了
// setOnAction()方法用于注册一个事件处理程序,就是设置一个按钮,在单击的时候会执行的动作
// EventHandler 是一个功能接口,只提供了一个方法是handle() 方法来处理按钮触发的动作
btn1.setOnAction(new EventHandler<ActionEvent>() {
@Override
// 重写handle方法 按钮一动作的整体思路就是:
// 创建一个textbox获取文本行中的内容
// 创建一个字符流缓冲区 调用Process类执行命令
// 然后循环读取出缓冲区的内容以字符串形式输出到文本域中
public void handle(ActionEvent event) {
// 使用getText()方法获取文本行里的内容
String text = textline.getText();
// 创建一个空的builder, 默认容量为16
StringBuilder stringbuilder = new StringBuilder();
try {
// 通过Process类 来调用系统命令 去执行获取的文本行中的内容
Process process = Runtime.getRuntime().exec(text);
// 创建一个字符流缓冲区中 并将字符流放置到字符流缓冲区中
BufferedReader bufferedReader = new BufferedReader(
// InputStreamReader()将字节流变为字符流
// getInputStream() 获取内容,转成数据输入流 是字节流
// 小知识:以 Stream 结尾的都是字节流,以 Reader 和 Writer 结尾的都是字符流。
// 字节流分三种:文件流 缓冲流 对象流
// 字符流分两种:转换流(本文使用的InputStreamReader) 缓冲字符流(本文使用的BufferedReader)
new InputStreamReader(process.getInputStream(), "GBK"));
// line为空
String line;
// readLine() 每次读取一行
while ((line=bufferedReader.readLine()) != null) {
// append()方法将其参数转换为字符串,然后将该字符串的字符追加到string builder中的字符序列
stringbuilder.append(line+"\n");
}
// 调用 setText 方法,并将要显示的文本作为字符串进行传递
textfield.setText(stringbuilder.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
});
btn2.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
// 清空数据的动作
textline.clear();
textfield.clear();
}
});
// 创建空的BorderPane布局
BorderPane root =new BorderPane();
// 在BorderPane布局中调用setTop方法将hbox布局放置在顶部 textfield也类似
root.setTop(hbox);
root.setCenter(textfield);
primaryStage.setTitle("命令执行小工具");
primaryStage.setScene(new Scene(root,600,400));
primaryStage.show();
}
}