Block owner window Java FX
Asked Answered
C

4

11

I would like to block the owner window for a popup in JavaFX.

I initialize my popup like this:

popUp = new Popup();
popUp.getContent().add(content);
popUp.show(pane.getScene().getWindow());

With this, I can still work in the first window (pane window). I would like to disable this action and I would like the user just works in the popup.

How to do this ?

Thanks.

Contend answered 25/3, 2013 at 22:24 Comment(0)
D
21

Use a Stage instead of a Popup.

Before showing the stage, invoke stage.initModality as either APPLICATION_MODAL or WINDOW_MODAL, as appropriate. Also invoke stage.initOwner to the parent window of your new stage so that it will appropriately block it for the WINDOW_MODAL case.

Stage stage = new Stage();
stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(pane.getScene().getWindow());
stage.setScene(new Scene(content));
stage.show();
Divan answered 25/3, 2013 at 22:43 Comment(2)
Shouldn't be Modality.APPLICATION_MODAL instead of Modality.WINDOW_MODAL? at least in my case it works with the former as suggested in the other user's answer, but not with the later.Comitia
It depends upon what you want to do Fran. If you want to block all windows in the application, then use APPLICATION_MODAL. If you only want to block the parent window chain (as the original question asks), then use WINDOW_MODAL. If you are blocking the parent window with WINDOW_MODAL, then you MUST call initOwner on your window with a valid, non-null, parent window reference, BEFORE you show your window, otherwise it won't block anything.Divan
G
4

Thanks, optimal solution: example with FXML load file:

@Override
    public void start(Stage primaryStage) throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource("DialogView.fxml"));
        primaryStage.initModality(Modality.APPLICATION_MODAL); // 1 Add one
        Scene scene = new Scene(root);        
        primaryStage.setScene(scene);
        primaryStage.initOwner(primaryStage.getScene().getWindow());// 2 Add two
        primaryStage.show();

    }

    public static void main(String[] args) {
        launch(args);

    }
Gerius answered 18/3, 2014 at 16:26 Comment(2)
Not working for me. :( Using Kotlin in IntelliJ Idea over OS X Mojave. Followed those steps, but I still can interact with the original window after opening the new one.Comitia
Oh Damn it! I mixed your answer with the previous one and I used Modality.WINDOW_MODAL with did NOT work. But APPLICATION_MODAL does! Thanks!Comitia
W
0

I'm using JavaFX11. Both this and this works with a small change. Here is my working example. I'm using rgielen's javafx-weaver

Main:

package com.featuriz.controller;

import javafx.fxml.FXML;
import javafx.scene.layout.AnchorPane;
import javafx.scene.text.Text;
import net.rgielen.fxweaver.core.FxControllerAndView;
import net.rgielen.fxweaver.core.FxmlView;
import org.springframework.stereotype.Component;

@Component
@FxmlView("/com/featuriz/ui/Login.fxml")
public class LoginController {
    
    private final FxControllerAndView<InfoDialogController, AnchorPane> infoDialog;

    @FXML
    private Text featuriz;

    public LoginController(FxControllerAndView<InfoDialogController, AnchorPane> infoDialog) {
        this.infoDialog = infoDialog;
    }

    @FXML
    public void initialize() {
        featuriz.setOnMouseClicked(
                actionEvent -> this.infoDialog.getController().show()
        );
    }
}

Dialog:

package com.featuriz.controller;

import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import net.rgielen.fxweaver.core.FxmlView;
import org.springframework.stereotype.Component;

@Component
@FxmlView("/com/featuriz/ui/InfoDialog.fxml")
public class InfoDialogController {

    private Stage stage;

    @FXML
    private Label lbl_info;

    @FXML
    private Button closeButton;

    @FXML
    private AnchorPane dialog_info;

    @FXML
    public void initialize() {
        Scene scene = new Scene(dialog_info);
        scene.setFill(Color.TRANSPARENT);
        this.stage = new Stage();
        this.stage.initModality(Modality.APPLICATION_MODAL);
        this.stage.initStyle(StageStyle.TRANSPARENT);
        this.stage.setScene(scene);
        this.stage.setAlwaysOnTop(true);

        String javaVersion = System.getProperty("java.version");
        String javafxVersion = System.getProperty("javafx.version");
        lbl_info.setText("JavaFX " + javafxVersion + "\nRunning on Java " + javaVersion + ".");

        closeButton.setOnAction(
                actionEvent -> this.stage.close()
        );
    }

    public void show() {
        this.stage.show();
    }

}
Wrapper answered 11/2, 2021 at 10:49 Comment(0)
A
0

You just have to add the Modality resource from javafx.stage.Modality;

And then add the line stage.initModality(Modality.APPLICATION_MODAL);

Here you have an example

Stage stage = new Stage();

            Parent root = FXMLLoader.load(getClass().getResource( -- pathInterface --));
            root.getStylesheets().add(getClass().getResource( -- pathCss --).toExternalForm());
            stage.initStyle(StageStyle.DECORATED.UNDECORATED);
            stage.initModality(Modality.APPLICATION_MODAL);
Ailyn answered 20/5, 2021 at 18:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.