JavaFX与FXML中如何绑定VBox子节点实现按钮按fx:id动态重排序
实现方法
完全可以实现,先提两个前置注意点:
- 你当前FXML里
fx:id="1"这类数字开头的写法不符合规范,fx:id必须是合法Java标识符,不能以数字开头,建议改成btn1、btn2这类格式,否则FXML加载阶段就会抛错。 - 普通
ArrayList没有变更通知能力,要做到列表顺序变更自动同步UI,必须用JavaFX自带的可观察列表ObservableList。
具体实现步骤
- 先修改FXML:给VBox加上
fx:id方便控制器注入,同时修正按钮的fx:id命名,如果你不想逐个注入按钮,也可以给每个Button同步设置和fx:id一致的普通id属性(CSS用的id属性,加载后可以直接通过节点getId()拿到)。
示例修改后的VBox片段:
<VBox fx:id="buttonContainer" prefHeight="200.0" prefWidth="100.0" GridPane.columnIndex="1"> <children> <Button fx:id="btn1" id="btn1" mnemonicParsing="false" prefHeight="72.0" prefWidth="350.0" text="1" /> <Button fx:id="btn2" id="btn2" mnemonicParsing="false" prefHeight="72.0" prefWidth="350.0" text="2" /> <Button fx:id="btn3" id="btn3" mnemonicParsing="false" prefHeight="72.0" prefWidth="350.0" text="3" /> <Button fx:id="btn4" id="btn4" mnemonicParsing="false" prefHeight="72.0" prefWidth="350.0" text="4" /> <Button fx:id="btn5" id="btn5" mnemonicParsing="false" prefHeight="72.0" prefWidth="350.0" text="5" /> <Button fx:id="btn6" id="btn6" mnemonicParsing="false" prefHeight="72.0" prefWidth="350.0" text="6" /> <Button fx:id="btn7" id="btn7" mnemonicParsing="false" prefHeight="72.0" prefWidth="350.0" text="7" /> </children> </VBox>
- 控制器里编写绑定逻辑:
import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.layout.VBox; import java.util.HashMap; import java.util.Map; public class YourController { @FXML private VBox buttonContainer; // 存储排序后的id序列,所有对顺序的修改都操作这个列表 private final ObservableList<String> sortedIds = FXCollections.observableArrayList(); @FXML public void initialize() { // 构建id到按钮实例的映射,不用逐个@FXML注入按钮 Map<String, Button> id2ButtonMap = new HashMap<>(); for (Node child : buttonContainer.getChildren()) { if (child instanceof Button btn) { id2ButtonMap.put(btn.getId(), btn); } } // 给列表添加变更监听器,列表任何增删、排序、元素替换操作都会触发UI重排 sortedIds.addListener((ListChangeListener<String>) change -> { buttonContainer.getChildren().clear(); for (String btnId : sortedIds) { Button targetBtn = id2ButtonMap.get(btnId); if (targetBtn != null) { buttonContainer.getChildren().add(targetBtn); } } }); // 初始化默认顺序 sortedIds.addAll("btn1", "btn2", "btn3", "btn4", "btn5", "btn6", "btn7"); } }
使用方式
后续你只要修改sortedIds列表的内容/顺序,比如调用排序、插入、删除、替换元素的方法,VBox内的按钮都会自动按最新的id序列重排,不需要手动刷新UI。
举个触发重排的例子:
// 倒序排列按钮 FXCollections.sort(sortedIds, (a,b) -> b.compareTo(a));
内容的提问来源于stack exchange,提问作者Catalina
相关产品推荐
相关产品推荐

