javaFX自定义标题栏(含自定义表单tableView)

news/2025/3/4 23:36:05/

基于:openjfx 17.0.2    openJDK 17.0.1    idea    win10  scene builder 2.0

使用fxml制作ui

必须定义AnchorPane,他的作用就是让嵌入其中的元件固定在此(相对上级元素的)位置。AnchorPane此时在BorderPane的Top位置,用于自定义标题栏。

关键点:Hbox右边距设置为0,但是不能点击左边据设置框!如图:

表单tableView有个关键选项,用来自动填充满,均匀分布列:  

完整代码 

fxml部分

<?xml version="1.0" encoding="UTF-8"?><?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?><BorderPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.demo4.HelloController"><top><AnchorPane prefHeight="36.0" prefWidth="200.0" BorderPane.alignment="CENTER"><children><Label prefHeight="36.0" prefWidth="60.0" text="自定义标题栏" AnchorPane.leftAnchor="0.0" /><HBox prefHeight="36.0" prefWidth="180.0" AnchorPane.rightAnchor="0.0"><children><Button fx:id="windowMinButton" mnemonicParsing="false" onMouseClicked="#windowMin" prefWidth="60.0" text="min" /><Button fx:id="windowMaxButton" mnemonicParsing="false" onMouseClicked="#windowMax" prefWidth="60.0" text="max" /><Button fx:id="windowCloseButton" mnemonicParsing="false" onMouseClicked="#windowClose" prefWidth="60.0" text="close" /></children></HBox></children></AnchorPane></top><center><TableView fx:id="tableView" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER"><columns><TableColumn fx:id="name" prefWidth="75.0" text="name" /><TableColumn fx:id="age" prefWidth="75.0" text="age" /><TableColumn fx:id="button" prefWidth="75.0" text="button" /></columns><columnResizePolicy><TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /></columnResizePolicy></TableView></center><bottom><Button fx:id="addTableView" mnemonicParsing="false" onMouseClicked="#addTableView" text="addTableView" BorderPane.alignment="CENTER" /></bottom>
</BorderPane>

控制器部分

java">package com.example.demo4;import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.geometry.Rectangle2D;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.MouseEvent;
import javafx.stage.Screen;
import javafx.stage.Stage;public class HelloController {@FXMLprivate TableColumn<Person, Void> button;@FXMLprivate Button windowMinButton;@FXMLprivate Button windowMaxButton;@FXMLprivate TableColumn<Person, String> name;@FXMLprivate TableView<Person> tableView;@FXMLprivate Button windowCloseButton;@FXMLprivate TableColumn<Person, Number> age;@FXMLvoid windowMin(MouseEvent event) {Stage stage = (Stage) windowMinButton.getScene().getWindow();stage.setIconified(true);}// 最大化/还原窗口(注意:这里没有直接的“最大化”方法,需要手动管理状态)private boolean isMaximized = false; // 用于跟踪窗口是否最大化@FXMLvoid windowMax(MouseEvent event) {Stage stage = (Stage) windowMaxButton.getScene().getWindow();Screen screen = Screen.getPrimary();Rectangle2D bounds = screen.getVisualBounds();if (isMaximized) {// 还原窗口到之前的大小,并移动到屏幕中心double width = 600; // 假设之前的宽度是600double height = 400; // 假设之前的高度是400stage.setWidth(width); stage.setHeight(height); stage.setX((bounds.getWidth() - width) / 2);stage.setY((bounds.getHeight() - height) / 2);isMaximized = false;} else {// 记录当前大小double x = stage.getX();double y = stage.getY();double width = stage.getWidth();double height = stage.getHeight();// 最大化窗口到屏幕大小Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds();stage.setX(screenBounds.getMinX());stage.setY(screenBounds.getMinY());stage.setWidth(screenBounds.getWidth());stage.setHeight(screenBounds.getHeight());// 存储最大化状态isMaximized = true;}}@FXMLvoid windowClose(MouseEvent event) {Stage stage = (Stage) windowCloseButton.getScene().getWindow();stage.close();}public void addTableView(MouseEvent mouseEvent) {// 设置列的单元格值工厂,其中的id以及name是Person类中的字段名。name.setCellValueFactory(new PropertyValueFactory<>("name"));age.setCellValueFactory(new PropertyValueFactory<>("age"));// 自定义单元格工厂button.setCellFactory(param -> {TableCell<Person, Void> cell = new TableCell<>() {private final Button button = new Button("Delete");@Overridepublic void updateItem(Void item, boolean empty) {super.updateItem(item, empty);if (empty) {setGraphic(null);} else {setGraphic(button);// 处理按钮点击事件,这里是删除按钮所在行button.setOnAction(event -> {ObservableList<Person> items = getTableView().getItems();int index = getIndex();if (index >= 0) {items.remove(index);}});}}};return cell;});// 创建一些数据ObservableList<Person> data = FXCollections.observableArrayList(new Person("Alice", 1),new Person("Bob", 2),new Person("Charlie", 3));// 将数据设置到TableView中tableView.setItems(data);}
}

