第六站:Java橙——JavaFX的动感舞台

JavaFX入门案例:创建一个基础UI应用

JavaFX允许开发者使用Java语言来设计和实现富客户端应用程序,这些应用程序具有高度互动的用户界面(UI),支持2D和3D图形,以及媒体播放等特性。下面,我们将通过一个简单的案例来展示如何使用JavaFX创建一个基本的UI应用,包括UI设计、构建场景图、以及事件处理的基本概念。

准备工作

确保你的开发环境已经配置好了JavaFX库。如果你使用的是IntelliJ IDEA或Eclipse,可以通过安装相应的JavaFX插件来简化配置过程。

示例目标

创建一个简单的应用程序,包含一个按钮,当用户点击按钮时,会在控制台打印一条消息,并改变按钮上的文字。

步骤1: 创建JavaFX项目

首先,创建一个新的Java项目,并确保JavaFX库已正确导入。

步骤2: 编写主类

在项目中创建一个主类,比如叫做JavaFXDemo.java,并编写以下代码:

java 复制代码
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class JavaFXDemo extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        // 创建按钮
        Button btn = new Button();
        btn.setText("点击我!");

        // 设置按钮的事件处理器
        btn.setOnAction(event -> {
            System.out.println("按钮被点击了!");
            btn.setText("已被点击");
        });

        // 创建场景图的根节点
        StackPane root = new StackPane();
        root.getChildren().add(btn);

        // 创建场景
        Scene scene = new Scene(root, 300, 250);

        // 设置舞台
        primaryStage.setTitle("JavaFX Hello World");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}
代码解析
  • Application类是JavaFX程序的入口点,通过重写其start方法来定义应用程序的启动逻辑。
  • Button是JavaFX中的一个UI控件,用于创建按钮。
  • StackPane是一个布局容器,它将所有子节点堆叠在一起,最后一个添加的节点位于最顶层。在这个例子中,我们使用它作为场景图的根节点。
  • Scene代表UI的一个可视部分,包含所有的UI元素(由StackPane根节点及其子节点构成)。
  • setOnAction用于为按钮添加事件处理器,当按钮被点击时,会执行Lambda表达式定义的代码块,这里实现了打印消息和改变按钮文字的功能。
  • primaryStage是应用程序的主要窗口,通过setTitlesetSceneshow等方法设置窗口标题、内容和显示窗口。
运行程序

运行JavaFXDemo类,你将看到一个包含"点击我!"按钮的窗口。点击按钮后,控制台会输出"按钮被点击了!",同时按钮上的文字变为"已被点击"。

通过这个简单的案例,你已经初步了解了JavaFX中UI设计、场景图构建以及事件处理的基本概念。随着学习的深入,你可以探索更复杂的布局、动画效果、以及与用户的更多交互方式,从而在JavaFX的动感舞台上创造更加丰富和生动的应用程序。

JavaFX:添加文本输入和响应处理

在上一个简单示例的基础上,让我们进一步扩展我们的JavaFX应用,加入文本输入框(TextField)和标签(Label),实现一个基本的交互场景:用户在文本框中输入文本,点击按钮后,输入的内容会显示在标签上。这个示例将帮助你理解如何在JavaFX中添加更多UI元素并处理它们之间的交互。

修改主类代码

我们将对之前的JavaFXDemo.java类进行修改,增加文本输入框和标签,并调整事件处理逻辑。

java 复制代码
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class JavaFXDemoExtended extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        // 创建UI元素
        TextField textField = new TextField();
        textField.setPromptText("请输入文本...");
        
        Label displayLabel = new Label("显示区域");
        
        Button btn = new Button("显示输入");
        btn.setOnAction(this::handleDisplayButton);

        // 使用VBox布局管理器垂直堆叠元素
        VBox vbox = new VBox(10); // 10是子元素间的间距
        vbox.getChildren().addAll(textField, btn, displayLabel);

        // 创建场景
        Scene scene = new Scene(vbox, 400, 300);

        // 设置舞台
        primaryStage.setTitle("JavaFX 文本输入示例");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void handleDisplayButton(ActionEvent event) {
        // 获取文本框输入的文本
        String inputText = ((Button)event.getSource()).getScene().lookup("#inputField").toString();
        if (inputText != null && !inputText.isEmpty()) {
            // 显示在标签上,实际应使用getText()获取纯文本内容,此处仅为示例简化
            ((Label)((Button)event.getSource()).getScene().lookup("#displayLabel")).setText(inputText);
        }
    }
}
代码解析
  • 新增了TextField(文本输入框)和Label(标签)两个UI组件。
  • 使用VBox布局管理器替代原来的StackPane,以垂直排列方式展示各个组件,同时设置了组件间的间距。
  • 在按钮的事件处理器handleDisplayButton中,我们尝试从场景中查找ID为inputField的文本框(但直接使用toString()并不正确,正确做法是使用textField.getText()获取文本),然后将获取到的文本设置到ID为displayLabel的标签上。注意,在实际应用中,直接使用lookup按ID查找并不是最佳实践,特别是对于动态生成的组件,这里仅为了演示目的简化处理。
