首页 > 编程语言 >JavaFX基础之组件讲解

JavaFX基础之组件讲解

时间:2025-01-08 18:11:40浏览次数:1  
标签:控件 JavaFX scene Scene 设置 讲解 组件 new Stage

@

目录

1 JavaFX 组件

1.1 Application

ApplicationJavaFX 程序的入口,任何JavaFx应用程序程序都要继承该类并重写start()方法。

public class Main extends javafx.application.Application {
    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
    }
}

通过main()执行Application的launch(String… args)方法,当然该方法不传入任何值也是可以执行的。launch()方法会默认执行本类下的init()start()stop()方法。

注意:线程方面,执行main()方法时是主线程,当调用init()方法时是JavaFX-Launcher线程,当调用start()方法时是JavaFX Application Thread线程,当调用stop()方法时依然是JavaFX Application Thread线程。因此,可以在init()方法中做一些连接数据库等初始化工作,可与start()方法的不同线程同步进行,提高运行效率。
执行下面的main()方法后显示顺序为:

import javafx.application.Application;
import javafx.stage.Stage;

public class Main extends Application {
    public static void main(String[] args) {
        launch(args);
        System.out.println("这是main方法");
    }

    @Override
    public void init() {
        System.out.println("这是初始化方法");
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.show();
        System.out.println("这是start()方法");
    }

    @Override
    public void stop() throws Exception {
        System.out.println("这个是stop()方法");
    }
}

可以看出只有当stop()方法被调用时(即Application应用程序被正常关闭,也可以是图形界面右上角的❌被点击时),launch()方法才执行完毕。(通过Platform.exit()退出界面也是属于正常退出)
通过IDE控制台终止应用程序属于非正常终止,它是通过关闭JVM从而关闭应用程序的。

也可以在其他类中的main()方法中调用launch()方法,但要传入相应的参数,第一个参数指定一个Application的子类,从而调用该类下的init()、start()、stop()方法,第二个参数制定一个String类型的值。
该方法launch(Class<? extends Application> appClass, String… args)也可以不指定String类型的值。

1.2 Stage舞台(窗口)

JavaFX Stagejavafx.stage.Stage表示 JavaFX 桌面应用程序中的窗口。在JavaFX中,窗口Stage可以插入一个场景Scene,它表示在窗口内显示的内容。
JavaFX 应用程序启动时,它会创建一个根 Stage 对象,该对象将传递给 start(Stage primaryStage) JavaFX 应用程序的根类的方法。此 Stage 对象代表JavaFx应用程序的主窗口。可以在应用程序生命周期的后期创建新Stage对象,以防应用程序需要打开更多窗口。

1.2.1 创建舞台

像创建任何其他Java对象一样创建Stage对象:Stage stage = new Stage();

1.2.2 展示舞台

简单地创建Stage对象不会显示它,为了使Stage可见,必须调用它的show()showAndWait()方法:

Stage stage = new Stage();
stage.show();

1.2.3 在舞台上设置场景

JavaFX在Stage中显示任何场景内容,必须在Stage显示前将Scene创建,并设置在Stage中:

VBox VBox = new VBox(new Label("A JavaFx Label"));
Scene scene = new Scene(vBox);

Stage stage = new Stage();
stage.setScene(scene);
// ...
// stage.show();

1.2.4 舞台标题

通过setTitle()方法设置Stage标题,将显示在Stage窗口的标题栏中:stage.setTitle("JavaFx stage window Title");

1.2.5 舞台位置

通过其setX()setY()方法设置窗口左上角的位置(X, Y),即启动后窗口在屏幕中的坐标:

stage.setX(100);
stage.setY(100);

注意:如果设置X和Y位置,可能还需要设置宽度高度,否则舞台窗口可能会变得非常小。

1.2.6 舞台宽度和高度

通过其setWidth()和setHeight()方法,设置JavaFx的宽度和高度:

stage.setWidth(600);
stage.setHeight(300);

一般我们不需要单独设置舞台宽高,只需通过场景的宽高设置来影响舞台的宽高。

1.2.7 舞台风格

