JavaFX:如何管理阶段的 z-index
Posted
技术标签:
【中文标题】JavaFX:如何管理阶段的 z-index【英文标题】:JavaFX : How to manage the z-index of stages 【发布时间】:2019-11-30 23:05:48 【问题描述】:有没有办法管理多个阶段的 z-index 排序(彼此独立)。例如,假设有 A、B 和 C 三个阶段。StageA 应该始终位于后面。 StageB 应位于中间,StageC 应始终位于顶部。只是特别注意这三个阶段彼此没有关系(如所有者)
下面是我所期待的快速演示。我需要访问任何阶段(用于拖动或修改),但需要维护 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);
【问题讨论】:
很确定 API 不允许开箱即用。唯一的机会是去当地的 JNA。据我所知,Windows(不确定其他操作系统)似乎也没有通过 DLL 直接从盒子中取出该功能,最近的事情是全局“始终在顶部”功能。 我认为最接近 Java 的方法是在List
中保持所需的阶段顺序并监听何时拖动阶段;当它被释放时,以正确的顺序重新聚焦所有阶段以重置它们的 z 顺序。不过,这只是我脑海中的一个快速想法。
您是想阻止说“中间”阶段获得焦点还是希望它在完成后回到中间?你也可以使用internal frame 吗?
感谢 Jai 和 Zephyr 的投入。我尝试使用 toFront 和 toBack 但无法获得确切的行为。将继续尝试其他方法。
【参考方案1】:
以下 mcve 演示从后到前阶段的重新排序,一旦从其中一个触发 ROOT MOUSE_EXITED_TARGET
事件。
这是一个简单但有限的解决方案:
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);
【讨论】:
感谢@c0der 提出另一种方法。这看起来比我迄今为止尝试的方法更有希望。如果我能得到更多建议,将等待一周,否则将其标记为已回答。 :)以上是关于JavaFX:如何管理阶段的 z-index的主要内容,如果未能解决你的问题,请参考以下文章