如何在 JavaFX 中获取当前打开的阶段?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32922424/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get the current opened stage in JavaFX?
提问by Mateus Viccari
Is there a way to get the current opened Stage in JavaFX, if there is one open?
有没有办法在 JavaFX 中获取当前打开的舞台,如果有一个打开?
Something like this:
像这样的东西:
Stage newStage = new Stage();
newStage.initOwner(JavaFx.getCurrentOpenedStage()); //Like this
采纳答案by Adam
Java 9 makes this possible by the addition of the javafx.stage.Window.getWindows()
method. Therefore you can just get list of Windows and see which are showing
Java 9 通过添加该javafx.stage.Window.getWindows()
方法使这成为可能。因此,您可以获取 Windows 列表并查看哪些正在显示
List<Window> open = Stage.getWindows().stream().filter(Window::isShowing);
回答by James_D
There's no built-in functionality for this. In most use cases, you open a new Stage
as a result of user action, so you can call getScene().getWindow()
on the node on which the action occurred to get the "current" window.
这没有内置功能。在大多数用例中,您会Stage
根据用户操作打开一个新getScene().getWindow()
窗口,因此您可以调用发生操作的节点来获取“当前”窗口。
In other use cases, you will have to write code to track current windows yourself. Of course, multiple windows might be open, so you need to track them in some kind of collection. I'd recommend creating a factory class to manage the stages and registering event handlers for the stages opening and closing, so you can update a property and/or list. You'd probably want this to be a singleton. Here's a sample implementation: here getOpenStages()
gives an observable list of open stages - the last one is the most recently opened - and currentStageProperty()
gives the focused stage (if any). Your exact implementation might be different, depending on your exact needs.
在其他用例中,您必须自己编写代码来跟踪当前窗口。当然,可能会打开多个窗口,因此您需要在某种集合中跟踪它们。我建议创建一个工厂类来管理阶段并为阶段打开和关闭注册事件处理程序,以便您可以更新属性和/或列表。你可能希望这是一个单身人士。这是一个示例实现:这里getOpenStages()
给出了一个可观察的打开阶段列表 - 最后一个是最近打开的 - 并currentStageProperty()
给出了重点阶段(如果有的话)。您的具体实现可能会有所不同,具体取决于您的具体需求。
public enum StageFactory {
INSTANCE ;
private final ObservableList<Stage> openStages = FXCollections.observableArrayList();
public ObservableList<Stage> getOpenStages() {
return openStages ;
}
private final ObjectProperty<Stage> currentStage = new SimpleObjectProperty<>(null);
public final ObjectProperty<Stage> currentStageProperty() {
return this.currentStage;
}
public final javafx.stage.Stage getCurrentStage() {
return this.currentStageProperty().get();
}
public final void setCurrentStage(final javafx.stage.Stage currentStage) {
this.currentStageProperty().set(currentStage);
}
public void registerStage(Stage stage) {
stage.addEventHandler(WindowEvent.WINDOW_SHOWN, e ->
openStages.add(stage));
stage.addEventHandler(WindowEvent.WINDOW_HIDDEN, e ->
openStages.remove(stage));
stage.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
if (isNowFocused) {
currentStage.set(stage);
} else {
currentStage.set(null);
}
});
}
public Stage createStage() {
Stage stage = new Stage();
registerStage(stage);
return stage ;
}
}
Note this only allows you to track stages obtained from StageFactory.INSTANCE.createStage()
or created elsewhere and passed to the StageFactory.INSTANCE.registerStage(...)
method, so your code has to collaborate with that requirement. On the other hand, it gives you the chance to centralize code that initializes your stages, which may be otherwise beneficial.
请注意,这仅允许您跟踪从StageFactory.INSTANCE.createStage()
其他地方获取或创建并传递给StageFactory.INSTANCE.registerStage(...)
方法的阶段,因此您的代码必须与该要求协作。另一方面,它让您有机会集中初始化您的阶段的代码,否则这可能是有益的。
Here's a simple example using this:
这是一个使用它的简单示例:
import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
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;
import javafx.stage.WindowEvent;
public class SceneTrackingExample extends Application {
int count = 0 ;
@Override
public void start(Stage primaryStage) {
StageFactory factory = StageFactory.INSTANCE ;
factory.registerStage(primaryStage);
configureStage(primaryStage);
primaryStage.show();
}
private void configureStage(Stage stage) {
StageFactory stageFactory = StageFactory.INSTANCE;
Stage owner = stageFactory.getCurrentStage() ;
Label ownerLabel = new Label();
if (owner == null) {
ownerLabel.setText("No owner");
} else {
ownerLabel.setText("Owner: "+owner.getTitle());
stage.initOwner(owner);
}
stage.setTitle("Stage "+(++count));
Button newStage = new Button("New Stage");
newStage.setOnAction(e -> {
Stage s = stageFactory.createStage();
Stage current = stageFactory.getCurrentStage() ;
if (current != null) {
s.setX(current.getX() + 20);
s.setY(current.getY() + 20);
}
configureStage(s);
s.show();
});
VBox root = new VBox(10, ownerLabel, newStage);
root.setAlignment(Pos.CENTER);
stage.setScene(new Scene(root, 360, 150));
}
public enum StageFactory {
INSTANCE ;
private final ObservableList<Stage> openStages = FXCollections.observableArrayList();
public ObservableList<Stage> getOpenStages() {
return openStages ;
}
private final ObjectProperty<Stage> currentStage = new SimpleObjectProperty<>(null);
public final ObjectProperty<Stage> currentStageProperty() {
return this.currentStage;
}
public final javafx.stage.Stage getCurrentStage() {
return this.currentStageProperty().get();
}
public final void setCurrentStage(final javafx.stage.Stage currentStage) {
this.currentStageProperty().set(currentStage);
}
public void registerStage(Stage stage) {
stage.addEventHandler(WindowEvent.WINDOW_SHOWN, e ->
openStages.add(stage));
stage.addEventHandler(WindowEvent.WINDOW_HIDDEN, e ->
openStages.remove(stage));
stage.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
if (isNowFocused) {
currentStage.set(stage);
} else {
currentStage.set(null);
}
});
}
public Stage createStage() {
Stage stage = new Stage();
registerStage(stage);
return stage ;
}
}
public static void main(String[] args) {
launch(args);
}
}
回答by Salman Saleh
You can create a label in your java fxml.
您可以在 java fxml 中创建标签。
Then in your controller class refer your label like this :
然后在您的控制器类中,像这样引用您的标签:
@FXML
private Label label;
@FXML
private Label label;
Then in any function of the controller class you can access the current stage by this block of code :
然后在控制器类的任何函数中,您都可以通过以下代码块访问当前阶段:
private void any_function(){
Stage stage;
stage=(Stage) label.getScene().getWindow();
}
回答by Nelio Alves
If you need the current stage reference inside an event handler method, you can get it from the ActionEvent param. For example:
如果您需要事件处理程序方法中的当前阶段引用,您可以从 ActionEvent 参数中获取它。例如:
@FXML
public void OnButtonClick(ActionEvent event) {
Stage stage = (Stage)((Node) event.getSource()).getScene().getWindow();
(...)
}
You can also get it from any control declared in your controller:
您还可以从控制器中声明的任何控件中获取它:
@FXML
private Button buttonSave;
(...)
Stage stage = (Stage) buttonSave.getScene().getWindow();