基于: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
欢迎指正错误,本人新手