Issue
When I set the modality of an stage it's hide the maximize button
Stage stage = new Stage();
stage.setScene(new Scene((Parent) controller.getViewNode()));
stage.initStyle(StageStyle.DECORATED);
stage.setResizable(true);
stage.setIconified(false);
stage.initModality(Modality.APPLICATION_MODAL);
stage.initOwner(window);
So I wanted the stage to be an modal but as well show the maximize button, what don't happen. By the way, I'm using Ubuntu. I alredy made a search but I only found how remove the maximize button
Solution
The same happens to me. If I try to maximize using
stage.setMaximized(true);
It won't work, neither the maximize button is shown. I'm researching about it, but no answer at all. It's the first similar question I've found here. I'm using:
- OS: GNU/Linux
- Distro: Manjaro
- Linux Core: 5.3.6-1
- DE: Gnome.
- Java Version: OpenJDK 12.0.1
- JavaFX Version: OpenJFX 12.0.1 (gluon build).
UPDATE: The oficial documentation states:
Note that showing a modal stage does not necessarily block the caller.
So, I've decided to solve the issue using an EventHandler. I've created a utility class which takes care of this.
import javafx.event.Event;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
/**
* This is a utility class to create a Widow Event handler
* in such way that when a child window shows, a parent (owner)
* stage get locked; and when the child window hides, the parent
* stage get unlocked.
*
* @author David Vidal
* @version 1.0
* @since 1.0
*/
public final class WindowsModality {
/*=================*
* Private fields. *
*=================*/
/**
* The parent stage.
*/
private final Stage owner;
/*===============*
* Constructors. *
*===============*/
/**
* Initialize an instance with given parameters.
*
* @param owner parent stage.
* @param child child stage.
*/
public WindowsModality(Stage owner, Stage child) {
this.owner = owner;
child.addEventHandler(WindowEvent.WINDOW_HIDDEN, this::childHidden);
child.addEventHandler(WindowEvent.WINDOW_SHOWN, this::childShown);
}
/*==================*
* Implementations. *
*==================*/
/**
* Implementation of functional interface EventHandler,
* used to know when the child window is closed/hidden.
*
* @param event from {@link javafx.event.EventHandler#handle(Event)}
*/
private void childHidden(WindowEvent event) {
if (!event.isConsumed()) {
owner.getScene().getRoot().setDisable(false);
}
}
/**
* Implementation of functional interface EventHandler,
* used to know when the child window is shown.
*
* @param event from {@link javafx.event.EventHandler#handle(Event)}
*/
private void childShown(WindowEvent event) {
if (!event.isConsumed()) {
owner.getScene().getRoot().setDisable(true);
}
}
}
And then, I just added the following code:
public void showAnotherStage(){
//(Create and setup the new stage and scene)
new WindowModality(primaryStage, newStage);
newStage.show();
//Do something else.
}
That was my solution, tested and working fine. When the child window (newStage) is shown, the owner (primaryStage) gets disabled, so despite the user can activate the primaryStage window, user can't interact with its nodes.
Answered By - bichoFlyer
Answer Checked By - Mildred Charles (JavaFixing Admin)