有没有办法在JavaFX中获得当前打开的Stage,如果有一个打开的话?
像这样的东西:
Stage newStage = new Stage();
newStage.initOwner(JavaFx.getCurrentOpenedStage()); //Like this
Run Code Online (Sandbox Code Playgroud)
Nel*_*ves 12
如果您需要事件处理程序方法中的当前阶段引用,您可以从 ActionEvent 参数中获取它。例如:
@FXML
public void OnButtonClick(ActionEvent event) {
Stage stage = (Stage)((Node) event.getSource()).getScene().getWindow();
(...)
}
Run Code Online (Sandbox Code Playgroud)
您还可以从控制器中声明的任何控件中获取它:
@FXML
private Button buttonSave;
(...)
Stage stage = (Stage) buttonSave.getScene().getWindow();
Run Code Online (Sandbox Code Playgroud)
Jam*_*s_D 10
这没有内置功能.在大多数用例中,Stage由于用户操作而打开一个新用例,因此您可以调用getScene().getWindow()发生操作的节点来获取"当前"窗口.
在其他用例中,您必须编写代码来自己跟踪当前窗口.当然,多个窗口可能是打开的,因此您需要在某种集合中跟踪它们.我建议创建一个工厂类来管理阶段并为阶段的打开和关闭注册事件处理程序,这样您就可以更新属性和/或列表.你可能希望这是一个单身人士.这是一个示例实现:这里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 ;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这只允许您跟踪从StageFactory.INSTANCE.createStage()其他地方获取或创建的阶段并传递给该StageFactory.INSTANCE.registerStage(...)方法,因此您的代码必须与该要求协作.另一方面,它使您有机会集中初始化阶段的代码,这可能是有益的.
这是一个使用它的简单示例:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 8
您可以在 java fxml 中创建标签。
然后在您的控制器类中,像这样引用您的标签:
@FXML
private Label label;
然后在控制器类的任何函数中,您都可以通过以下代码块访问当前阶段:
private void any_function(){
Stage stage;
stage=(Stage) label.getScene().getWindow();
}
Run Code Online (Sandbox Code Playgroud)
Java 9通过添加javafx.stage.Window.getWindows()方法使这成为可能.因此,您只需获取Windows列表并查看正在显示的内容
List<Window> open = Stage.getWindows().stream().filter(Window::isShowing);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15996 次 |
| 最近记录: |