아이디어는 팝업 Stage
의 onCloseRequestProperty 속성을 사용하는 것입니다.
이 창을 닫으라는 외부 요청이있을 때 호출됩니다. 설치된 이벤트 처리기는 수신 이벤트를 사용하여 창을 닫지 못하게 할 수 있습니다. 조건 (않도록, 하나 개의 카드에서 귀하의 경우를 선택한 경우) 경우는 Stage
의 폐쇄를 중단 할 수 있습니다이 속성으로
은 WindowEvent
에 consume를 호출하여 충족되지 않습니다.
참고 : 문서 상태로는 다음 요청이 외부 경우에만 유효합니다, 그래서 당신이 Stage
의 close 메서드를 호출 할 경우, 첨부 된 리스너가 실행되지 않습니다. 이 방법을 호출하는 대신 해결 방법으로 WindowEvent.WINDOW_CLOSE_REQUEST 이벤트를 수동으로 시작할 수 있습니다.
예 :
public class PopUpApp extends Application {
Stage popupStage;
Stage primaryStage;
@Override
public void start(Stage stage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root, 400, 400);
primaryStage = stage;
initPopUpStage();
// When the Pop-Up stage is showing, do not handle any action on the
// main GUI
root.disableProperty().bind(popupStage.showingProperty());
Button b = new Button("Open deck");
b.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
// Add some ToggleButtons to simulate the cards
VBox vbox = new VBox();
vbox.setAlignment(Pos.CENTER);
List<ToggleButton> toggles = new ArrayList<ToggleButton>();
for (int i = 0; i < 4; i++) {
ToggleButton tb = new ToggleButton("Card " + i + 1);
toggles.add(tb);
}
vbox.getChildren().addAll(toggles);
Scene sc = new Scene(vbox, 300, 300);
popupStage.setScene(sc);
// On close request check for the condition
popupStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent event) {
Boolean readytoClose = false;
for (ToggleButton toggle : toggles) {
if (toggle.isSelected()) {
readytoClose = true;
break;
}
}
// Consume the event a show a dialog
if (!readytoClose) {
event.consume();
Alert alert = new Alert(AlertType.INFORMATION,
"At least one card has be to be selected!");
alert.showAndWait();
}
}
});
popupStage.show();
}
});
root.setCenter(b);
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
private void initPopUpStage() {
popupStage = new Stage();
popupStage.initOwner(primaryStage);
popupStage.initStyle(StageStyle.UNDECORATED);
// On focus loss, close the window
popupStage.focusedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
// Rather than popupStage.close(); fire the event manually
if (!newValue)
popupStage.fireEvent(new WindowEvent(popupStage, WindowEvent.WINDOW_CLOSE_REQUEST));
}
});
}
public static void main(String[] args) {
launch(args);
}
}
업데이트 :
주요 Stage
내가 추가 한 사용할 수없는이 줄을 만들려면 :
root.disableProperty().bind(popupStage.showingProperty());
이는 동안 루트 BorderPane
을 해제합니다 팝업 단계가 표시됩니다. 팝업 창이 닫히 자마자 기본 창이 다시 활성화됩니다.
감사합니다. 이런 종류의 기능을 위해 onCloseRequest를 사용할 수 있는지 전혀 몰랐습니다. 그래도 엄청난 문제 야. 'Modality '가 없다면 사용자는 팝업창이 나더라도 나머지 응용 프로그램과 통신 할 수 있습니다. 그들은 갑판을 50 번 클릭하고 50 개의 창을 만들 수 있습니다. 내 현재의 아이디어는 내 기본 GUI 클래스에 정적 부울 변수를 갖는 것입니다.이 변수는 "현재 표시된 창입니까?"라고 말합니다. 이 변수가 true이면 기본 스테이지에서 이벤트 핸들러를 활성화하지 마십시오. 그러나 그것은 일종의 고통입니다. 다른 아이디어? – Hatefiend
답변에서 내 업데이트를 참조하십시오. – DVarga
굉장합니다. 마지막 한가지. 나는 이것과 같이 보이고 숨길 수있는 여섯 개의 독특한 창을 가지고 있으며, 나는 여섯 명 모두가 그런 식으로 묶일 필요가있다. 지금은'.bind()'를 호출하면 이전의'bind'를 덮어 씁니다. 그리고 바운드 된 마지막 속성 만이 비활성화 된 속성에 영향을줍니다. 여러 항목을 어떻게 바인딩 할 수 있습니까? – Hatefiend