通过其 initStyle() 方法,参数为枚举类StageStyle设置JavaFX的样式,可以选择一组不同的样式:

  • DECORATED:默认装饰Stage是带有操作系统装饰(标题栏和最小化/最大化/关闭按钮)和白色背景的标准窗口。
  • UNDECORATED:未装饰Stage是没有操作系统装饰的标准窗口,但仍具有白色背景。
  • TRANSPARENT:透明Stage是具有透明背景的未装饰窗口。
  • UNIFIED:统一Stage就像一个装饰的舞台,只是装饰区域和主要内容区域之间没有边界。
  • UTILITY:实用程序Stage是装饰过的窗口,但装饰最少。

1.2.8 舞台全屏模式

通过其 setFullScreen() 方法将窗口设置为全屏模式:stage.setFullScreen(true);

1.2.9 阶段生命周期事件

Stage可以发出一些可以监听的事件,这些舞台事件是:Close RequestHiding HiddenShowingShown

关闭阶段事件监听器,可以在舞台上侦听关闭事件,当用户单击舞台窗口右上角的关闭按钮时,触发回调事件。
如需要在主Stage窗口关闭后清理一些资源、停止一些线程等。监听Stage关闭事件会很有用:
stage.setOnCloseRequest(event -> System.out.println("closing stage"));

1.2.10 键盘或鼠标事件

可以在 Stage上设置侦听键盘事件,可以捕获在舞台具有焦点时发生的所有键盘事件。

stage.addEventHandler(KeyEvent.KEY_PRESSED, e -> System.out.println("键盘按下的键:" + e.getCode().getName()));
stage.addEventHandler(MouseEvent.MOUSE_PRESSED, e -> System.out.println("鼠标按下的键:" + e.getButton()));

示例:

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyEvent;
import javafx.stage.Stage;

import java.io.FileInputStream;

public class Main extends Application {
    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setTitle("WASD控制图片移动");
        stage.getIcons().add(new Image("images/测试图片.png"));
        FileInputStream input = new FileInputStream("src/resources/images/测试图片.png");
        Image image = new Image(input);
        ImageView imageview = new ImageView(image);
        imageview.setFitWidth(100);
        imageview.setFitHeight(100);

        Group group = new Group(imageview);
        Scene scene = new Scene(group, 600, 600);
        stage.setScene(scene);

        stage.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
            if ("W".equals(event.getCode().getName())) {
                imageview.setLayoutY(imageview.getLayoutY() - 10);
            }
            if ("S".equals(event.getCode().getName())) {
                imageview.setLayoutY(imageview.getLayoutY() + 10);
            }
            if ("A".equals(event.getCode().getName())) {
                imageview.setLayoutX(imageview.getLayoutX() - 10);
            }
            if ("D".equals(event.getCode().getName())) {
                imageview.setLayoutX(imageview.getLayoutX() + 10);
            }
        });

        stage.show();
    }
}

1.3 Scene场景

场景对象是场景图的根。换句话说,场景包含其中的所有可视的GUI组件。场景由类表示javafx.scene.Scene。必须在Stage上设置Scene对象才能可见。
场景图是一种树状数据结构,用于排列(和分组)图形对象,以便于逻辑表示。它还允许图形引擎通过完全或部分跳过最终图像中看不到的对象,以最有效的方式渲染对象。下图显示了JavaFX场景图体系结构的一个示例:
在这里插入图片描述

1.3.1 创建场景

Scene您可以通过其构造函数创建对象。需要传递根组件作为参数,下面是创建Scene对象的示例:

VBox vBox = new VBox();
Scene scene = new Scene(vBox);

1.3.2 在舞台上设置场景

为了使Scene可见,必须在Stage上设置它:

VBox vBox = new VBox(new Label("A JavaFx Label"));
Scene scene = new Scene(vBox);

Stage stage = new Stage();
stage.setScene(scene);

注意Stage一次只能显示一个Scene

1.3.3 场景鼠标光标

可以在Scene上设置鼠标光标。鼠标光标是显示在鼠标光标(指针)位置的小图标。可以通过setCursor()方法设置鼠标的光标。

小案例:设置两个场景,通过按钮绑定事件,实现场景和鼠标光标的互相转换:

public class Main extends Application {
    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        Button button0 = new Button("点击切换场景");
        button0.setLayoutX(200);
        button0.setLayoutY(200);
        AnchorPane root = new AnchorPane();
        root.getChildren().add(button0);
        Scene scene = new Scene(root, 500, 500);
        scene.setCursor(new ImageCursor(new Image("images/测试图片1.png")));

        Label label = new Label("你好,JavaFx");
        label.setLayoutX(200);
        label.setLayoutY(200);
        Button button1 = new Button("返回原场景");
        button1.setLayoutX(200);
        button1.setLayoutY(250);
        AnchorPane root1 = new AnchorPane();
        root1.getChildren().addAll(label, button1);
        Scene scene1 = new Scene(root1, 500, 500);
        scene1.setCursor(new ImageCursor(new Image("images/测试图片2.png")));

        button0.setOnAction(event -> {
            primaryStage.setScene(scene1);
        });

        button1.setOnAction(event -> {
            primaryStage.setScene(scene);
        });

        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

1.4 Node节点 UI控件的通用属性

Node类是所有控件的父类,下面通过其控件子类示例演示Node节点的UI控件的通用属性。

1.4.1 控件节点坐标系

每个 JavaFX 节点都有自己的笛卡尔坐标系。与常规笛卡尔坐标系的唯一区别是Y轴是相反的。也就是说,坐标系的原点在坐标系的左上角。随着Y值的增加,该点从坐标系的顶部向下移动。Y轴的这种反转在2D图形坐标系中是正常的。

JavaFX 节点可能具有负X和Y坐标。
每个节点都有自己的坐标系。此坐标系用于在父节点内定位子节点实例,或者在 JavaFX 画布上绘图时。这意味着,作为另一个节点的子节点的节点都有自己的坐标系,以及在其父节点坐标系中的位置 (X,Y)。
以下是父节点坐标系的示例,其中子节点位于父节点坐标系中的(25,25)处。子节点也有它自己的坐标系,它有它的 (0,0),其中子节点位于父坐标系中-意思是在父节点坐标系中的(25,25)。
在这里插入图片描述

1.4.2 设置控件坐标

Label label = new Label("你好,JavaFx");
label.setLayoutX(200);  // 设置控件X轴坐标
label.setLayoutY(200);  // 设置控件Y轴坐标

1.4.3 设置控件风格

css语法类似,只是前面加上-fx,设置红色背景,蓝色边框和边框宽度为3个像素:

label.setStyle("-fx-background-color: red; -fx-border-color: blue; -fx-border-width: 3px"); // 设置控件风格,与css语法类似,只是前面加上-fx

1.4.4 设置控件首要背景宽度和高度

label.setPrefWidth(200);    // 设置控件背景宽度
label.setPrefHeight(50);    // 设置控件背景高度

1.4.5 设置文本居中

label.setAlignment(Pos.CENTER); // 设置文本居中

1.4.6 设置是否显示/隐藏该控件

true:默认显示控件,false:隐藏控件

label.setVisible(false);    // 是否显示该控件

1.4.7 设置控件半透明值

label.setOpacity(0.5);  // 设置控件半透明值

1.4.8 设置控件旋转角度

label.setRotate(70);    // 设置控件旋转角度

1.4.9 设置控件X轴和Y轴平移量

label.setTranslateX(60);    // 设置X轴平移量
label.setTranslateY(100);   // 设置Y轴平移量

案例演示:

public class Main extends Application {
    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        Label label = new Label("你好,JavaFx");
        label.setLayoutX(200);  // 设置控件X轴坐标
        label.setLayoutY(200);  // 设置控件Y轴坐标
        label.setStyle("-fx-background-color: red; -fx-border-color: blue; -fx-border-width: 3px"); // 设置控件风格,与css语法类似,只是前面加上-fx
        label.setPrefWidth(200);    // 设置控件背景宽度
        label.setPrefHeight(50);    // 设置控件背景高度
        label.setAlignment(Pos.CENTER); // 设置文本居中
        //label.setVisible(false);    // 是否显示该控件
        label.setOpacity(0.5);  // 设置控件半透明值
        label.setRotate(70);    // 设置控件旋转角度
        label.setTranslateX(60);    // 设置X轴平移量
        label.setTranslateY(100);   // 设置Y轴平移量
        AnchorPane root = new AnchorPane();
        root.getChildren().add(label);
        Scene scene = new Scene(root, 500, 500);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

1.5 UI控件的属性绑定和属性监听

小案例:在场景中画一个圆,利用属性单向绑定,使拖动边框大小时,圆始终保持在中心位置。并且设置X轴属性监听器,使得横向拖动边框时,控制台打印移动数据值,而Y轴不设置属性监听,纵向拖动时不打印数据值。

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class Main extends Application {
    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        AnchorPane root = new AnchorPane();
        Scene scene = new Scene(root, 500, 500);

        Circle circle = new Circle();
        circle.setCenterX(250);
        circle.setCenterY(250);
        circle.setRadius(100);
        circle.setStroke(Color.BLACK);
        circle.setFill(Color.WHITE);
        // 设置属性单向绑定,使圆始终保持在中心位置
        circle.centerXProperty().bind(scene.widthProperty().divide(2));
        circle.centerYProperty().bind(scene.heightProperty().divide(2));

        // 设置X轴属性监听器
        circle.centerXProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                System.out.println("x轴中心点改变了,原来是:" + oldValue + ",现在是:" + newValue);
            }
        });

        root.getChildren().add(circle);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

