2016-06-15 6 views
1

を使用せずにステージを変えるからのブロックユーザーIは、次のようなアプリケーションを持っている:のJavaFX - MODAL

enter image description here

ユーザーはカードのデッキをクリックすると、それは新しいステージを開きます。

このステージは、次のいずれかの方法で閉じることができます。

  • は、右のステージをクリックしてください。

  • ステージの外側をクリックします(フォーカスが失われたときの均等ハンドラーがあります)。

しかし、時々私は、このウィンドウを使用してデッキから1枚以上のカードを選択するようにユーザーを必要としています。私は少なくとも1枚のカードを選択するまで、彼が窓を閉じるのを許可したくありません。つまり、MODALを使用して彼のステージ(My Applicaiton)にアクセスできないようにする必要がありました。 MODALの問題は、ステージの外をクリックすることで、彼ができるようにしたいときでさえ、彼が前にできるようにウィンドウから出ることは決してできません。彼は今すぐ右クリックするだけで残すことができます。私はボタンを追加することができたが、私は本当にむしろそうではなかった。

私は私の問題を十分に説明してくれることを願っています。私は何をお勧めしますか? MODALせずに前の段階に戻ることをユーザーにブロックする方法はありますか?ステージが表示された後にModalityを変更することもできないため、動作しません。

ありがとうございます!

答えて

2

ポップアップStageonCloseRequestPropertyプロパティを使用することです。

このウィンドウを閉じる外部要求があるときに呼び出されます。 イベントハンドラがインストールされていると、 受信イベントを消費してウィンドウが閉じることを防ぐことができます。条件(LEST一枚のカードで、あなたのケースでは、選択されている)場合は、Stageの閉鎖を中断することができます。このプロパティを使用して

WindowEventconsumeを呼び出すことによって満たされていません。

注:ドキュメントの状態として:あなたはStagecloseメソッドを呼び出した場合、添付のリスナーが実行されないことになるので、要求は、外部にある場合にのみ有効です。このメソッドを呼び出すのではなく、解決策としてWindowEvent.WINDOW_CLOSE_REQUESTイベントを手動で起動することができます。一方、これはルートBorderPaneが無効になります

root.disableProperty().bind(popupStage.showingProperty()); 

:私は、この行を追加した主なStageが使用できないようにするに

例:

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); 
    } 
} 

更新ポップアップステージが表示されます。ポップアップウィンドウが閉じられるとすぐに、メインウィンドウが再度有効になります。

+0

ありがとうございます。私はこの種の機能のためにonCloseRequestを使うことはできないと思っていました。しかし、ここには大きな問題がある。 「モダリティ」なしでは、ユーザは、ポップアップ段階があるにもかかわらず、依然としてアプリケーションの残りの部分と通信することが許可される。彼らはデッキを50回クリックして50の窓を作った。私の現在のアイデアは、メインのGUIクラスに静的なブール変数を持たせることです。これは "現在表示されているウィンドウですか?"その変数がtrueの場合、プライマリステージでイベントハンドラを有効にしないでください。しかし、それは一種の痛みです。他のアイデア? – Hatefiend

+0

答えの私の更新を見てください。 – DVarga

+0

最後に一つだけ。私は6つのユニークなウィンドウが表示され、このように非表示になり、私はそれらのすべての6つのようにバインドする必要があります。今すぐ '.bind()'を呼び出すと、前の 'bind'を上書きし、正しくバインドされた最後のプロパティだけが、無効なプロパティに影響を与えます。どのように私は複数をバインドできますか? – Hatefiend