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 {
    
    @Override
    public 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>() {
                @Override
                public 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 modality
        Stage stage = new Stage();
        
        // Set the stage owner and modality
        stage.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();
    }
}

猜你喜欢

转载自blog.csdn.net/weiweiqiao/article/details/133212079