ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • javaFX - 다이얼로그
    카테고리 없음 2020. 5. 23. 12:20

    javaFX 다이얼로그 

     

    다이얼로그 : 주 윈도우에서 알림이나 사용자의 입력을 위해 실행되는 서브 윈도우.

     

    자체적으로 실행될 수 없음. 주 윈도우(소유자 윈도우)에서 띄워준다.

     

    모달 과 모달리스 두 가지 종류가 있음.

     

    모달 다이얼로그 : 다이얼로그를 닫기 전까지 소유자 윈도우 사용불가.

     

    모달리스 다이얼로그 : 소유자 윈도우 계속 사용가능.

     

    다이얼로그 종류

     

    1. FileChooser : 파일 선택

     

    2. DirectoryChooser : 디렉토리 선택

     

    3. popup : 팝업창

     


    FileChooser

     

    로컬 PC의 파일을 선택할 수 있는 다이얼로그.

     

      열기, 저장을 할 수 있음. 파일 확장명을 필터링하여 원하는 파일만 볼 수도 있음.

     

    컨트롤이 아니다 => FXML에서 선언 X

     

    버튼이나 메뉴 아이템의 ActionEvent를 처리할 때 자바 코드로 FileChooser를 생성하고,

     

    showOpenDialog() or showSaveDialog()를 호출해야 함.

     

    사용방법
    
    FileChooser fc = new FileChooser();
    
    fc.getExtensionFilters().addAll(
    
        new ExtemsionFilter(),
    
        new ExtemsionFilter(),               // 파일 확장자 명으로 필터링.
    
        new ExtemsionFilter(),
    
        new ExtemsionFilter());
    
    File selectedFile = fc.showOpenDialog(primaryStage); // 다이얼로그 띄움.
    
    String selectedFilePath = selectedFile.getPath(); // 선택된 파일의 경로.

    fileChooser는 모달 다이얼로그이므로

     

    showOpenDialog() or showSaveDialog()를 호출할 때는 소유자 윈도우(Stage)를 매개값으로 해야함.

     


    DirectoryChooser

     

    파일이 아니라 Directory(폴더)를 선택할 때는, FileChooser 대신 DirectoryChooser를 사용.

     

    DirectoryChooser dc = new DirectoryChooser();
    
    File selectedDc = dc.showDialog(primaryStage);
    
    String selectedDcPath = selectedDc.getPath();

    pop

     

    투명한 컨테이너를 제공하는 모달리스 다이얼로그=> 소유자 윈도우에서 계속 사용 가능.

     

    컨트롤의 tooltip, 메세지 통지, 드롭다운 박스, 마우스 오른쪽 클릭했을 때 나타나는 메뉴 등등을

     

    만들 때 사용될 수 있음.

     

    ex)메세지 통지 popup
    
    Popup pu = new Popup();
    
    pu.getContent().add(FXMLLoader.load(getClass().getResource("popup.fxml")));
    
    show() : popup 실행 메서드.
    
    pu.show(primaryStage);  // 화면 정중앙에 실행.
    
    pu.show(primaryStage, anchorX, anchorY); // 지정된 좌표에서 실행.

    Popup은 다른 윈도우보다 최상위 위치에 놓임

     

    => Popup이 실행되면 어떤 윈도우를 실행해요 Popup이 항상 제일 위에 옴.

     

    Popup을 닫으려면??

     

    => 주 윈도우를 닫거나, Popup에 추가된 컨트롤 이벤트를 처리하여 hide()메서드 호출.

     

    가장 간단 방법: setAutoHide(true)를 설정하는 방법.

     

    pu.setAutoHide(true); / 포커스가 다른 윈도우로 이동하면 Popup은 자동으로 닫힘.

     

    예제) 메세지 통지용 Popup 예제
    
    <?xml version="1.0" encoding="UTF-8"?>
    
    
    
    <?import javafx.geometry.*?>
    
    <?import java.lang.*?>
    
    <?import javafx.scene.control.*?>
    
    <?import javafx.scene.image.*?>
    
    <?import javafx.scene.layout.*?>
    
    
    
    <HBox xmlns:fx="http://javafx.com/fxml"  alignment="CENTER_LEFT" 
    
    style="-fx-background-color: black; -fx-background-radius: 20;" > /CSS 적용.
    
       <children>
    
          <ImageView id="imgMessage" fitHeight="30" fitWidth="30" preserveRatio="true"/>
    
          <Label id="lblMessage" style="-fx-text-fill: white;"> /CSS 적용.
    
             <HBox.margin>
    
                <Insets left="5.0" right="5.0" />
    
             </HBox.margin>
    
          </Label>
    
       </children>
    
     
    
    </HBox>
    
    
    
    Popup 실행 코드.
    
    Popup pu = new Popup();
    
    
    Parent parent = FXMLLoader.load(getClass().getResource("popup.fxml"));
    
    ImageView imageView = (ImageView) parent.lookup("#imgMessage");
    
    imageView.setImage(new Image(getClass().getResource("images/dialog-info.png").toString()));
    
    imageView.setOnMouseClicked(event->pu.hide());
    
    Label lblMessage = (Label)parent.lookup("#lblMessage");
    
    lblMessage.setText("메시지가 왔습니다.");
    
    
    pu.getContent().add(parent);
    
    pu.setAutoHide(true);//다른 윈도우로 포커스를 이동하면 popup자동 닫힘.
    
    pu.show(primaryStage);
    
     
    
    }

    * Popup도 다이얼로그이다. => 소유자 윈도우가 필요하다. => show() 메서드를 호출할 때 매개값으로

    소유자 윈도우인 Stage가 필요하다.

     


    커스텀 다이얼로그

     

     Stage를 직접 생성하면 다양한 내용의 다이얼로그를 만들 수 있다. 

     

     Stage dialog = new Stage(StageStyle.UTILITY);

     

    dialog.initModality(Modality.WINDOW)MODAL);

     

    dialog.initOnwer(primaryStage);

     

    Stage 생성자 매개값에는 윈도우의 스타일을 결정짓는 StageStyle 열거 상수가 옴.

     

    StageStyle 열거상수  설명

     

    DECORATED          일반적 윈도우 스타일, 흰 배경, 제목줄에 장식(아이콘, 타이틀, 축소, 복원, 닫기                                                      버튼 장식)이 있다.  

     

    UNDECORATED       흰 배경, 제목줄 X

     

    TRANSPARENT        투명 배경, 제목줄 X

     

    UNIFIED                DECORATED와 같지만, 내용물의 경계선 X 

     

    UTILITY                 흰 배경, 제목줄에 타이틀, 종료버튼만 있다.

     

    매개값이 없는 기본 생성자로 Stage 생성 시 => DECORATED 원도우 생성.

     

    initModality(Modality.WINDOW)MODAL) => 모달 다이얼로그로 설정.

     

    미설정 시 모달리스 다이얼로그가 됨.

     

    initOnwer(primaryStage) = > 소유자 원도우 설정.

     

    ex) 확인 다이얼로그 내용
    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.layout.*?>
    
    <?import javafx.scene.control.*?>
    
    <?import javafx.scene.image.*?>
    
    <AnchorPane prefHeight="150.0" prefWidth="400.0" xmlns:fx="http://javafx.com/fxml">
    
       <children>
    
          <ImageView fitHeight="50" fitWidth="50" layoutX="15" layoutY="15" preserveRatio="true">
    
             <image><Image url="@images/dialog-info.png" /></image>
    
          </ImageView>
    
          <Button id="btnOk" layoutX="336.0" layoutY="104.0" text="확인" />
    
          <Label id="txtTitle" layoutX="87.0" layoutY="33.0" prefHeight="15.0" prefWidth="290.0" />
    
       </children>
    
     
    
    </AnchorPane>
    
    
    
    확인 다이얼로그 실행.
    
    Stage dialog = new Stage(StageStyle.UTILITY);
    
    dialog.initModality(Modality.WINDOW_MODAL);
    
    dialog.initOwner(primaryStage);
    
    dialog.setTitle("확인 다이얼로그");
    
    
    Parent parent = FXMLLoader.load(getClass().getResource("custom_dialog.fxml"));
    
    Label txtTitle = (Label) parent.lookup("#txtTitle");
    
    txtTitle.setText("확인하시겠습니까?");
    
    Button btnOk = (Button) parent.lookup("#btnOk");
    
    btnOk.setOnAction(event->dialog.close());
    
    Scene scene = new Scene(parent);
    
    
    dialog.setScene(scene);
    
    dialog.setResizable(false);
    
    dialog.show();

     


    컨트롤러에서 primaryStage 사용

     

    컨트롤러에서 다이얼로그를 실행할 때 -> 소유자 윈도우가 될 primaryStage 필요

     

    컨트롤러에서 primaryStage를 얻는 방법
    
    1. 메인 클래스에서 전달.
    
      primaryStage는 메인 클래스의 start() 매개값으로 전달된다 -> start() 메서드에서 컨트롤러로 primaryStage를 전달하면 됨.
    
    FXML 루트태그 fx:controller 속성에 지정된 컨트롤러 클래스는 FXMLLoader가 FXML을 로딩할 때 객체로 생성됨. FXMLLoader는 생성된 컨트롤러를 리턴하는 getController() 메서드 제공.
    
    * getController() 는 인스턴스 메서드이다 => FXMLLoader 객체가 필요.
    
    -> FXMLLoader의 정적 메서드인 load()의 호출 코드는 인스턴스 메서드 load()호출 코드로 바뀌어야 함.
    
    FXMLLoader loader = new FXMLLoader(getClass().getResource("root.fxml"));
    
    Parent root = loader.load();
    
    RootController controller = loader.getController();
    
    controller.setPrimaryStage(primaryStage);
    
    컨트롤러의 setPrimaryStage() 메서드를 호출하면서 primaryStage를 매개값으로 전달함.
    
    * => 컨트롤러 클래스는 필드와 setter 메서드를 추가해 두어야 함.
    
    public class RootController implements Initializable {
    
    
    private Stage primaryStage;
    
    public void setPrimaryStage(Stage primaryStage) {
    
    this.primaryStage = primaryStage;
    
     
    
    }
    
         ..... 
    
       }

     

    2. 컨터이너 or 컨트롤러로부터 얻음.

     

      컨테이너나 컨트롤의 getScene() 는 자신이 포함된 Scene 객체 리턴.

     

    Scene의 getWindow() 는 자신이 보여주는 Stage 객체 리턴.

     

    컨트롤러에서 primaryStage 객체를 얻는 코드

     

    =>

     

    Stage primaryStage = (Stage) 컨트롤.getScene().getWindow();

     

    * initialize() 안에서는 사용 불가.

     

    => 아직 primaryStage가 생성되지 않아서.

     

    메인 클래스의 start() 메서드에서 Scene 객체를 생성하고 primaryStage에 Scene을 설정해야 위 코드가 정상 동작 때문

     

    에 이벤트 처리 메서드 내에서 위 코드를 사용해야 함.

     

    JavaFX 다이얼로그 전체 예제)
    
    root.fxml
    
    <?xml version="1.0" encoding="UTF-8"?>
    
    
    
    <?import javafx.scene.layout.*?>
    
    <?import javafx.scene.control.*?>
    
    <?import javafx.geometry.*?>
    
    
    
    <HBox xmlns:fx="http://javafx.com/fxml" fx:controller="thisisjava.RootController"
    
    alignment="TOP_LEFT" spacing="10.0" >
    
       <children>
    
          <Button text="Open FileChooser" onAction="#handleOpenFileChooser"/>
    
          <Button text="Save FileChooser" onAction="#handleSaveFileChooser"/>      
    
          <Button text="DirectoryChooser" onAction="#handleDirectoryChooser"/>
    
          <Button text="Popup" onAction="#handlePopup"/>
    
          <Button text="Custom Dialog" onAction="#handleCustom"/>
    
       </children>
    
       <padding>
    
          <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
    
       </padding>
    
    </HBox>
    
    
    
    
    popup.fxml
    
    <?xml version="1.0" encoding="UTF-8"?>
    
    
    
    <?import javafx.geometry.*?>
    
    <?import java.lang.*?>
    
    <?import javafx.scene.control.*?>
    
    <?import javafx.scene.image.*?>
    
    <?import javafx.scene.layout.*?>
    
    
    
    <HBox xmlns:fx="http://javafx.com/fxml"
    
    alignment="CENTER_LEFT" style="-fx-background-color: black; -fx-background-radius: 20;" >
    
       <children>
    
          <ImageView id="imgMessage" fitHeight="30" fitWidth="30" preserveRatio="true"/>
    
          <Label id="lblMessage" style="-fx-text-fill: white;">
    
             <HBox.margin>
    
                <Insets left="5.0" right="5.0" />
    
             </HBox.margin>
    
          </Label>
    
       </children>
    
    </HBox>
    
    
    
    
    costom_dialog.fxml
    
    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.layout.*?>
    
    <?import javafx.scene.control.*?>
    
    <?import javafx.scene.image.*?>
    
    <AnchorPane prefHeight="150.0" prefWidth="400.0" xmlns:fx="http://javafx.com/fxml">
    
       <children>
    
          <ImageView fitHeight="50" fitWidth="50" layoutX="15" layoutY="15" preserveRatio="true">
    
             <image><Image url="@images/dialog-info.png" /></image>
    
          </ImageView>
    
          <Button id="btnOk" layoutX="336.0" layoutY="104.0" text="확인" />
    
          <Label id="txtTitle" layoutX="87.0" layoutY="33.0" prefHeight="15.0" prefWidth="290.0" />
    
       </children>
    
    </AnchorPane>
    
    
    
    
    자바1)
    
    package thisisjava;
    
    
    
    import javafx.application.Application;
    
    import javafx.fxml.FXMLLoader;
    
    import javafx.scene.Parent;
    
    import javafx.scene.Scene;
    
    import javafx.stage.Stage;
    
    
    
    public class AppMain extends Application {
    
    @Override
    
    public void start(Stage primaryStage) throws Exception {
    
    FXMLLoader loader = new FXMLLoader(getClass().getResource("root.fxml"));
    
    Parent root = loader.load();
    
    RootController controller = loader.getController();
    
    controller.setPrimaryStage(primaryStage);
    
    
    Scene scene = new Scene(root);
    
    
    primaryStage.setTitle("JavaFX 다이얼로그");
    
    primaryStage.setScene(scene);
    
    primaryStage.show();
    
    }
    
    
    public static void main(String[] args) {
    
    launch(args);
    
    }
    
    }
    
    
    자바2)
    
    package thisisjava;
    
    
    
    import java.io.File;
    
    import java.net.URL;
    
    import java.util.ResourceBundle;
    
    
    
    import javafx.event.ActionEvent;
    
    import javafx.fxml.FXMLLoader;
    
    import javafx.fxml.Initializable;
    
    import javafx.scene.Parent;
    
    import javafx.scene.Scene;
    
    import javafx.scene.control.Button;
    
    import javafx.scene.control.Label;
    
    import javafx.scene.image.Image;
    
    import javafx.scene.image.ImageView;
    
    import javafx.scene.layout.HBox;
    
    import javafx.stage.DirectoryChooser;
    
    import javafx.stage.FileChooser;
    
    import javafx.stage.FileChooser.ExtensionFilter;
    
    import javafx.stage.Modality;
    
    import javafx.stage.Popup;
    
    import javafx.stage.Stage;
    
    import javafx.stage.StageStyle;
    
    
    
    public class RootController implements Initializable {
    
    @Override
    
    public void initialize(URL location, ResourceBundle resources) {
    
    }
    
    
    private Stage primaryStage;
    
    public void setPrimaryStage(Stage primaryStage) {
    
    this.primaryStage = primaryStage;
    
    }
    
    
    public void handleOpenFileChooser(ActionEvent e) {
    
    FileChooser fileChooser = new FileChooser();
    
    fileChooser.getExtensionFilters().addAll(
    
    new ExtensionFilter("Text Files", "*.txt"),
    
    new ExtensionFilter("Image Files", "*.png", "*.jpg", "*.gif"),
    
    new ExtensionFilter("Audio Files", "*.wav", "*.mp3", "*.aac"),
    
    new ExtensionFilter("All Files", "*.*"));
    
    File selectedFile = fileChooser.showOpenDialog(primaryStage);
    
    if (selectedFile != null) {
    
    System.out.println(selectedFile.getPath());
    
    }
    
    }
    
    
    public void handleSaveFileChooser(ActionEvent e) {
    
    FileChooser fileChooser = new FileChooser();
    
    fileChooser.getExtensionFilters().add(new ExtensionFilter("All Files", "*.*"));
    
    File selectedFile = fileChooser.showSaveDialog(primaryStage);
    
    if (selectedFile != null) {
    
    System.out.println(selectedFile.getPath());
    
    }
    
    }
    
    
    public void handleDirectoryChooser(ActionEvent e) {
    
    DirectoryChooser directoryChooser = new DirectoryChooser();
    
    File selectedDir = directoryChooser.showDialog(primaryStage);
    
    if (selectedDir != null) {
    
    System.out.println(selectedDir.getPath());
    
    }
    
    }
    
    
    public void handlePopup(ActionEvent e) throws Exception {
    
    Popup popup = new Popup();
    
    
    Parent parent = FXMLLoader.load(getClass().getResource("popup.fxml"));
    
    ImageView imageView = (ImageView) parent.lookup("#imgMessage");
    
    imageView.setImage(new Image(getClass().getResource("images/dialog-info.png").toString()));
    
    imageView.setOnMouseClicked(event->popup.hide());
    
    Label lblMessage = (Label)parent.lookup("#lblMessage");
    
    lblMessage.setText("메시지가 왔습니다.");
    
    
    popup.getContent().add(parent);
    
    popup.setAutoHide(true);
    
    popup.show(primaryStage);
    
    }
    
    
    public void handleCustom(ActionEvent e) throws Exception {
    
    Stage dialog = new Stage(StageStyle.UTILITY);
    
    dialog.initModality(Modality.WINDOW_MODAL);
    
    dialog.initOwner(primaryStage);
    
    dialog.setTitle("확인 다이얼로그");
    
    
    Parent parent = FXMLLoader.load(getClass().getResource("custom_dialog.fxml"));
    
    Label txtTitle = (Label) parent.lookup("#txtTitle");
    
    txtTitle.setText("확인하시겠습니까?");
    
    Button btnOk = (Button) parent.lookup("#btnOk");
    
    btnOk.setOnAction(event->dialog.close());
    
    Scene scene = new Scene(parent);
    
    
    dialog.setScene(scene);
    
    dialog.setResizable(false);
    
    dialog.show();
    
    }
    
    }

     

    댓글

Designed by Tistory.