我有一个JavaFX 2.2 FlowPane,希望它的孩子可以按需更改其顺序。
我发现
Collections.sort( getChildren(), new Comparator(){...} );
导致异常
java.lang.IllegalArgumentException: Children: duplicate children added: parent = ...
我还尝试使用子节点Nodes toFront()方法进行排序(如此处How to change order of children in JavaFX所示),但这似乎并不影响列表顺序。
还有什么我可以尝试的,还是场景图中的孩子关于他们的顺序是不变的?
参考方案
更新:勘误表
由于JavaFX 2.x中的错误,此答案的示例解决方案在JavaFX 2.x中不起作用。感谢assylias识别JavaFX 2.x错误:
当我运行您的程序时,列表不会更新,除非我水平调整窗口大小(垂直不做任何事情)-jdk 7u25 / Windows 7 x64。
该错误已在Java 8中修复,因此,如果您使用Java 8,则示例解决方案将起作用。
解决方案策略
代码段
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);
}
}
}
JavaFX FXML无效类型 - java我正在Linux中用Eclipse编写JavaFX应用程序,并使用SceneBuilder编写了某些FXML代码。当我移至Windows时,如果我尝试执行代码,它将运行良好,但是,如果我尝试修改fxml文件,它将开始给我一个错误(与修改无关)。我也尝试使用NetBeans,但没有任何改变。错误是:javafx.fxml.LoadException: Ligh…
JavaFX DatePicker设置日期值的对齐方式 - java当我使用JavaFX的Datepicker并使用节点的整个宽度时,日期选择器的文本不会居中。我尝试使用setStyle("-fx-alignment: center;"),但这不起作用。我想要这样的东西(用油漆做):如何将文字居中?这是示例代码:import java.time.LocalDate; import javafx.appli…
JavaFX HBox HGrow优先级 - java我有一个包含javafx.scene.layout.HBox的JavaFX场景。此HBox包含两个孩子,一个javafx.scene.control.ComboBox后跟一个javafx.scene.control.Spinner。最小的FXML文件来说明我的问题是:<?import javafx.scene.control.ComboBox?>…
创建具有不同样式的大量文本-JavaFX FXML - java在JavaFx应用程序的fxml类中,我想使用最少的组件(而不是每行添加多个标签)来添加大量文本。我还想在同一组件中创建各种样式的文本。我应该使用哪个组件(例如TextArea),以及如何在其中创建多个样式(使用CSS)。 参考方案 使用TextFlow并向其中添加Text。您可以在各个Text组件上使用CSS为它们设置不同的样式。完整的例子:import …
JavaFX WebView URL.createObjectURL未定义 - java我正在使用JavaFX 8嵌入式WebView。我想从Blob图片构建Blob URL。但是,URL.createObjectURL给了我未定义的信息。在JavaFX 8 WebView环境中,是否有任何方法(匀场等)从Blob对象创建Blob URL? 参考方案 看来目前尚不支持它,但是Java 9将于9月发布。https://bugs.openjdk.j…