提问者:小点点

JavaFX : 如何管理阶段的 z 索引


有没有办法管理多个阶段(彼此独立)的 z 索引排序。比如,假设有三个阶段 A、B

下面是我所期待的快速演示。我需要访问任何阶段(拖动或修改),但z顺序需要保持。非常感谢任何想法或帮助。

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import java.util.HashMap;
import java.util.Map;

public class StagesZOrdering_Demo extends Application {
    private Map<String, Stage> stages = new HashMap<>();

    @Override
    public void start(Stage stage) throws Exception {
        Button button1 = new Button("Back");
        button1.setOnAction(e -> openStage("Back"));

        Button button2 = new Button("Middle");
        button2.setOnAction(e -> openStage("Middle"));

        Button button3 = new Button("Front");
        button3.setOnAction(e -> openStage("Front"));

        VBox root = new VBox(button1, button2, button3);
        root.setAlignment(Pos.CENTER);
        root.setSpacing(10);
        Scene sc = new Scene(root, 200, 200);
        stage.setScene(sc);
        stage.show();
    }

    private void openStage(String title) {
        if (stages.get(title) != null) {
            stages.get(title).requestFocus();
        } else {
            Stage stg = new Stage();
            stg.setTitle(title);
            stg.setScene(new Scene(new StackPane(), 300, 300, Color.GRAY));
            stg.show();
            stg.setOnHidden(e -> stages.remove(title));
            stages.put(title, stg);
        }
    }

    public static void main(String... a) {
        Application.launch(a);
    }
}

共1个答案

匿名用户

下面的mcve演示了一旦从一个ROOT<code>MOUSE_EXITED_TARGET</code>事件触发,从后到前阶段的重新排序
这是一个简单但有限的解决方案:

import javafx.application.Application;
import javafx.event.Event;
import javafx.event.EventType;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class StagesZOrdering_Demo extends Application {

    public enum STAGES {BACK, MIDDLE, FRONT;}
    private final EnumMap<STAGES, Stage> stages = new EnumMap<>(STAGES.class);

    @Override
    public void start(Stage stage) throws Exception {

        VBox root = new VBox();
        for(STAGES s : STAGES.values()){
            Button button = new Button(s.name());
            button.setOnAction(e -> openStage(s));
            root.getChildren().add(button);
        }

        root.setAlignment(Pos.CENTER);
        root.setSpacing(10);
        Scene sc = new Scene(root, 200, 200);
        stage.setScene(sc);
        stage.show();
    }

    private void openStage(STAGES s) {
        if (stages.get(s) == null) {
            Stage stg = new Stage();
            stg.setTitle(s.name());
            stg.addEventHandler(EventType.ROOT, e->reOrder(e));
            stg.setScene(new Scene(new StackPane(), 300, 100, Color.GRAY));
            stg.show();
            stg.setOnHidden(e -> stages.remove(s));
            stages.put(s, stg);
        }
    }

    private void reOrder(Event e){
        if(! e.getEventType().getName().equals("MOUSE_EXITED_TARGET"))
            return;

        for(STAGES s : STAGES.values()){
            Stage stage = stages.get(s);
            if(stage != null) {
                stage.requestFocus();
            }
        }
    }

    public static void main(String... a) {
        Application.launch(a);
    }
}