我有一个父阶段,上面可以显示弹出窗口。代码如下:
private static Stage chooseBreedStage;
static {
chooseBreedStage = new Stage();
chooseBreedStage.setTitle("Choose breed");
chooseBreedStage.initOwner(AppKitty.getStage());
chooseBreedStage.initModality(Modality.WINDOW_MODAL);
chooseBreedStage.setScene(SceneManager.getInstance().getScene(SceneEnum.CHOOSE_BREED_SCREEN));
}
public void showChooseBreedPopup() {
chooseBreedStage.showAndWait();
}
在显示popup之前,我使用seteffect()方法模糊父节点。如何在弹出窗口关闭时消除模糊效果?
在我的尝试中,我总是面临这样的问题:尽管popup已经消失,但是在父屏幕控制器中@fxml注解的元素是空的,但是它们是可见的,不会被popup隐藏
有没有监听器,当舞台没有被阻塞并且场景已经被加载时处理事件,这样我就可以和@fxml对象交互了?
以下是场景控制器的一部分,设置在初级阶段:
public class MainScreenController {
private GaussianBlur blur = new GaussianBlur();
@FXML
public StackPane mainScreen;
public void blurOn() {
mainScreen.setEffect(blur);
}
public void blurOff() {
mainScreen.setEffect(null);
}
public void makeTestClick(ActionEvent event) {
blurOn();
SceneManager.getInstance().getController(ChooseBreedScreenController.class)
.showChooseBreedPopup();
}
}
scenemanager类代码(@data是lombok注解,可以用getters和setters替换):
public class SceneManager {
private final Map<SceneEnum, SceneData> sceneData = new HashMap<>();
@Data
private class SceneData {
private Scene scene;
private FXMLLoader loader;
private Controller controller;
SceneData(Scene scene, FXMLLoader loader) {
setScene(scene);
setLoader(loader);
setController(controller);
}
}
private static SceneManager instance = new SceneManager();
public static SceneManager getInstance() {
return instance;
}
private SceneManager() {
}
public <T extends Controller> T getController(Class<T> controllerClass) {
SceneEnum sceneEnum = getCorrespondingEnum(controllerClass);
if (sceneData.get(sceneEnum) == null || sceneData.get(sceneEnum).getController() == null) {
initSceneController(controllerClass);
}
return (T) sceneData.get(sceneEnum).getController();
}
public Controller getController(SceneEnum sceneEnum) {
return getController(sceneEnum.getControllerClass());
}
private <T extends Controller> void initSceneController(Class<T> controllerClass) {
try {
SceneEnum sceneEnum = getCorrespondingEnum(controllerClass);
if (sceneData.get(sceneEnum) == null) {
initScene(sceneEnum);
}
sceneData.get(sceneEnum).setController(controllerClass.getConstructor().newInstance());
} catch (Exception e) {
//todo here should be popup with error
}
}
private <T extends Controller> SceneEnum getCorrespondingEnum(Class<T> controllerClass) {
Optional<SceneEnum> desiredSceneEnum = Arrays.stream(SceneEnum.values())
.filter(sceneEnum -> controllerClass.isAssignableFrom(sceneEnum.getControllerClass()))
.findFirst();
return desiredSceneEnum.orElseGet(() -> {
//todo here should be shown popup with error
return null;
});
}
public Scene getScene(SceneEnum sceneEnum) {
if (sceneData.get(sceneEnum) == null) {
initScene(sceneEnum);
}
return sceneData.get(sceneEnum).getScene();
}
private void initScene(SceneEnum sceneEnum) {
ConsumerWithException<SceneEnum, IOException> loadingScene = sceneType -> {
FXMLLoader loader = getFxmlLoader(sceneEnum);
Scene scene = new Scene(loader.load());
sceneData.put(sceneEnum, new SceneData(scene, loader));
};
try {
loadingScene.accept(sceneEnum);
} catch (IOException initializeScreenException) {
try {
//Loading app error popup scene, before calling getController() method for
//this popup, to avoid recursion if loading app error popup scene producing exception as well
//(it may be in initScene method inside getController method)
loadingScene.accept(SceneEnum.APP_ERROR_POPUP);
getController(AppErrorPopupController.class)
.showAppErrorPopup(sceneEnum);
} catch (IOException initializeErrorPopupException) {
//todo make a better logging
initializeErrorPopupException.printStackTrace();
}
}
}
private FXMLLoader getFxmlLoader(SceneEnum scene){
return new FXMLLoader(this.getClass().getResource(scene.getScenePath()));
}
}
应用程序类:
public class AppKitty extends Application {
private static Stage stage;
public static Stage getStage() {
return stage;
}
public static void setScene(SceneEnum sceneEnum) {
getStage().setScene(SceneManager.getInstance()
.getScene(sceneEnum));
}
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
stage = primaryStage;
primaryStage.setTitle("AppKitty");
primaryStage.setScene(SceneManager.getInstance().getScene(SceneEnum.MAIN_SCREEN));
primaryStage.show();
}
}
主屏幕.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<StackPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="applicationinterface.controllers.MainScreenController"
prefHeight="400.0" prefWidth="600.0"
fx:id="mainScreen"
stylesheets="@../styles/mainScreenBackground.css"
id="background_image">
<Label fx:id="title" text="What do you want?" alignment="TOP_CENTER"
stylesheets="@../styles/outline.css" styleClass="outline" StackPane.alignment="TOP_CENTER">
</Label>
<HBox
fx:id="bottomBar" id="outline.label" alignment="BOTTOM_CENTER"
stylesheets="@../styles/outline.css" spacing="20" StackPane.alignment="BOTTOM_CENTER">
<StackPane.margin>
<Insets bottom="10"/>
</StackPane.margin>
<Button fx:id="randomKittyButton" text="Random Kitty" onAction="#randomKittyClick" focusTraversable="false"
stylesheets="@../styles/buttonBorder.css" styleClass="button"/>
<Button fx:id="makeTestButton" text="Take the test" onAction="#makeTestClick" focusTraversable="false"
stylesheets="@../styles/buttonBorder.css" styleClass="button"/>
</HBox>
</StackPane>
1条答案
按热度按时间idfiyjo81#
根据您的代码,您需要在静态块中声明时包含popup阶段的close处理程序。您可以包含以下任何处理程序(视需要而定)