You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX如何基于模板动态创建节点 实现多条聊天消息的按需展示

解决方案

你现有单条消息的数据模型、单条消息控制器逻辑无需修改,仅需补充承载多条消息的主容器和动态加载逻辑即可,修改步骤如下:

1. 确认单条消息布局(Display.fxml)

你现有的Display.fxml为单条消息的布局,参考结构如下即可正常使用:

<?xml version="1.0" encoding="UTF-8"?>
<VBox xmlns:fx="http://javafx.com/fxml" spacing="3" prefWidth="400" style="-fx-background-color: #f0f0f0; -fx-padding: 8px; -fx-background-radius: 6px;">
    <Label fx:id="sender" style="-fx-font-weight: bold; -fx-font-size: 13px;"/>
    <Label fx:id="message" style="-fx-font-size: 14px;" wrapText="true"/>
</VBox>

2. 创建主界面承载布局

新建MainContainer.fxml作为主界面,用来承载所有消息节点:

<?xml version="1.0" encoding="UTF-8"?>
<ScrollPane xmlns:fx="http://javafx.com/fxml" fitToWidth="true">
    <VBox fx:id="messageContainer" spacing="10" style="-fx-padding: 15px;"/>
</ScrollPane>

3. 新增主界面控制器

新建MainController.java处理动态添加消息的逻辑:

package stackkoverflow.stackoverflow;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.VBox;
import java.io.IOException;
import java.util.List;

public class MainController {
    @FXML
    private VBox messageContainer;

    // 批量加载多条消息
    public void loadMessages(List<MessageNode> messageList) throws IOException {
        for (MessageNode msg : messageList) {
            // 每次加载单条消息需新建独立的FXMLLoader实例,不可复用
            FXMLLoader loader = new FXMLLoader(getClass().getResource("Display.fxml"));
            loader.setController(new MessageControler(msg));
            messageContainer.getChildren().add(loader.load());
        }
    }

    // 动态添加单条新消息,后续发送新消息直接调用该方法即可
    public void addSingleMessage(MessageNode newMsg) throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("Display.fxml"));
        loader.setController(new MessageControler(newMsg));
        messageContainer.getChildren().add(loader.load());
    }
}

4. 修改启动类代码

package stackkoverflow.stackoverflow;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
import java.util.List;

public class test extends Application {
    @Override
    public void start(Stage primaryStage) {
        // 构造测试消息列表
        List<MessageNode> testMessages = List.of(
                new MessageNode("user", "hello world"),
                new MessageNode("user", "hello world"),
                new MessageNode("user", "hello world"),
                new MessageNode("user", "hello world")
        );

        try {
            // 加载主界面
            FXMLLoader mainLoader = new FXMLLoader(getClass().getResource("MainContainer.fxml"));
            Scene scene = new Scene(mainLoader.load(), 500, 600);
            MainController mainController = mainLoader.getController();
            // 加载所有测试消息
            mainController.loadMessages(testMessages);

            primaryStage.setTitle("消息测试");
            primaryStage.setScene(scene);
            primaryStage.show();

            // 测试动态新增消息:3秒后自动添加一条新消息
            new Thread(() -> {
                try {
                    Thread.sleep(3000);
                    // JavaFX UI操作必须在FX主线程执行
                    javafx.application.Platform.runLater(() -> {
                        try {
                            mainController.addSingleMessage(new MessageNode("系统通知", "动态新增的消息"));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    });
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();

        }catch (IOException ie){
            ie.printStackTrace();
        }
    }

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

补充说明

  • 若消息量超过百条,建议替换为ListView组件实现,配合自定义ListCell加载单条消息,利用虚拟滚动机制减少内存占用,性能更流畅。
  • 所有节点操作必须放在JavaFX主线程执行,动态新增消息时不要直接在子线程执行节点添加逻辑,需用Platform.runLater()包装。

内容的提问来源于stack exchange,提问作者GoThirteenM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 18:27:00