在JavaFX中,如何判断哪个阶段在另一个阶段的前面?

时间:2018-10-18 00:36:20

标签: javafx

我有一个JavaFX应用程序,其中有几个打开的阶段可提供浮动窗口。我想从头到尾遍历这些阶段。我有一个要排序的所有阶段的列表,正在寻找一种方法,可以让我比较两个阶段并确定哪个阶段在前面。有办法吗?

1 个答案:

答案 0 :(得分:2)

这只是一种可能性。

  1. 将每个打开的Stage存储在可以观察到的更改列表中。
  2. 在每个阶段的focusedProperty上添加一个侦听器。当它变为true时,
  3. 从我们的列表中删除该阶段,并在索引0处读取它
  4. 现在,在列表上创建一个侦听器,您的“焦点” Stage将始终位于索引0。

您现在有一个ArrayList,用于按顺序存储打开的阶段。

这是一个简单的MCVE演示。当然,还有一些地方需要改进,我欢迎提出建议,但这确实提供了一些基本功能。

OpenStages.java:

import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;

/**
 * Implementation of a SimpleListProperty that will store our ObservableArrayList
 */
public class OpenStages<Stage> extends SimpleListProperty<Stage> {

    /**
     * Constructor that creates an ObservableArrayList
     */
    public OpenStages() {
        super(FXCollections.observableArrayList());
    }

    /**
     * Removes this Stage from the list and re-adds it at index 0
     */
    public void focusStage(Stage stage) {
        this.remove(stage);
        this.add(0, stage);
    }
}

Main.java:

import javafx.application.Application;
import javafx.collections.ListChangeListener;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application {

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

    @Override
    public void start(Stage primaryStage) {
        // Custom SimpleListProperty that holds our ObservableArrayList of open stages
        OpenStages<Stage> openStages = new OpenStages<>();

        // Simple interface
        VBox root = new VBox(5);
        root.setPadding(new Insets(10));
        root.setAlignment(Pos.CENTER);

        Button btnCreateStage = new Button("Create New Stage");
        btnCreateStage.setOnAction(event -> {

            // Create a new Stage
            Stage newStage = new Stage();

            // Add a listener to the focusedProperty of the Stage. When focus changes to true, we
            // need to update our openStages list
            newStage.focusedProperty().addListener((observable, oldValue, newValue) -> {
                if (newValue) {
                    openStages.focusStage(newStage);
                }
            });

            // Add the stage to our OpenStages list.
            openStages.add(newStage);

            // Simple layout for the new Stage
            VBox stageRoot = new VBox();
            stageRoot.setPrefSize(300, 100);
            stageRoot.setPadding(new Insets(10));
            stageRoot.setAlignment(Pos.CENTER);

            // Let's add a label and title to indicate which Stage this is
            stageRoot.getChildren().add(new Label("Stage #" + openStages.size()));
            newStage.setTitle("Stage #" + openStages.size());

            newStage.setScene(new Scene(stageRoot));

            // Finally, let's show the stage
            newStage.show();

        });

        // Now, let's create a simple listener for our openStages list to print out the focused Stage
        openStages.addListener(new ListChangeListener<Stage>() {
            @Override
            public void onChanged(Change<? extends Stage> c) {
                // Only interested in a stage being added
                if (c.next() && c.wasAdded()) {
                    System.out.println("Focused stage: " + openStages.get(0).getTitle());
                }
            }
        });

        // Add the Button to our main layout
        root.getChildren().add(btnCreateStage);

        // Show the Stage
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
}