首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaFX -更改FlowPane中子级的顺序

JavaFX -更改FlowPane中子级的顺序
EN

Stack Overflow用户
提问于 2013-09-06 22:07:20
回答 1查看 5.1K关注 0票数 5

我有一个JavaFX 2.2 FlowPane,并希望它的孩子是改变他们的订单,按需。

我发现

代码语言:javascript
复制
Collections.sort( getChildren(), new Comparator(){...} );

导致异常

代码语言:javascript
复制
java.lang.IllegalArgumentException: Children: duplicate children added: parent = ...

我还尝试使用子节点toFront()方法进行排序(如这里所建议的如何在JavaFX中改变儿童的顺序),但这似乎不影响列表顺序。

还有什么是我可以尝试的,或者是场景图中的孩子们在他们的订单上是不可变的?

EN

回答 1

Stack Overflow用户

发布于 2013-09-06 22:49:20

更新: Errata

由于JavaFX 2.x中有一个错误,这个答案的示例解决方案将无法在JavaFX 2.x中工作。感谢assylias识别了JavaFX 2.x错误:

当我运行您的程序时,列表不会更新,直到我水平地调整窗口大小(垂直不做任何事情)-JDK7u25/Windows7 x64。

这个bug在Java 8中是固定的,所以如果您使用Java 8,这个示例解决方案就能工作。

解决策略

  1. 根据流窗格子元素创建一个新集合。
  2. 对新的收藏进行排序。
  3. 将流窗格的子元素设置为已排序集合的内容。

代码片段

代码语言:javascript
复制
ObservableList<Node> workingCollection = FXCollections.observableArrayList(
    flow.getChildren()
);

Collections.sort(workingCollection, new NodeComparator());

flow.getChildren().setAll(workingCollection);

样本输出

排序前的样本输出:

排序后的样本输出:

示例应用程序

代码语言:javascript
复制
import javafx.application.Application;
import javafx.collections.*;
import javafx.event.*;
import javafx.geometry.Pos;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;

import java.util.*;

public class FlowGo extends Application {
    private final ObservableList<Label> labels = FXCollections.observableArrayList(
        createLabel("oranges"),
        createLabel("apples"),
        createLabel("pears"),
        createLabel("peaches"),
        createLabel("bananas")
    );

    @Override public void start(Stage stage) {
        FlowPane flow = createFlow();

        VBox layout = new VBox(10);
        layout.getChildren().setAll(
            flow,
            createActionButtons(flow)
        );
        layout.setAlignment(Pos.CENTER);
        layout.setStyle("-fx-padding: 10px; -fx-background-color: cornsilk;");

        stage.setScene(new Scene(layout));
        stage.show();
    }

    private HBox createActionButtons(final FlowPane flow) {
        Button sort = new Button("Sort");
        sort.setOnAction(new EventHandler<ActionEvent>() {
            @Override public void handle(ActionEvent actionEvent) {
                ObservableList<Node> workingCollection = FXCollections.observableArrayList(
                    flow.getChildren()
                );

                Collections.sort(workingCollection, new NodeComparator());

                flow.getChildren().setAll(workingCollection);
            }
        });

        Button reset = new Button("Reset");
        reset.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent actionEvent) {
                flow.getChildren().setAll(labels);
            }
        });

        HBox buttonBar = new HBox(10);
        buttonBar.getChildren().addAll(
            sort,
            reset
        );
        buttonBar.setAlignment(Pos.CENTER);

        return buttonBar;
    }

    private FlowPane createFlow() {
        FlowPane flow = new FlowPane();
        flow.setHgap(10);
        flow.setVgap(10);
        flow.getChildren().setAll(labels);
        flow.setAlignment(Pos.CENTER);
        flow.setStyle("-fx-padding: 10px; -fx-background-color: lightblue; -fx-font-size: 16px;");

        return flow;
    }

    private Label createLabel(String text) {
        Label label = new Label(text);
        label.setUserData(text);

        return label;
    }

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

    private static class NodeComparator implements Comparator<Node> {
        @Override
        public int compare(Node o1, Node o2) {
            String s1 = (String) o1.getUserData();
            String s2 = (String) o2.getUserData();

            return s1.compareTo(s2);
        }
    }
}
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18667297

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档