文章目录
1.1 JAVA GUI演变
JAVA语言主要使用的GUI类存在一个演变过程
- AWT(抽象窗体工具包):最初作为主要的GUI类,但AWT并不适合开发综合的GUI项目。
- Swing:以AWT为基础的应用程序用户界面,具有丰富、灵活的功能和模块化组件。
- JavaFX:具有结构化代码、重用性和封装性,便于开发富因特网应用(RIA)。
1.2 JavaFX特点
- 融入了现代GUI技术以方便开发富因特网(RIA),可以表现一般桌面应用具有的特点与功能。
- 可以灵活地在桌面或者Web浏览器中切换运行。
- JavaFX为支持触摸的设备提供多点触控支持,如平板和智能手机。
- JavaFX具有内建的2D、3D、动画支持,以及视频和音频的回放功能。
1.3 初始窗口
Application.launch(MyJavaFX.class);
launch方法是一个定义在 Application 类中的 静态方法,用于启动一个独立的 JavaFX 应用。
Button btOK=new Button("Click me");
实例化按钮对象 参数字符串是按钮上的内容
Scene scene=new Scene(btOK,500,500);
构成场景 指定了场景的宽度和高度并且将节点对象放置在该场景中。
也可以不指定场景的宽度与高度进行创建 JavaFX会由场景内容自动给定场景大小。
public void start(Stage primaryStage) {}
当—个JavaFX 应用启动时, JVM使用它的无参构造方法来创建类的一个实例,同时调用其start 方法。
start 方法一般用于将 UI 组件放入一个场景,并且在舞台中显示该场景,此时对start()方法进行了重写 。
primaryStage.setTitle("MyJavaFX");
为舞台修改名称(标题)
primaryStage.setScene(scene);
将场景scene设定在舞台primaryStage内
primaryStage.show();
显示舞台
舞台(Stage) 节点(node) 场景(Scene) :
示例代码:
//显示一个占据整个场景的"Click me"按钮
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
public class MyJavaFX_oneOK extends Application {
@Override
public void start(Stage primaryStage) {
Button btClick=new Button("Click me");
Scene scene=new Scene(btClick,500,500);
primaryStage.setTitle("MyJavaFX");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
运行效果:
1.4 窗口多开
根据需要 可以创建更多舞台
每个舞台都是独立的窗口
示例代码:
//窗口双开
package com.FXbasics;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
public class MyJavaFX_twostage extends Application {
@Override//建立两个舞台
public void start(Stage primaryStage){
Button btOK=new Button("ok");
Scene scene=new Scene(btOK,250,250);
primaryStage.setTitle("first");
primaryStage.setScene(scene);
primaryStage.show();
Stage stage=new Stage();
stage.setTitle("second");
stage.setScene(new Scene(new Button("No"),250,250));
stage.show();
stage.setResizable(false);
primaryStage.setResizable(false);
}
public static void main(String[] args) {
Application.launch(args);
}
}
运行效果:
新建场景与按钮没有那么死板 在场景放置于舞台的过程中 也可以新建场景
甚至可以多层嵌套新建
stage.setScene(new Scene(new Button("No"),250,250));
该行代码在放置场景时新建场景并在场景中新建节点
默认情况下,用户可以拖动窗口边线以改变舞台的大小。
如要防止用户改变舞台大小,调用 stage.setResizable(false)
stage.setResizable(false);
primaryStage.setResizable(false);
1.5 部件组成
场景内可以包含UI组件与面板 但是不能直接包含形状与图像视图
面板可以包含节点的任何子类型(面板本身也是节点子类型的一种)
Node的每个子类都有一个无参的构造方法,用于创建一个默认的节点。
1.6 部件居中
在我们之前写过的几个程序中,
都是由一个button按钮,占据了整个场景与舞台。
无论我们如何调整窗口大小,按钮都会自动适应。
在此处我们学习:将该按钮限制在面板中 再将面板放置在场景中心
从而达到按钮限制在中心的目的
示例代码:
/*尝试将单个按钮放置在面板上显示*/
package com.FXbasics;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class MyJavaFX_ButtonInpane extends Application {
@Override
public void start(Stage primaryStage){
//创建一个场景并将按钮放置在其中的面板上(不覆盖整个窗口)
StackPane pane=new StackPane();
//创建堆栈面板对象 实例化为pane
Button btOK=new Button("OK");
//创建按钮对象 实例化为btOK
pane.getChildren().add(btOK);
//将按钮节点(node)添加到该堆栈面板上
Scene scene=new Scene(pane,200,100);
//创建宽度200 高度100的场景
primaryStage.setTitle("ButtonInPane");
//修改舞台的名称为ButtonInPane
primaryStage.setScene(scene);
//将场景scene放置在舞台primaryStage中
primaryStage.show();
//显示舞台
}
public static void main(String[] args) {
launch(args);
//运行应用程序
}
}
运行效果:
1.7 描绘颜色
圆的大小:
- 当窗口大小改变时,圆的位置是不会随之改变的,不像前文中的按钮会进行适应。
- 它的圆心与半径均为固定值,这意味着该圆在窗口中是不会改变的。
- 将窗口拖拽到足够小,是可以遮盖该圆的。
Java图形的尺寸单位都是“像素”
circle.setStroke (Color.RED)
设置画笔颜色(图像的边框)
circle.setFill (Color .BLUE)
对图形的填充颜色
将颜色设置为“null”则是无色(注意与white区分)
1.8 坐标轴
左上角为(0,0) x轴正半轴向右 y轴正半轴向下。
1.9 属性绑定
- 此处是将圆心的x坐标与y坐标与面板的width/2以及height/2进行了属性绑定。
- 将一个目标对象绑定到源对象中,源对象的修改将自动反映到目标对象中。
- 如果源对象中的值改变了,目标对象也将自动改变。
- 目标对象称为绑定对象或者绑定属性
- 源对象称为可绑定对象或者可观察对象
示例代码:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class MyJavaFX_CenterCircle extends Application {
@Override
public void start(Stage primaryStage){
Pane pane=new Pane();
Circle circle=new Circle();
circle.centerXProperty().bind(pane.widthProperty().divide(2));
//x坐标与面板的width/2绑定
circle.centerYProperty().bind(pane.heightProperty().divide(2));
//y坐标与面板的height/2绑定
circle.setRadius(100);
circle.setStyle(
"-fx-Stroke:black;-fx-fill:red;");
pane.getChildren().add(circle);
Scene scene =new Scene(pane,400,400);
primaryStage.setScene(scene);//放置场景
primaryStage.setTitle("ShowCenterCircle");
primaryStage.show();
}
public void main(String[] args){
launch(args);
}
}
运行效果:
注意属性/数值的区别:
Java中的基本类型与字符串类型都可以作为绑定属性,对于每一个绑定属性,都拥有返回值,修改值及返回该属性对象的三种方法。
例如:对于圆心x来说
- getCenter X() 称为值的获取方法
- setCenterX() 称为值的设置方法
- centerXProperty() 称为属性获取方法
1.10 样式设置
抽象类Node定义了许多对于节点而言通用的属性和方法。
JavaFX 的样式属性类似于Web 页面中指定 HTML 元素样式的层叠样式表( CSS)
因此, JavaFX 的样式属性称为 JavaFX CSS
基本的设置方式 如:
circle.setStyle( "-fx-Stroke:black;-fx-fill:red;");
-
对各个样式使用前缀-fx-进行定义 在具体样式后使用“:”并添加具体的样式属性
-
每个节点拥有它自己的样式属性
-
设定样式:styleName:value
-
一个节点的多个样式属性可以一起设置,通过分号;进行分隔。
-
该行代码将圆对象实例的笔划颜色与填充颜色进行了设定
如果使用了一个不正确的 JavaFX CSS, 程序依然可以编译和运行,但是样式将被忽略。
不会进行报错也不会中断程序,但该行代码无效,如同不存在。
1.11 旋转按钮
button.setRotate(double value)
- 设定旋转角度(单位为度)
- 围绕图形中心旋转
- Value>0则表示顺时针
在如下代码中使用样式设置及旋转按钮的方法
示例代码:
import javafx.application.Application;//父类
import javafx.scene.Scene;//场景
import javafx.scene.control.Button;//按钮
import javafx.stage.Stage;//舞台
import javafx.scene.layout.StackPane;//堆栈面板
public class MyJavaFX_NodeRotate extends Application{
@Override
public void start(Stage primaryStage){
StackPane pane=new StackPane();
Button ok=new Button("OK");
ok.setStyle("-fx-color:white;-fx-txt:red");
pane.setRotate(45);
pane.getChildren().add(ok);
pane.setStyle("-fx-border-color:black;-fx-background-color:red;");
Scene scene=new Scene(pane,200,100);
primaryStage.setTitle("NodeRotate");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args){
Application.launch(args);
}
}
运行效果:
1.12 色彩空间
Javafx.scene.paint.Color是Paint的具体子类
用于封装颜色信息
可以通过以下构造方法构建颜色实例:
public Color (double r, double g , double b, double opacity);
- 称为 RGBA 模型
- 其中 RGB 分别表示红色、绿色、蓝色,其值从 0 (最深色)到1(最浅色)。
- A表示alpha值
- 定义了一个颜色的透明度,从 0.0 (完全透明)到 1.0 (完全不透明)
- Color类是不可更改的 当一个Color对象创建后 它的属性不能再修改
可以使用上述方式进行颜色的构建,或是使用Color类中内建的标准颜色
BLUE BROWN CYAN DARKGRAY GOLD....
1.13 字体信息
Font类描述字体名、粗细和大小
可以在渲染文字的时候设置字体信息。
描述一类字体需要四类信息
Font.font(("Times NewROMAN"),FontWeight.BOLD,FontPosture.ITALIC,20)
(字体名字,字体粗细,字体形态以及字体的大小)
-
均存在默认值 未提供的信息便使用默认值
-
可以通过调用静态方法 getFamilies() 获得一个可用的字体系列名字列表
-
System.out.println(Font.getFamilies());
-
字体形态是两个常量:FontPosture.ITALIC(斜体) 和FontPosture.REGULAR
-
Font对象是不可改变的
示例代码:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.*;
import javafx.scene.control.*;
public class MyJavaFX_FontDemo extends Application {
@Override
public void start(Stage primaryStage){
Pane pane=new StackPane();
Circle circle=new Circle();
circle.setRadius(50);
circle.setStroke(Color.BLACK);
/*circle.setFill(new Color(0.5,0.5,0.5,1));*/
circle.setFill(Color.PINK);
pane.getChildren().add(circle);
Label label=new Label("JavaFx");
label.setFont(Font.font(("Courier"),FontWeight.BLACK,20));
pane.getChildren().add(label);
Scene scene=new Scene(pane,200,200);
primaryStage.setTitle("FontDemo");
primaryStage.setScene(scene);
primaryStage.show();
System.out.println(Font.getFamilies());
}
public static void main(String[] args){
launch(args);
}
}
运行效果:
1.14 载入图片
Image类表示一个图像,ImageView类可以用于显示一个图像。
后接图像文件可以是URL地址或是本地路径
//先创建Image对象 再利用该对象作为参数创建ImageView
Image image = new Image("image/us.gif ") ;
ImageView imageView = new ImageView(image);
也可以直接从一个本地路径或者一个URL来创建ImageView
ImageView imageView = new ImageView("image/us.gif");
示例代码:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.layout.Pane;
import javafx.scene.layout.HBox;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
public class MyJavaFX_ShowImage extends Application{
@Override
public void start(Stage primarystage){
Pane pane=new HBox(10);
pane.setPadding(new Insets(10,10,10,10));
Image image=new Image("file:/C:/users/yt/Desktop/1.jpg");
ImageView imageView1=new ImageView(image);
pane.getChildren().add(imageView1);
ImageView imageView2=new ImageView(image);
pane.getChildren().add(imageView2);
imageView2.setFitHeight(200);
imageView2.setFitWidth(100);
ImageView imageView3=new ImageView(image);
pane.getChildren().add(imageView3);
imageView3.setRotate(180);
Scene scene=new Scene(pane);
primarystage.setTitle("ShowImage");
primarystage.setScene(scene);
primarystage.show();
}
}
运行效果:
1.16 布局面板
JavaFX提供了多种类型的面板,用于自动地将节点布局在希望的位置和大小。
类 | 描述 |
---|---|
Pane | 布局面板的基类 |
StackPane | 节点放置在中央 并叠加在其他节点之上 |
FlowPane | 依次流式放置 |
Gridpane | 网格布局 |
BorderPane | 方位放置 |
HBox | 水平放置 |
VBox | 垂直放置 |
整体对齐方式 默认是左对齐 Pos.LEFT
面板中的方向(默认:Orientation.HORIZONTAL 即水平排列)
节点之间的水平间隔与垂直间隔默认为0 (它是double类型的值)
getChildren( )是实例方法,它能够返回某一面板中的节点列表
- 可以使用add(node)方法将一个元素加到列表中
- 或是使用addAll(node1,nide2,…)来添加一系列的节点到面板中
- 同样 可以使用 remove(Node)来从列表中移除一个节点
- 或者使用 removeAll() 方法将面板中的所有节点移除
1.17 FlowPane
FlowPane 该类面板将节点按照加入的词序 从左到右或者从上到下垂直组织
当一行或者一列排满的时候 开始新的一行或者一列。
如果修改窗体大小,节点将自适应进行重新组织。
示例代码:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
public class MyJavaFX_ShowFlowPane extends Application {
@Override
public void start(Stage PrimaryStage) {
Label Firstname = new Label("First name:");
Label MI = new Label("MI:");
FlowPane pane = new FlowPane(Orientation.HORIZONTAL, 5, 5);
pane.setPadding(new Insets(10, 12, 13, 14));
pane.getChildren().addAll(Firstname,new TextField(),MI);
TextField textField = new TextField();
textField.setPrefColumnCount(1);
pane.getChildren().addAll(textField, new Label("Last Name:"), new TextField());
Scene scene = new Scene(pane, 320, 100);
PrimaryStage.setTitle("ShowFlowPane");
PrimaryStage.setScene(scene);
PrimaryStage.show();
System.out.println(pane.getChildren());
}
public static void main(String[] args) {
launch(args);
}
}
运行效果:
窄窗体时:
宽窗体时:
1.18 GridPane
很直观的布局方式,如二维表格一般放置节点
存在行索引与列索引 索引自0开始
示例代码:
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class MyJavaFX_ShowGridPane extends Application {
@Override
public void start(Stage primaryStage){
GridPane pane=new GridPane();//创建网格面板
pane.setAlignment(Pos.CENTER);//设置该面板中内容的整体对齐方式 “居中”
pane.setPadding(new Insets(11.5,12.5,13.5,14.5));//设定边框
pane.setHgap(0);//节点间的横向距离
pane.setVgap(5.5);//节点间的纵向距离
pane.setGridLinesVisible(true);//网格线是否可视化
pane.add(new Label("First Name:"),0,0);//将First Name:文本放置在第一行第一列(1,1)
pane.add(new TextField(),1,0);//将文本框放置在第一行第二列(1,2)
pane.add(new Label("MI:"),0,1);//将MI:文本放置在第二行第一列(2,1)
pane.add(new TextField(),1,1);//将文本框放置在第二行第二列(2,2)
pane.add(new Label("Last Name:"),0,2);//将Last Name:文本放置在第三行第一列(3,1)
pane.add(new TextField(),1,2);//将文本框放置在第三行第二列(3,2)
Button btAdd=new Button("Add Name");//新建按钮btAdd 其名称为Add Name
pane.add(btAdd,1,3);//将该按钮添加到第四行第二列(4,2)
GridPane.setHalignment(btAdd, HPos.LEFT);//将面板中的btAdd按钮 设置为右对齐(某节点的水平对齐方式 但被限制在网格内)
Scene scene=new Scene(pane);//将面板放入场景中
primaryStage.setTitle("ShowGridPane");//将舞台名称修改为ShowGridPane
primaryStage.setScene(scene);//场景放置在舞台上
primaryStage.show();//显示舞台
}
}
运行效果: