JavaFXでフルスクリーンの切り換えイベントを監視する方法メモ

JavaFX で、ウィンドウのフルスクリーン表示が切り換わる際のイベントを監視して任意の処理を実行する方法のメモ。
Javadoc を眺めてたら気づいた方法なので、他に良い方法があるかもしれない。


#環境
##OS
Windows7 64bit

##Java
1.7.0_25

#実装
##起動用クラス
```java:Main.java
package fx;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {
    
    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        FXMLLoader loader = new FXMLLoader(FullScreenController.getFxmlUrl());
        
        Parent parent = (Parent) loader.load();
        
        FullScreenController controller = loader.getController();
        controller.setStage(stage);
        
        Scene scene = new Scene(parent);
        stage.setScene(scene);
        stage.setTitle("Full Screen Sample");
        stage.show();
    }
}
```

##コントローラクラス
```java:FullScreenController.java
package fx;

import java.net.URL;

import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.scene.control.MenuBar;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class FullScreenController {
    
    private Stage stage;
    
    @FXML private VBox vBox;
    @FXML private MenuBar menu;
    
    @FXML
    public void switchFullScreen() {
        this.stage.setFullScreen(!this.stage.isFullScreen());
    }
    
    public void setStage(Stage stage) {
        this.stage = stage;
        
        ReadOnlyBooleanProperty fullScreenProperty = this.stage.fullScreenProperty();
        fullScreenProperty.addListener(new ChangeListener<Boolean>() {
            @Override
            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean isFullScreen) {
                if (isFullScreen) {
                    vBox.getChildren().remove(menu);
                } else {
                    vBox.getChildren().add(0, menu);
                }
            }
        });
    }

    public static URL getFxmlUrl() {
        return FullScreenController.class.getResource("FullScreen.fxml");
    }
}
```

##FXML
```xml:FullScreen.fxml
<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.text.*?>

<VBox fx:id="vBox" prefHeight="400.0" prefWidth="640.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="fx.FullScreenController">
  <children>
    <MenuBar id="menuBar" fx:id="menu" VBox.vgrow="NEVER">
      <menus>
        <Menu mnemonicParsing="false" text="File" />
        <Menu mnemonicParsing="false" text="Edit" />
        <Menu mnemonicParsing="false" text="Help" />
      </menus>
    </MenuBar>
    <BorderPane id="button" prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: lightblue;" VBox.vgrow="ALWAYS">
      <center>
        <Button id="button" mnemonicParsing="false" onAction="#switchFullScreen" prefHeight="98.0" prefWidth="236.0" text="Full Screen">
          <font>
            <Font size="30.0" />
          </font>
        </Button>
      </center>
    </BorderPane>
  </children>
</VBox>
```

##説明
`Stage` クラスには `fullScreenProperty` という `ReadOnlyBooleanProperty` 型のフィールドが存在する。
この `ReadOnlyBooleanProperty` クラスは `ObservableValue` インターフェースを実装していて、 `addListener(ChangeListener)` メソッドでリスナーを登録すれば、プロパティ値の変更を監視できる。

そのリスナーを登録しているのが、 `FullScreenController.java` の以下の部分。

```java:プロパティ値のリスナーを登録する
    public void setStage(Stage stage) {
        this.stage = stage;
        
        ReadOnlyBooleanProperty fullScreenProperty = this.stage.fullScreenProperty();
        fullScreenProperty.addListener(new ChangeListener<Boolean>() {
            @Override
            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean isFullScreen) {
                if (isFullScreen) {
                    vBox.getChildren().remove(menu);
                } else {
                    vBox.getChildren().add(0, menu);
                }
            }
        });
    }
```

フルスクリーンが切り替わるタイミングで、メニューバーの除去と追加を実行している。

#実行結果
##ウィンドウ表示
![ウィンドウ表示](https://qiita-image-store.s3.amazonaws.com/0/28302/9c0e65d5-5b29-7d18-65d0-67ebaed4d0e2.jpeg)

##全画面表示
![全画面表示](https://qiita-image-store.s3.amazonaws.com/0/28302/2fadbf9f-4fbb-fc98-2e12-3eb34d680b6d.jpeg)

#参考
+ [Stage#isFullScreen (JavaFX 2.2)](http://docs.oracle.com/javafx/2/api/javafx/stage/Stage.html#fullScreenProperty)
+ [ReadOnlyBooleanProperty (JavaFX 2.2)](http://docs.oracle.com/javafx/2/api/javafx/beans/property/ReadOnlyBooleanProperty.html)
+ [ObservableValue (JavaFX 2.2)](http://docs.oracle.com/javafx/2/api/javafx/beans/value/ObservableValue.html)
+ [ChangeListener (JavaFX 2.2)](http://docs.oracle.com/javafx/2/api/javafx/beans/value/ChangeListener.html)