25.4.20学习总结
如何使用listView组件来做聊天界面
1. 什么是CellFactory?
在JavaFX中,控件(比如ListView、TableView等)用Cell来显示每一条数据。
-
Cell:代表这个单元格(即每个列表项)中显示的内容和样式。 -
CellFactory:是一个工厂接口,负责创建和配置每个Cell。
简单来说,
CellFactory用于定义如何将数据对象(比如好友信息)转化为界面显示的单元格(Cell)。
2. 为什么要自定义CellFactory?
默认的Cell只显示数据的toString()方法的内容,
如果你需要自定义界面布局(比如显示头像、名字、状态指示等),
就需要自定义Cell,通过实现自己的CellFactory。
3. 如何自定义CellFactory?
-
自定义
CellFactory的步骤:-
调用
listView.setCellFactory(); -
在
call()中返回一个自定义的ListCell<T>; -
重写
updateItem(),设置每个单元格的内容。
-
详细的步骤:
1.创建一个消息属性类;
例如,以聊天室的聊天界面为例
import javafx.scene.image.Image;public class TextMessage {private final String content;private final int MessageType;private final String userName;private final Image profilePicture;private final boolean isSender;public TextMessage(String content, int MessageType, String userName, Image profilePicture, boolean isSender) {this.content = content;this.MessageType = MessageType;this.userName = userName;this.profilePicture = profilePicture;this.isSender = isSender;}public String getContent() {return content;}public int getMessageType() {return MessageType;}public String getUserName() {return userName;}public Image getProfilePicture() {return profilePicture;}public boolean getIsSender() {return isSender;}}
2.创建Cell类(稍后写详细代码)
其中,ListCell后跟着的是你创建的属性类。重写方法后,我们将在else里写具体代码。
public class ChatTextMessageCell extends ListCell<TextMessage> {@Overrideprotected void updateItem(TextMessage item, boolean empty) {super.updateItem(item, empty);if (empty || item == null) {setText(null);setGraphic(null);} else {}}
}
3.在控制器类里初始化
首先,在类里添加如下代码:
private ObservableList<TextMessage> messages;
其中,ObservableList是 JavaFX 中用于实现数据绑定的重要接口。它允许 UI 控件自动响应数据变化。
将你的listView组件声明一下,如下,
@FXML public ListView<TextMessage> chatList;
初始化方法(注意:以initialize为名的无参方法无论加不加注解都会在应用启动时执行):
@FXML public void initialize(){messages = FXCollections.observableArrayList();chatList.setItems(messages);chatList.setCellFactory(param -> new ChatTextMessageCell());}
4.具体写Cell类
注意:这个类对于初学者来说并不好写,可能需调整多次才能达到预期。
对于javaFX有过了解的知道,VBox和HBox的区别,我们将在下面可能频繁使用这两个容器。
我们需要聊天界面显示的每条消息由头像,昵称,发出的消息等组成,其中,头像位于最左端或者最右端,昵称和发出的消息共同组成上下结构位于头像的另一端。也就是说,根容器,是需要展示左右两端的,我们使用HBox作为根容器,如下:
HBox root = new HBox();
之后,我们分别声明头像的组件和另一端的容器,又因为另一端是上下结构,我们使用VBox作为容器。如下:
ImageView imageView = new ImageView(item.getProfilePicture());
VBox messageBox = new VBox();
之后,我们将两者放入根容器中,如下:
root.getChildren().addAll(imageView, messageBox);
之后便是相同的操作了,依次处理上下结构即可。
显然,这样的结果不符合要求,我们还行对组件进行设置。在这便需要各位查阅官方文档了。
记得在最后加上setGraphic(root);应用设置!!!
完整代码引用:
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Circle;public class ChatTextMessageCell extends ListCell<TextMessage> {@Overrideprotected void updateItem(TextMessage item, boolean empty) {super.updateItem(item, empty);if (empty || item == null) {setText(null);setGraphic(null);} else {HBox root = new HBox();if (item.getMessageType() == 1) {// 时间消息样式保持不变Label timeLabel = new Label(item.getContent());timeLabel.setStyle("-fx-font-size: 10px; -fx-text-fill: gray;");root.getChildren().add(timeLabel);root.setAlignment(Pos.CENTER);} else {// ================== 头像区域 ==================ImageView imageView = new ImageView(item.getProfilePicture());imageView.setFitHeight(40);imageView.setFitWidth(40);imageView.setPreserveRatio(false);imageView.setClip(new Circle(20, 20, 15));// ================== 消息内容区域 ==================VBox messageBox = new VBox();// 昵称标签(添加左外边距贴近头像)Label nameLabel = new Label(item.getUserName());nameLabel.setStyle("-fx-font-size: 12px; -fx-text-fill: #666; /*-fx-padding: 0 0 2px 8px;*/");// 消息气泡if(item.getMessageType()==2){HBox bubble = new HBox();bubble.setMaxWidth(200);bubble.setStyle("-fx-background-radius: 15px; " +"-fx-padding: 8px 12px; " +"-fx-background-color: " + (item.getIsSender() ? "#f5f5f5" : "#0099ff") + ";");// 消息文本Label messageLabel = new Label(item.getContent());messageLabel.setStyle("-fx-font-size: 14px; " +"-fx-text-fill: " + (item.getIsSender() ? "black" : "white") + ";");messageLabel.setWrapText(true);// ================== 布局组装 ==================bubble.getChildren().add(messageLabel);messageBox.getChildren().addAll(nameLabel, bubble);// 根容器设置root.setSpacing(5);if (item.getIsSender()) {messageBox.setAlignment(Pos.CENTER_LEFT);root.setAlignment(Pos.CENTER_LEFT);root.getChildren().addAll(imageView, messageBox);} else {messageBox.setAlignment(Pos.CENTER_RIGHT);root.setAlignment(Pos.CENTER_RIGHT);root.getChildren().addAll(messageBox, imageView);}}}setGraphic(root);}}
}
5.将listView的默认样式去除
在你的resources文件中,创建css文件,内容如下:
.list-view { /* 应用于整个ListView */-fx-background-color: WHITE; /* ListView 背景透明 */
}.list-cell {-fx-background-color: transparent; /* 单元格背景透明 */-fx-padding: 0; /* 移除默认内边距 */-fx-border: none; /* 移除边框 */-fx-focus-color: transparent; /* 移除焦点效果 */-fx-control-inner-background: transparent; /* 解决部分主题背景问题 */-fx-text-fill: black; /* 默认文本颜色,并保持 */
}.list-cell:hover {-fx-background-color: transparent; /* 悬停时透明 */
}.list-cell:selected {-fx-background-color: transparent; /* 选中时透明 */
}.list-cell:selected:focused {-fx-background-color: transparent; /* 选中并聚焦时透明 */
}.list-cell:pressed {-fx-background-color: transparent; /* 按下时透明 */
}
将此css文件导入即可。
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 900, 618);
// 加载 CSS 文件
scene.getStylesheets().add(Objects.requireNonNull(getClass().getResource("style.css")).toExternalForm());
相关文章:
25.4.20学习总结
如何使用listView组件来做聊天界面 1. 什么是CellFactory? 在JavaFX中,控件(比如ListView、TableView等)用Cell来显示每一条数据。 Cell:代表这个单元格(即每个列表项)中显示的内容和样式。 …...
Spring之我见 - Spring Boot Starter 自动装配原理
欢迎光临小站:致橡树 Spring Boot Starter 的核心设计理念是 约定优于配置,其核心实现基于 自动配置(Auto-Configuration) 和 条件化注册(Conditional Registration)。以下是其生效原理: 约定…...
如何高效利用呼叫中心系统和AI语音机器人
要更好地使用呼叫中心系统和语音机器人,需要结合两者的优势,实现自动化、智能化、高效率的客户服务与业务运营。以下是优化策略和具体实践方法: 一、呼叫中心系统优化 1. 智能路由与IVR优化 智能ACD(自动呼叫分配) …...
【Windows上配置Git环境】
在Windows上配置Git环境可以按照以下步骤进行: 1. 下载Git 打开浏览器,访问Git官方网站https://git-scm.com/downloads。在下载页面中,找到适用于Windows的下载链接,根据你的系统是32位还是64位选择相应的安装包进行下载 。 2.…...
OpenCV基础01-图像文件的读取与保存
介绍: OpenCV是 Open Souce C omputer V sion Library的简称。要使用OpenCV需要安装OpenCV包,使用前需要导入OpenCV模块 安装 命令 pip install opencv-python 导入 模块 import cv2 1. 图像的读取 import cv2 img cv2.imread(path, flag)这里的flag 是可选参数&…...
C 语言的未来:在变革中坚守与前行
C 语言,作为编程语言领域的一位 “老将”,自诞生以来就一直扮演着至关重要的角色。历经数十年的发展,它的影响力依然广泛而深远。在科技飞速发展的今天,新的编程语言如雨后春笋般不断涌现,C 语言的未来发展走向成为了众…...
go语言优雅关机和优雅重启笔记
一、优雅关机 生活化例子 餐馆关门:你去餐馆吃火锅,刚坐下点完菜(客户端发请求),餐馆老板突然接到通知要停电(收到关机指令)。老板很贴心,先停止接待新客人(停止接收新请…...
【算法】计数排序、桶排序、基数排序
算法系列八:非比较排序 一、计数排序 1.实现 1.1步骤 1.2代码 2.性质 2.1稳定性 2.1.1从前往后前始版: 2.1.2从后往前末始版: 2.2复杂度 2.2.1时间复杂度 2.2.2空间复杂度 二、桶排序 1.实现 1.1步骤 1.2代码 2.稳定性 三、…...
Halcon应用:相机标定
提示:若没有查找的算子,可以评论区留言,会尽快更新 Halcon应用:相机标定 前言一、Halcon应用?二、应用实战1、图像理解1.1、开始标定 前言 本篇博文主要用于记录学习Halcon中算子的应用场景,及其使用代码和…...
【C++ 程序设计】实战:C++ 实践练习题(31~40)
目录 31. 数列:s 1 + 2 + 3 + … + n 32. 数列:s 1 - 2 - 3 - … - n 33. 数列:s 1 + 2 - 3 + … - n 34. 数列:s 1 - 2 + 3 - … &#…...
【perf】perf工具的使用生成火焰图
文章目录 1. What is perf?2. perf使用2.1 perf的子工具集2.2 常用指令perf list指令格式参数perf中事件分类使用示例 perf stat指令格式参数 perf top指令格式参数交互式界面操作使用示例 perf record指令格式参数使用示例 perf report指令格式参数交互式界面操作使用示例 pe…...
绿幕抠图直播软件-蓝松抠图插件--使用相机直播,灯光需要怎么打?
使用SONY相机进行绿幕抠图直播时,灯光布置是关键,直接影响抠图效果和直播画质。以下是详细的灯光方案和注意事项: 一、绿幕灯光布置核心原则 均匀照明:绿幕表面光线需均匀,避免阴影和反光(亮度差控制在0.5…...
从外网访问局域网服务器的方法
一、为什么局域网的服务器无法在外网访问? 服务器、电脑之间靠IP地址寻址,目前大部分基于IPV4进行寻址访问。但是因为IPV4的地址数量有限,中国分到的还比较少,所以非常紧缺。 一个解决方案就是在局域网来建立一个内部的网…...
每日面试实录·携程·社招·JAVA
📍面试公司:携程 👜面试岗位:后端开发工程师(社招) 🕐面试时长:约 50 分钟 🔄面试轮次:第 1 轮技术面 ✨面试整体节奏: 这场携程的社招 Java 一面…...
Redis增删改查
### 进入redis控制台 redis-cli --raw #加上raw,防止中文乱码### 增 127.0.0.1:6379> LPUSH list0 "hello" #增加一个list 1 127.0.0.1:6379> LRANGE list0 0 -1 #查看list hello### 删 127.0.0.1:6379> DEL list0 #删除list 1 127.0.0.1:6379> LRANG…...
机器学习 Day12 集成学习简单介绍
1.集成学习概述 1.1. 什么是集成学习 集成学习是一种通过组合多个模型来提高预测性能的机器学习方法。它类似于: 超级个体 vs 弱者联盟 单个复杂模型(如9次多项式函数)可能能力过强但容易过拟合 组合多个简单模型(如一堆1次函数)可以增强能力而不易过拟合 集成…...
学习笔记十九——Rust多态
🧩 Rust 多态终极通俗指南 📚 目录导航 多态一句话概念静态分派 vs 动态分派——根本差异参数化多态(泛型) 3.1 函数里的泛型 3.2 结构体里的泛型 3.3 方法里的泛型 3.4 枚举里的泛型Ad hoc 多态(特例多态࿰…...
交换机与路由器的主要区别:深入分析其工作原理与应用场景
在现代网络架构中,交换机和路由器是两种至关重要的设备。它们在网络中扮演着不同的角色,但很多人对它们的工作原理和功能特性并不十分清楚。本文将深入分析交换机与路由器的主要区别,并探讨它们的工作原理和应用场景。 一、基本定义 1. 交换…...
【Oracle专栏】Oracle中的虚拟列
Oracle相关文档,希望互相学习,共同进步 风123456789~-CSDN博客 1.背景 在EXP方式导出时,发现 出现如下提示 EXP-00107: virtual column 不支持,因此采用expdp方式导出。于是本文针对oracle虚拟列进行简单介绍。 2. 相…...
2020 年 7 月大学英语四级考试真题(组合卷)——解析版
🏠个人主页:fo安方的博客✨ 💂个人简历:大家好,我是fo安方,目前中南大学MBA在读,也考取过HCIE Cloud Computing、CCIE Security、PMP、CISP、RHCE、CCNP RS、PEST 3等证书。🐳 &…...
大语言模型的训练、微调及压缩技术
The rock can talk — not interesting. The rock can read — that’s interesting. (石头能说话,不稀奇。稀奇的是石头能读懂。) ----硅谷知名创业孵化器 YC 的总裁 Gar Tan 目录 1. 什么是大语言模型? 2. 语言建模ÿ…...
NEAT 算法解决 Lunar Lander 问题:从理论到实践
NEAT 算法解决 Lunar Lander 问题:从理论到实践 0. 前言1. 定义环境2. 配置 NEAT3. 解决 Lunar lander 问题小结系列链接0. 前言 在使用 NEAT 解决强化学习问题一节所用的方法只适用于较简单的强化学习 (reinforcement learning, RL) 环境。在更复杂的环境中使用同样的进化解…...
firewall指令
大家好,今天我们继续来了解服务管理,来看看打开或关闭指定端口,那么话不多说,开始吧. 1.打开或者关闭指定端口 在真正的生产环境,往往需要防火墙,但问题来了,如果我们把防火墙打开,那么外部请求数据包就不能跟服务器监听通讯,这时,需要打开指定的端口,比如80,22,8080等. 2.fi…...
【MySQL】MySQL表的增删改查(CRUD) —— 上篇
目录 MySQL表的增删改查(CRUD) 1. 新增(Create)/插入数据 1.1 单行数据 全列插入 insert into 表名 values(值, 值......); 1.2 单行数据 指定列插入 1.3 多行数据 指定列插入 1.4 关于时间日期(datetime&am…...
STM32的三种启动方式
目录 一、从主闪存存储器启动(Main Flash Memory) 二、从系统存储器启动(System Memory) 三、从内置SRAM启动(Embedded SRAM) 一、从主闪存存储器启动(Main Flash Memory) >&g…...
软考高级系统架构设计师-第15章 知识产权与标准化
【本章学习建议】 根据考试大纲,本章主要考查系统架构设计师单选题,预计考3分左右,较为简单。 15.1 标准化基础知识 1. 标准的分类 分类 内容 国际标准(IS) 国际标准化组织(ISO)、国际电工…...
Spring Boot 整合 DeepSeek 实现AI对话 (保姆及教程)
文章目录 文章目录 前言 一、创建 spring boot 工程 二、申请key 三、修改配置文件 application.properties 四、编写控制器(controller) 五、运行调试 前言 提示:随着人工智能的不断发展,ai这门技术也越来越重要,很多…...
Java File 类详解
Java File 类详解 File 类是 Java 中用于表示文件和目录路径名的抽象类,位于 java.io 包中。它提供了丰富的 API,用于操作文件系统,包括创建、删除、重命名、查询文件属性等功能。 1. File 类核心知识点 (1)构造方法…...
通过特定协议拉起 electron 应用
在 Android 通过 sheme 协议可以拉起其他应用。 electron 应用也可以通过类似特定协议被拉起。 在同时有 web、客户端的应用里,可以通过这种方式在 web 拉起客户端。 支持拉起客户端 const PROTOCOL xxxif (process.defaultApp) {// 这里是开发环境,有…...
前端与传统接口的桥梁:JSONP解决方案
1.JSONP原理 1.1.动态脚本注入 说明:通过创建 <script> 标签绕过浏览器同源策略 1.2.回调约定 说明:服务端返回 函数名(JSON数据) 格式的JS代码 1.3.自动执行 说明:浏览器加载脚本后立即触发前端预定义的回调函数(现代开…...