1.6 JavaFX应用里的事件驱动编程

小案例:利用事件驱动,实现将一个任意文件拖拽到文本框中后,拖拽时显示移动,拖拽松开后文本框显示文件的绝对路径。

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

public class Main extends Application {
    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        AnchorPane root = new AnchorPane();
        Scene scene = new Scene(root, 500, 500);
        TextField textField = new TextField();  // 文本框
        textField.setLayoutX(150);
        textField.setLayoutY(200);

        textField.setOnDragOver(event -> {
            event.acceptTransferModes(TransferMode.ANY);
        });

        textField.setOnDragDropped(event -> {
            Dragboard dragboard = event.getDragboard();
            if (dragboard.hasFiles()) {
                String path = dragboard.getFiles().get(0).getAbsolutePath();
                textField.setText(path);
            }
        });
        root.getChildren().add(textField);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

1.7 Color、Font、Image

1.7.1 Color颜色

案例演示:利用Color类设置圆的边框颜色和内部填充颜色

public class Main extends Application {
    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        AnchorPane root = new AnchorPane();
        Scene scene = new Scene(root, 500, 500);

        Circle circle = new Circle();
        circle.setCenterX(250); // 设置圆心X轴位置
        circle.setCenterY(250); // 设置圆心Y轴位置
        circle.setRadius(100);  // 设置半径
        //circle.setFill(Color.rgb(100, 50, 100));    // 设置内部填充颜色
        circle.setFill(Color.web("#f66a08"));   // 设置内部填充颜色,与CSS颜色语法一样
        circle.setStroke(Color.BLUE);  // 设置描边颜色
        circle.setStrokeWidth(10);    // 设置圆边框宽度

        root.getChildren().add(circle);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

1.7.2 Font字体

win系统在 C:\Windows\Fonts下可查阅系统字体
在这里插入图片描述
案例演示:为Label标签设置Font字体风格

public class Main12 extends Application {
    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        AnchorPane root = new AnchorPane();
        Scene scene = new Scene(root, 500, 500);

        Label label = new Label("文本Font演示");
        label.setLayoutX(150);
        label.setLayoutY(150);
        //label.setFont(new Font(30));  // 设置字体
        label.setFont(Font.font("华文行楷", FontWeight.BOLD, 30));   // 参数:字体名称,字重(斜体,黑体,粗体等),字体大小


        root.getChildren().add(label);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

1.7.3 Image图片

Image图片支持BMP/GIF/JPEG/PNG

案例演示:通过Image和ImageView类显示图片

public class Main13 extends Application {
    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        AnchorPane root = new AnchorPane();
        Scene scene = new Scene(root, 500, 500);

