JavaFX:窗体显示状态,模态非模态
程序窗体显示一般有3中模式。非模态和模态,其中模态又分为程序模态和窗体模态。
非模态可以理解为窗体之间没有任何限制,可以用鼠标、键盘等工具在窗体间切换。
程序模态是窗体打开后,该程序的所有窗体都被冻结,无法切换,只能在程序模态窗体关闭后才可切换。
窗体模态是窗体打开后,该窗体上溯的所有窗体都被冻结,无法切换,但是程序中已打开,不在该上溯线上的窗体可以和该窗体自由切换。
测试代码如下:
package javafx8.ch04;import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.Window;import static javafx.stage.Modality.APPLICATION_MODAL;
import static javafx.stage.Modality.NONE;
import static javafx.stage.Modality.WINDOW_MODAL;/*** @copyright 2023-2022* @package learnjavafx8.javafx8.ch04* @file StageModalityApplication.java* @date 2023-02-02 20:59* @author qiao wei* @version 1.0* @brief 设置窗体模态,JavaFX共分3中模态。* 非模态NONE:Defines a top-level window that is not modal and does not block any other window。* 程序模态APPLICATION_MODAL:Defines a modal window that blocks events from being delivered to any* other application window。* 窗体模态WINDOW_MODAL:Defines a modal window that block events from being delivered to its entire* owner window hierarchy。* @history*/
public class StageModalityApplication extends Application {@Overridepublic void start(Stage primaryStage) {// Buttons to display each kind of modal stage Button ownedNoneButton = new Button("Owned None");/*** 父控件为primaryStage,父控件与子控件stage之间为非模态,鼠标可以在父子控件间切换,当父控件关闭时,子控件* 跟随父控件一起关闭。*/ownedNoneButton.addEventHandler(MouseEvent.MOUSE_CLICKED,new EventHandler<MouseEvent>() {@Overridepublic void handle(MouseEvent event) {showDialog(primaryStage, NONE);}});
// ownedNoneButton.setOnAction(e -> showDialog(primaryStage, NONE));
// ownedNoneButton.setOnAction(new EventHandler<ActionEvent>() {
// @Override
// public void handle(ActionEvent actionEvent) {
// showDialog(primaryStage, NONE);
// }
// });Button nonOwnedNoneButton = new Button("Non-owned None");/*** 父控件为null, primaryStage与控件stage之间为非模态,鼠标可以在两个控件间切换,当primaryStage控件关闭* 时,stage控件不关闭。*/nonOwnedNoneButton.setOnAction(e -> showDialog(null, NONE));// 与创建此窗口的上层窗口形成模态。Button ownedWinButton = new Button("Owned Window Modal");// 父控件为primaryStage的WINDOW_MODAL模式,只与父控件形成模态,与父控件的其余子控件不形成模态。ownedWinButton.setOnAction(e -> showDialog(primaryStage, WINDOW_MODAL));Button nonOwnedWinButton = new Button("Non-owned Window Modal");// 父控件为null的WINDOW_MODAL模式,因为父控件为null,相当与父控件、父控件的其余子控件不形成模态。nonOwnedWinButton.setOnAction(e -> showDialog(null, WINDOW_MODAL));// 与创建此窗口的程序的所有窗口均形成模态。Button ownedAppButton = new Button("Owned Application Modal");// Set button opacity。ownedAppButton.setOpacity(0.3);// 父控件为primaryStage的APPLICATION_MODAL模式,与Application中的的其余所有子控件均形成模态。ownedAppButton.setOnAction(e -> showDialog(primaryStage, APPLICATION_MODAL));Button nonOwnedAppButton = new Button("Non-owned Application Modal");// 父控件为null的APPLICATION_MODAL模式,与父控件、父控件的其余子控件均形成模态。nonOwnedAppButton.setOnAction((ActionEvent event)-> showDialog(null, APPLICATION_MODAL));VBox root = new VBox();root.getChildren().addAll(ownedNoneButton, nonOwnedNoneButton,ownedWinButton, nonOwnedWinButton,ownedAppButton, nonOwnedAppButton);Scene scene = new Scene(root, 300, 200);primaryStage.setScene(scene);primaryStage.setTitle("The Primary Stage");// Set full screen and unresizable。primaryStage.setFullScreen(true);
// primaryStage.setResizable(false);primaryStage.show();}public static void main(String[] args) {Application.launch(StageModalityApplication.class, args);}/*** @class StageModalityApplication* @date 2023-06-21 21:01* @author qiao wei* @version 1.0* @brief 根据窗口拥有者和模式设置窗口状态。* @param owner 窗口的父控件。* @param modality 窗口模式。* @return * @throws*/private void showDialog(Window owner, Modality modality) {// Create a new stage with specified owner and modalityStage stage = new Stage();// Set the stage owner and modalitystage.initOwner(owner);stage.initModality(modality);Label modalityLabel = new Label(modality.toString());Button closeButton = new Button("Close");
// closeButton.setOnAction(e -> stage.close());closeButton.addEventHandler(MouseEvent.MOUSE_CLICKED, mouseEvent -> stage.close());VBox root = new VBox();root.getChildren().addAll(modalityLabel, closeButton);Scene scene = new Scene(root, 200, 100);// 设置鼠标在scene的显示模式scene.setCursor(Cursor.HAND);stage.setScene(scene);stage.setTitle("A Dialog Box");stage.show();}
}