application主程序部分

java">package com.example.demo4;import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.StageStyle;import java.io.IOException;public class HelloApplication extends Application {double OffsetX, OffsetY;@Overridepublic void start(Stage stage) throws IOException {FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));Scene scene = new Scene(fxmlLoader.load(), 600, 400);// 定义拖动窗口scene.setOnMousePressed(event -> {OffsetX = event.getSceneX();OffsetY = event.getSceneY();});//鼠标拖动窗口scene.setOnMouseDragged(event -> {stage.setX(event.getScreenX() - OffsetX);stage.setY(event.getScreenY() - OffsetY);});// 去掉窗口标题、最小化、最大化和关闭按钮以及窗口边框stage.initStyle(StageStyle.UNDECORATED);stage.setScene(scene);stage.show();}public static void main(String[] args) {launch();}
}

用到的Person类部分

java">package com.example.demo4;import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;public class Person {// 最好定义成finalprivate final StringProperty name;private final IntegerProperty age;public Person(String name, int age) {this.name = new SimpleStringProperty(name);this.age = new SimpleIntegerProperty(age);}// 不能删除getAge和getName,否则报错public int getAge() {return age.get();}public String getName() {return name.get();}
}

代码参考资料:CSDN  AI

欢迎指正错误,本人新手 


http://www.ppmy.cn/news/1576669.html

相关文章

JAVA毕设项目-基于SSM框架的ssm数据结构学习网(vue)源码+设计文档

文末获取源码数据库文档 感兴趣的可以先收藏&#xff0c;有毕设问题&#xff0c;项目以及论文撰写等问题都可以和博主沟通&#xff0c;尽最大努力帮助更多的人&#xff01; 目 录 目 录 摘 要 abstract 第1章 绪论 1.1开发背景 1.2开发意义 1.3研究内容 1.4主…

ZooKeeper分布式协调框架

ZooKeeper分布式协调框架 学会ZooKeeper的基本使用&#xff1a;命令行、Java编程理解ZooKeeper watcher监听器工作原理&#xff1a;注册、监听事件、回调函数&#xff08;考点&#xff09;能独立描述出ZooKeeper选举过程&#xff08;难点、考点&#xff09;理解、并讲述客户端从…

【leetcode hot 100 76】最小覆盖子串

解法一&#xff1a;&#xff08;滑动窗口&#xff09;在 s 上滑动窗口&#xff0c;通过移动 r 指针不断扩张窗口。当窗口包含 t 全部所需的字符后&#xff0c;如果能收缩&#xff0c;我们就收缩窗口直到得到最小窗口。 class Solution {// <字母, 出现的次数>Map<Cha…

【实战篇】【深度解析DeepSeek:从机器学习到深度学习的全场景落地指南】

一、机器学习模型:DeepSeek的降维打击 1.1 监督学习与无监督学习的"左右互搏" 监督学习就像学霸刷题——给标注数据(参考答案)训练模型。DeepSeek在信贷风控场景中,用逻辑回归模型分析百万级用户数据,通过特征工程挖掘出"凌晨3点频繁申请贷款"这类魔…

广义线性模型下的数据分析(R语言)

一、实验目的&#xff1a; 通过上机试验&#xff0c;掌握利用R实现线性回归分析、逻辑回归、列联分析及方差分析&#xff0c;并能对分析结果进行解读。 数据&#xff1a; 链接: https://pan.baidu.com/s/1JqZ_KbZJEk-pqSUWKwOFEw 提取码: hxts 二、实验内容&#xff1a; 1、2…

Python PDF文件拆分-详解

目录 使用工具 将PDF按页数拆分 将PDF的每一页拆分为单独的文件 将PDF按指定页数拆分 根据页码范围拆分PDF 根据指定内容拆分PDF 将PDF的一页拆分为多页 在日常生活中&#xff0c;我们常常会遇到大型的PDF文件&#xff0c;这些文件可能难以发送、管理和查阅。将PDF拆分成…

【Java 基础(人话版)】Java 虚拟机(JVM)

引言 学习 Java 时&#xff0c;我们经常听到 “一次编译&#xff0c;随处运行” 这句话。这背后的核心支撑技术就是 Java 虚拟机&#xff08;JVM, Java Virtual Machine&#xff09;。JVM 负责运行 Java 代码&#xff0c;使得 Java 具有良好的跨平台能力。 但你知道吗&#x…

DeepSeek vs Grok vs ChatGPT:大模型三强争霸,谁将引领AI未来?

DeepSeek vs. Grok vs. ChatGPT&#xff1a;大模型三强争霸&#xff0c;谁将引领AI未来&#xff1f; 在人工智能领域&#xff0c;生成式模型的竞争已进入白热化阶段。DeepSeek、Grok和ChatGPT作为三大代表性工具&#xff0c;凭借独特的技术路径和应用优势&#xff0c;正在重塑…