注意事项
  • 上述代码中直接使用lookup方法并通过.toString()获取文本是不准确的,正确做法是应该直接使用文本框的实例方法getText()来获取用户输入的文本。
  • 为了使lookup方法按ID查找有效,你需要为相关的UI组件设置ID。例如,textField.setId("inputField")displayLabel.setId("displayLabel"),但上述代码中遗漏了这一细节,请在实际应用中添加。

通过这个追加的案例,你学习了如何在JavaFX应用中添加文本输入处理,以及如何利用事件处理器来响应用户的不同操作,进一步加深了对JavaFX UI设计和交互处理的理解。

JavaFX:实现数据绑定与属性更改监听

在之前的基础上,我们将进一步提升应用的互动性,通过实现数据绑定(Data Binding)和属性更改监听(Property Change Listener),让界面元素自动同步更新。我们将创建一个简单的表单,包含两个TextField用于输入名字和年龄,当用户输入信息后,下方的Label会自动显示用户的简介信息,无需点击按钮。

修改后的主类代码
java 复制代码
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class JavaFXDataBindingDemo extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        // 创建UI元素
        TextField nameField = new TextField();
        TextField ageField = new TextField();

        // 使用StringProperty实现双向绑定
        StringProperty userInfo = new SimpleStringProperty();

        Label userInfoLabel = new Label();
        userInfoLabel.textProperty().bind(userInfo);

        // 设置布局
        VBox vbox = new VBox(10);
        vbox.setAlignment(Pos.CENTER);
        vbox.getChildren().addAll(
                new Label("姓名:"), nameField,
                new Label("年龄:"), ageField,
                new Label("用户信息:"),
                userInfoLabel
        );

        // 监听文本框变化,更新userInfo
        nameField.textProperty().addListener((observable, oldValue, newValue) -> {
            updateUserInfo(nameField.getText(), ageField.getText(), userInfo);
        });
        ageField.textProperty().addListener((observable, oldValue, newValue) -> {
            updateUserInfo(nameField.getText(), ageField.getText(), userInfo);
        });

        // 创建场景
        Scene scene = new Scene(vbox, 400, 300);

        // 设置舞台
        primaryStage.setTitle("JavaFX 数据绑定示例");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void updateUserInfo(String name, String age, StringProperty userInfo) {
        // 简单的逻辑,根据输入更新用户简介
        if (!name.isEmpty() && !age.isEmpty()) {
            userInfo.set("姓名: " + name + ", 年龄: " + age);
        } else {
            userInfo.set("请输入姓名和年龄");
        }
    }
}
代码解析
  • 引入了StringProperty,它是JavaFX属性包中的一个类,用于封装可观察的字符串值,支持数据绑定。
  • 创建了nameFieldageField两个文本输入框,并为这两个文本框的textProperty添加了监听器。当文本框内容发生变化时,触发updateUserInfo方法更新用户信息。
  • userInfoLabel的文本通过textProperty().bind(userInfo)userInfo属性绑定,实现了数据的自动同步。这意味着,当userInfo的值发生改变时,userInfoLabel显示的文本也会相应更新。
  • updateUserInfo方法用于根据输入的名字和年龄更新userInfo的值,从而间接更新界面上显示的用户信息。

通过此案例,你学习了如何在JavaFX应用中实现数据绑定和属性监听,使得UI组件能够自动反映数据模型的变化,提高了应用程序的交互性和用户体验。

JavaFX案例追加:实现列表选择与详情显示