        ImageView imageView = new ImageView();
        Image image = new Image("images/背景.png");
        imageView.setImage(image);

        root.getChildren().add(imageView);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

参考连接:https://blog.csdn.net/weixin_52152676/article/details/138005850

标签:控件,JavaFX,scene,Scene,设置,讲解,组件,new,Stage
From: https://www.cnblogs.com/jingzh/p/18660298

相关文章

  • JavaFX基础之环境配置,架构,FXML
    目录1JavaFX1.1简介1.2环境准备1.2.1手动管理依赖1.2.2maven或Gradle管理1.3JavaFX架构1.3.1JavaFX架构图1.3.2JavaFX组件1.3.2.1舞台1.3.2.2场景1.3.2.3控件1.3.2.4布局1.3.2.5图表1.3.2.62D图形1.3.2.73D图形1.3.2.8声音1.3.2.9视频1.4简单使用1.5FXML1.5.......
  • asp.net程序设计2675企业管理信息系统【源码+讲解视频】
    项目包含:源码、参考论文、讲解视频、说明文档,部署录像开发环境开发工具:VisualStudio2010或以上版本数据库:SQLServer2005或以上版本开发语言:c#操作系统:windows7或以上浏览器:GoogleChrome(推荐)、Edge、360浏览器随着电信技术和计算机技术的飞速发展,现代管理信息......
  • 十六、Vue 组件
    文章目录一、组件的概念和优势二、创建组件全局组件的定义和注册局部组件的定义和注册三、组件通信父子组件通信父组件向子组件传递数据子组件向父组件传递事件非父子组件通信事件总线(EventBus)的使用Vuex(简单介绍用于状态管理,在组件通信中的应用)......
  • Kubernetes 组件中的证书作用与使用方法
    Kubernetes组件中的证书作用与使用方法Kubernetes(K8s)是一个容器编排平台,在云原生架构中广泛应用。在Kubernetes中,证书是保证集群安全通信的关键组成部分。每个组件间的相互通信都依赖于证书来验证身份和加密数据。本文将介绍Kubernetes中各个核心组件的证书作用和使用......
  • halcon组件匹配
    组件匹配需要创建多个ROI来分别对应每个组件,同时需要比较多的训练图片尽可能识别组件间不同的相对位置关系。 *创建多个ROI生成组件gen_rectangle2(InitialComponents,265,138,-0.02,23,13)gen_rectangle2(InitialComponent,342,286,-0.02,168,13)concat_obj(I......
  • 最牛逼的关于SpringBootJpa批量写入的问题讲解
    SpringBootjpa默认批量写入性能很差分析很多人认为是一条sql一条sql执行的问题,故而改为了insertintotablevalues(),()一条sql执行多条数据插入,当然这样没有问题,也是常用的解决办法;但本质上是事务控制的问题,默认save,或者saveAll(本质也是save),一个save就是一条sql的i......
  • Vue.js组件开发-如何动态更改图表类型
    Vue.js组件开发中,动态更改图表类型通常涉及到更新图表库的配置并重新渲染图表。如果使用的是ECharts,可以通过修改图表配置中的type属性来实现,并调用setOption方法来应用更改。示例:展示如何在Vue.js组件中动态更改ECharts图表类型:<template><div><divref="chart"st......
  • 【静态网页模板源码】000061 响应式深绿灰白企业模板组件网站-响应式(附源码)
    前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦......
  • nuxt3 父子组件通信有哪些方式
    在Nuxt3中,父子组件之间的通信方式和Vue3是一样的。父子组件通信的方式主要有以下几种:1.使用Props和Events(父子组件)这是Vue的基本通信方式,适用于父组件向子组件传递数据,或者子组件向父组件发送消息。父组件传递数据给子组件(Props)父组件通过props向子组件传递......
  • 基于java的SpringBoot/SSM+Vue+uniapp的工贸学生信息管理系统的详细设计和实现(源码+l
    文章目录前言详细视频演示具体实现截图技术栈后端框架SpringBoot前端框架Vue持久层框架MyBaitsPlus系统测试系统测试目的系统功能测试系统测试结论为什么选择我代码参考数据库参考源码获取前言......