AlertBox 는 보통 새로운 윈도우를 하나 더 띄우는 것이다. 윈도우 GUI 프로그램을 사용하다 보면 기존의 윈도우에서 한 개의 윈도우를 더 오픈해야 하는 경우가 생긴다. 윈도우를 오래 사용하다보면 의식하지 않고 사용하는 것인데 윈도우 안에서 새로운 윈도우를 오픈하는 것이므로 두개의 창이 열린다.

 

 

Stage 구조를 두개 오픈하면 기존의 window 는 root 윈도우가 된다.

 

 

윈도우가 화면에 표시될 때 알 수 있지만 그러기 위해서는 윈도우를 열기 위한 작업을 반복하는 것이다.

 

이전 까지의 포스트를 통해서 javafx 는 다음의 구조라는 것을 알았다.

 

- Stage 클래스 : 처음 열리는 Stage 클래스가 root 윈도우다.

 

 - Scene 클래스 : 하나의 Stage 클래스에 여러개의 Scene 들을 배치하여 이동할 수 있다.

 

- 레이아웃 매니저 : StackPane 이나 VBox, HBox 등이 있다.

 

- 컴포넌트들 (컨트롤, 컨테이너 등의 이름으로 불린다) 을 레이아웃 매니저에 추가한다.

 

Python 의 tkinter 같은 간단한 GUI 를 사용해봤다면 이 과정이 좀 복잡해 보일 지도 모른다. JavaFX 는 좀 더 번거롭기는 해도 기능이나 디자인 측면에서 tkinter 보다 우수하다.

 

하나의 창을 띄우기 위해서 이 모든 과정을 다 거쳐야 한다는 점에 주의한다.

 

* 새로운 창을 별도의 클래스에 정의한다. AlertBox라는 이름의 클래스를 정의한다.

 

이전까지 포스팅을 봤다면 충분히 이해할 내용이다.

 

package com;


import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;

public class AlertBox {
    public static void display(String title, String msg){
        Stage window = new Stage();

        window.initModality(Modality.APPLICATION_MODAL);
        window.setTitle(title);
        window.setMinWidth(300);

        Label label = new Label();
        label.setText(msg);
        Button closeButton = new Button("Close the window");
        closeButton.setOnAction(e -> window.close());

        VBox layout = new VBox(10);
        layout.getChildren().addAll(label,closeButton);
        layout.setAlignment(Pos.CENTER);

        Scene scene = new Scene(layout, 300, 500);
        window.setScene(scene);
        window.showAndWait();
    }
}

 

여기서 modality 를 설정해주면 새로운 창을 닫기 전까지 원래 창(root)을 조작할 수 없다. 새로운 AlertBox 창이 닫혀야 된다. 아래의 코드로 설정한다.

 

window.initModality(Modality.APPLICATION_MODAL);

 

 

* 다음은 root 윈도우다. 이전 까지의 포스팅과 같은 코드이다.

 

다음의 코드는 위의 AlertBox의 메서드를 실행시킨다.

 button.setOnAction(e -> AlertBox.display("Window", "alert box is awesome"));
package com;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application  {

    Stage window;
    Scene scene;
    Button button;

    @Override
    public void start(Stage primaryStage) throws Exception{
        window = primaryStage;
        window.setTitle("Title Here");

        button = new Button("CLICK");
        button.setOnAction(e -> AlertBox.display("Window", "alert box is awesome"));

        StackPane layout = new StackPane();
        layout.getChildren().add(button);
        scene = new Scene(layout, 500, 300);
        window.setScene(scene);
        window.show();
    }

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

 

1. 실행하면 root 윈도우를 표시한다

 

 

2. 버튼을 클릭하면 서브 윈도우가 나타난다.

 

 

 

3. 서브윈도우가 닫히기 전까지는 root 윈도우의 조작이 되지 않는다. modality 설정

 

4. sub 윈도우 종료 root 윈도우 순서로 종료한다.

 

* Stage 클래스를 두개 사용하여 sub 윈도우와 root 윈도우를 동시에 열어봤다.

 

내가 사용하려는 윈도우의 숫자만큼 Stage 클래스가 필요하다는 점을 알 수 있다.

 

 

윈도우 간의 통신

 

이번의 예제는 윈도우 간의 통신을 한다. 우선 AlertBox 와 비슷한 ConfirmBox 를 만든다. 흔히 우리가 yes or no 를 묻는 윈도우 창이다. Confirmation Window 라고 부른다. Yes 입력시에 true 를 No 에 false 를 리턴한다. 아까 AlertBox 와는 다르게 리턴형을 불린으로 정했다. 코드는 변수와 메서드를 따라가며 읽는다. 변수의 이름을 읽으면 자기 자신을 충분히 설명하도록 작성하는게 좋다.

 

많은 개발자들이 변수의 작성에 어려움을 겪고 있다. 좋은 변수의 작성은 곧 쉽게 읽혀지는 좋은 코드로 확장성이 좋아짐을 뜻한다.

 

package com;

import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;


public class ConfirmBox {

    static boolean answer;

    public static boolean display(String title, String msg){
        Stage window = new Stage();
        window.initModality(Modality.APPLICATION_MODAL);
        window.setTitle(title);
        window.setMinWidth(300);

        Label label = new Label();
        label.setText(msg);

        // create 2 buttons

        Button yesButton = new Button("Yes");
        Button noButton = new Button("No");

        yesButton.setOnAction(e -> {
            answer = true;
            window.close();
        });
        noButton.setOnAction(e -> {
            answer = false;
            window.close();
        });

        VBox layout = new VBox(10);
        layout.getChildren().addAll(label, yesButton, noButton);
        layout.setAlignment(Pos.CENTER);

        Scene scene = new Scene(layout, 300, 500);
        window.setScene(scene);
        window.showAndWait();

        return answer;
    }
}

이것을 받는 코드를 Main 클래스에 추가한다.

 

람다 식이 요긴하게 쓰인다. 람다식을 여러 줄에 입력하기 위해 e -> { } 대괄호의 사용법을 잘 봐둔다.

 

이렇게 하면 코드가 길어져도 인터페이스를 구현할 필요가 없기 때문에 유용하다.

 

어떤 버튼을 클릭했느냐에 따라서 콘솔창에 결과가 다르게 나타나는 것을 확인 할 수 있다. 콘솔창의 변화가 확인되면 흐름을 잡은 것이다. 이제 필요한 코드를 작성하여 변수에 연결시키면 프로그램의 기능을 구현할 수 있다.

공유하기

facebook twitter kakaoTalk kakaostory naver band