在现有基础上,我们再为应用程序增加一些复杂度,通过添加一个可选择的项目列表(ListView)和一个显示选中项目详细信息的区域,进一步展示JavaFX在处理用户界面和数据交互方面的灵活性。

假设我们要创建一个简单的图书目录应用,其中有一个列表显示图书标题,当用户从列表中选择一本书时,旁边会显示该书的简介。

修改后的主类代码
java 复制代码
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class JavaFXListSelectionDemo extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        // 创建书籍数据模型
        ObservableList<Book> books = FXCollections.observableArrayList(
                new Book("Java编程思想", "Bruce Eckel", "深入Java编程的高级教程"),
                new Book("Effective Java", "Joshua Bloch", "提升Java程序员的有效实践"),
                new Book("Clean Code", "Robert C. Martin", "编写可读、可复用和可维护的代码")
        );

        // 创建UI元素
        ListView<Book> bookListView = new ListView<>(books);
        Label bookDetailsLabel = new Label("请选择一本书籍");

        // 当选中项变化时,更新详情显示
        bookListView.getSelectionModel().selectedItemProperty().addListener((obs, oldBook, newBook) -> {
            if (newBook != null) {
                bookDetailsLabel.setText(newBook.getDetails());
            } else {
                bookDetailsLabel.setText("请选择一本书籍");
            }
        });

        // 设置布局
        VBox vbox = new VBox(10);
        vbox.setAlignment(Pos.CENTER);
        vbox.getChildren().addAll(bookListView, bookDetailsLabel);

        // 创建场景
        Scene scene = new Scene(vbox, 600, 700);

        // 设置舞台
        primaryStage.setTitle("JavaFX 列表选择示例");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    // 图书类
    public static class Book {
        private final StringProperty title = new SimpleStringProperty();
        private final StringProperty author = new SimpleStringProperty();
        private final StringProperty details;

        public Book(String title, String author, String details) {
            this.title.set(title);
            this.author.set(author);
            this.details = new SimpleStringProperty(details);
        }

        public String getTitle() {
            return title.get();
        }

        public String getAuthor() {
            return author.get();
        }

        public String getDetails() {
            return title.get() + " by " + author.get();
        }
    }
}
代码解析
  • 定义了一个Book类,用于存储书籍的标题、作者和简介信息,每个属性都使用SimpleStringProperty以便于数据绑定和监听。
  • 创建了一个ObservableList<Book>来存储书籍对象,FXCollections.observableArrayList方法保证了列表中的元素变化可以被监听。
  • 使用ListView<Book>来展示书籍列表,并通过监听bookListView.getSelectionModel().selectedItemProperty()来检测选中项的变化。
  • 当用户从列表中选择一本书时,通过监听器自动更新旁边的bookDetailsLabel,显示选中书籍的详细信息。
  • 布局调整为VBox,以适应新增的列表视图和细节展示标签。

通过此案例,你不仅学习了如何在JavaFX中使用列表视图(ListView)和数据模型类,还掌握了如何监听和处理用户的选择事件,进一步提升了UI设计的互动性和实用性。

相关推荐
Yongqiang Cheng1 分钟前
Python operator.itemgetter(item) and operator.itemgetter(*items)
python·operator·itemgetter
小扳3 分钟前
Docker 篇-Docker 详细安装、了解和使用 Docker 核心功能(数据卷、自定义镜像 Dockerfile、网络)
运维·spring boot·后端·mysql·spring cloud·docker·容器
MavenTalk4 分钟前
Move开发语言在区块链的开发与应用
开发语言·python·rust·区块链·solidity·move
v'sir13 分钟前
POI word转pdf乱码问题处理
java·spring boot·后端·pdf·word
FksLiao16 分钟前
Superset安装
python
李少兄17 分钟前
解决Spring Boot整合Redis时的连接问题
spring boot·redis·后端
提高记忆力22 分钟前
SpringBoot整合FreeMarker生成word表格文件
java·spring
JDS_DIJ23 分钟前
RabbitMQ
java·rabbitmq·java-rabbitmq
L Jiawen24 分钟前
【Python · PyTorch】卷积神经网络(基础概念)
pytorch·python·cnn
goomind29 分钟前
深度学习模型评价指标介绍
人工智能·python·深度学习·计算机视觉