当前位置: 首页 > 知识库问答 >
问题:

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

沈单弓
2023-03-14
Collections.sort( getChildren(), new Comparator(){...} );
java.lang.IllegalArgumentException: Children: duplicate children added: parent = ...

还有什么我可以尝试的,或者在场景图中的孩子们是不变的,关于他们的顺序?

共有1个答案

晏永康
2023-03-14

更新:勘误表

由于JavaFX2.x中的一个bug,此答案的示例解决方案将无法在JavaFX2.x中工作。感谢assylias识别JavaFX2.x bug:

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

    null
ObservableList<Node> workingCollection = FXCollections.observableArrayList(
    flow.getChildren()
);

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

flow.getChildren().setAll(workingCollection);

样本输出

排序前的示例输出:

排序后的示例输出:

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);
        }
    }
}
 类似资料:
  • 主要内容:1- FlowPane布局,2- FlowPane示例,3- Scene Builder上的FlowPaneJavaFX FlowPane布局 1- FlowPane布局 是一个容器。它在一行上排列连续的子组件,并且如果当前行填满了以后,则自动将子组件向下推到下一行。 2- FlowPane示例 代码如下 - 运行示例,得到以下结果: 3- Scene Builder上的FlowPane 您可以使用JavaFX Scene Builder轻松设计界面。下图显示了使用Scane Buil

  • 我看到下面的链接-https://stackoverflow.com/questions/5302197/javafx-bug-is-there-a-way-to-force-repaint-this-not-a-single-threading-pr调用requestLayout似乎没有帮助。我还尝试在图中的各个节点上调用impl_updatePG和impl_transformsChanged。

  • 我正在寻找一种方法来更改Java堆栈中元素的顺序,以便偶数在奇数下。 例如:5, 2, 6, 7, 1, 4, 3 它变成这个5, 7, 1, 3, 2, 6, 4。 以下是我目前的代码,我被困在寻找如何改变订单: 谢谢你的帮助!

  • 我想做一些类似于下拉列表的事情,以便我的用户可以选择他们是想要gmail、hotmail还是outlook。然后,我希望按钮更新以显示他们的偏好。我必须只使用引导,因此不能使用 到目前为止,我已经尝试给他们所有相同的id,但是JS只使用了第一个,我不想给他们所有不同的id(太麻烦了)。所以我写的是使用子编号(类似于数组)并将值放入按钮。但是,我不知道如何找出当前html标记的位置号。请帮助我,提前

  • 我在这个问题上发现了一些类似的问题,但我想再问一遍,以便得到一个更明确的答案。我正在编写一个图匹配算法,其中图上的每个节点分配给一个优先级集,取决于其邻居的匹配。细节其实并不重要,但我使用了std::priority_queue以便首先匹配最高优先级的节点。这里有一个棘手的问题:每次引入一个新的匹配,匹配节点的邻居的优先级将被更新。 我的问题自然是,如何更新新匹配的顺序?我能强制执行吗?或者是否有

  • 我正在尝试使用重叠项目(类似轮播组件)实现ViewPager2。一切似乎都很好,但我的中心项目与下一个项目重叠。我希望我的中心物品位于任何相邻物品的前面。 见下图: 当你使用ViewPager1类时,我们可以覆盖getChildDrawingOrder。 请参见此处的示例解决方案:链接 但不能派生和扩展ViewPager2(因为ViewPager1类是最终类)。我该怎么办?