09. JavaFX 다이얼로그
다이얼로그(Dialog)는 주 윈도우에서 알림을 표시하거나 사용자의 입력을 받기 위해 실행되는 서브 윈도우입니다. 다이얼로그를 띄우는 주 윈도우를 소유자(Owner) 윈도우라고 합니다.
다이얼로그 종류
- 모달(Modal): 다이얼로그를 닫기 전까지 소유자 윈도우를 사용할 수 없음.
- 모달리스(Modeless): 다이얼로그가 떠 있어도 소유자 윈도우를 계속 사용할 수 있음.
JavaFX는 FileChooser, DirectoryChooser, Popup, stage를 이용한 커스텀 다이얼로그 등을 제공합니다.
1. FileChooser, DirectoryChooser
FileChooser
파일 열기/저장을 위한 다이얼로그입니다.
FileChooser fileChooser = new FileChooser();
// 확장자 필터 설정
fileChooser.getExtensionFilters().addAll(
new ExtensionFilter("Text Files", "*.txt"),
new ExtensionFilter("Image Files", "*.png", "*.jpg", "*.gif"),
new ExtensionFilter("All Files", "*.*")
);
// 파일 열기 다이얼로그 실행
File selectedFile = fileChooser.showOpenDialog(primaryStage);
if (selectedFile != null) {
System.out.println("선택된 파일: " + selectedFile.getPath());
}
// 파일 저장 다이얼로그 실행
File savedFile = fileChooser.showSaveDialog(primaryStage);
DirectoryChooser
디렉토리를 선택하기 위한 다이얼로그입니다.
DirectoryChooser directoryChooser = new DirectoryChooser();
File selectedDir = directoryChooser.showDialog(primaryStage);
if (selectedDir != null) {
System.out.println("선택된 폴더: " + selectedDir.getPath());
}
2. Popup
Popup은 투명한 컨테이너를 제공하는 모달리스 다이얼로그입니다. 툴팁, 알림 메시지, 드롭다운 메뉴 등에 사용됩니다.
- 장식(제목 표시줄, 닫기 버튼 등)이 없습니다.
autoHide속성을true로 설정하면 포커스를 잃을 때 자동으로 닫힙니다.
예제: 알림 팝업
popup.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.image.Image?>
<?import javafx.geometry.Insets?>
<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>
Java 코드
// Popup 생성
Popup popup = new Popup();
// FXML 로드
HBox hbox = (HBox) FXMLLoader.load(getClass().getResource("popup.fxml"));
ImageView imageView = (ImageView) hbox.lookup("#imgMessage");
imageView.setImage(new Image(getClass().getResource("images/dialog-info.png").toString()));
imageView.setOnMouseClicked(event -> popup.hide()); // 클릭 시 닫기
Label lblMessage = (Label) hbox.lookup("#lblMessage");
lblMessage.setText("메시지가 왔습니다.");
// Popup 설정
popup.getContent().add(hbox);
popup.setAutoHide(true); // 포커스 이동 시 자동 닫힘
popup.show(primaryStage); // 실행
3. 커스텀 다이얼로그 (Custom Dialog)
Stage를 직접 생성하여 원하는 형태의 다이얼로그를 만들 수 있습니다.
// Stage 생성 및 스타일 설정
Stage dialog = new Stage(StageStyle.UTILITY);
dialog.initModality(Modality.WINDOW_MODAL); // 모달 설정
dialog.initOwner(primaryStage); // 소유자 윈도우 설정
dialog.setTitle("확인");
// 내용 설정 (FXML 로드)
Parent parent = FXMLLoader.load(getClass().getResource("custom_dialog.fxml"));
Scene scene = new Scene(parent);
dialog.setScene(scene);
dialog.setResizable(false); // 크기 조절 불가
// 다이얼로그 실행
dialog.show();
StageStyle 열거 상수
| 상수 | 설명 | | :————– | :——————————————- | | DECORATED | 일반적인 윈도우 (흰 배경, 제목줄, 장식 있음) | | UNDECORATED | 흰 배경, 제목줄 없음 | | TRANSPARENT | 투명 배경, 제목줄 없음 | | UNIFIED | DECORATED와 동일하나 내용물 경계선 없음 | | UTILITY | 흰 배경, 제목줄에 타이틀과 종료 버튼만 있음 |
4. PrimaryStage 얻기
컨트롤러에서 다이얼로그를 띄우려면 primaryStage 참조가 필요합니다.
방법 1: 메인 클래스에서 Setter 주입
// Main
FXMLLoader loader = new FXMLLoader(getClass().getResource("root.fxml"));
Parent root = loader.load();
RootController controller = loader.getController();
controller.setPrimaryStage(primaryStage); // Setter 호출
// Controller
private Stage primaryStage;
public void setPrimaryStage(Stage primaryStage) {
this.primaryStage = primaryStage;
}
방법 2: Node로부터 얻기 (이벤트 핸들러 내에서)
// 버튼 클릭 이벤트 핸들러 등에서 사용 가능
public void handleButton(ActionEvent e) {
// 이벤트가 발생한 컨트롤(button)이 속한 Scene의 Window를 얻음
Stage primaryStage = (Stage) ((Node)e.getSource()).getScene().getWindow();
// 또는
// Stage primaryStage = (Stage) button.getScene().getWindow();
}
주의: initialize() 메소드 시점에는 무대가 준비되지 않았으므로 이 방법을 사용할 수 없습니다.