JavaFXのTips¶
オブジェクト参照¶
ウィンドウ関係のオブジェクト参照¶
stageの参照を取得したい¶
ダイアログ表示等で、stageの参照を必要とする箇所がありますが、FXMLと一緒に生成されるコントローラーではstageの参照を保持していません。
コントロールからシーンを辿ってstageを取得¶
private Stage getStage() {
return (Stage) label.getScene().getWindow();
}
ただし、初期化中(例えば、コントローラのinitializeメソッド中)でこの処理を実行すると、まだsceneがstageに登録されていないため、NullPointerExceptionが発生します。
イベントハンドラーの中で呼び出すようにします。
または次のTipsを参照ください。
sceneの参照を取得したい¶
FXMLと対になるコントローラーのinitializeメソッドは、ルートノードがまだsceneにセットされる前に(FXMLLoaderでロードされる時点で)実行されます。
NodeクラスのsceneProperty を使うと、sceneがノードにセットされたタイミングを取れるので、initializeメソッドの中でscenePropertyの変化をイベントとして受け取り処理を記述することで、scene参照を利用する処理を書くことができます。
@Override
public void initialize(URL url, ResourceBundle rb) {
root.sceneProperty().addListener((observable, oldScene, newScene) -> {
if (newScene != null) {
// scene がセットされた
}
});
:
- このタイミングでsceneのgetWindow()を呼ぶと、まだsceneがStageにセットされる前なのでgetWindow()がnullを返します。initializeメソッド内で上述のコードでsceneを取得し、インスタンスフィールドに格納、Stageを使う段階でインスタンスフィールドのsceneからgetWindow()で取得します。
スタイルシート¶
テーマ¶
JavaFXには、全体のルック・アンド・フィールを定義する、SwingでいうLook & Feelに相当するThemeがあります。
定義済みテーマの指定¶
JavaFX 2では、Caspianと呼ばれるテーマがデフォルトでした。JavaFX 8ではModenaと呼ばれるテーマがデフォルトです。これは次のコードのように変更できます。
public class MyApplication extends Application {
:
@Override
public void start(Stage stage) throws Exception {
setUserAgentStylesheet(STYLESHEET_CASPIAN);
:
}
:
}
Applicationクラスには、次の2つの定数が定義されています(Java SE 8)。
- STYLESHEET_CASPIAN
- STYLESHEET_MODENA
スタイルシートの指定¶
画面全体に適用するスタイルシートの指定¶
APIで指定¶
APIで指定する場合、Sceneインスタンスに設定します。
Scene scene = ...
scene.getStylesheets().addAll("alfa.css", "bravo.css");
ただし、ここで指定する文字列はURLである必要があります。カレントディレクトリに置いても認識されません。次のようにエラーとなってしまいます。
8 01, 2014 10:27:26 午前 com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged 警告: Resource "alfa.css" not found.
上記コード例のように指定する場合、クラスパスのルート直下に置きます。
NetBeansのantプロジェクトではsrcフォルダ直下に置くことで、ビルド時にjarファイルのルートに配置されます。
FXMLで指定¶
FXMLで指定する場合、FXMLルートコンテナの子要素に記述します1。
<BorderPane>
:
<stylesheets>
<URL value="@alfa.css"/>
<URL value="@bravo.css"/>
</stylesheets>
</BorderPane>
パスなしでファイル名を指定するときは、このFXMLと同じ場所に置きます。
SceneBuilderで指定する場合、ルートコンテナのプロパティからJavaFX CSSグループのStylesheetsに指定します。次にSceneBuilderの指定画面(部分抜粋)を示します。
参考¶
JavaFX 2で始めるGUI開発 第9回 CSSによるスタイリング
レイアウト¶
画像¶
画像生成¶
シーンを画像に出力したい(画面キャプチャ)¶
WritableImage snapshot = scene.snapshot(null);
ImageIO.write(SwingFXUtils.fromFXImage(snapshot, null), "png", new File("scene.png"));
画像読み込み¶
ファイルから画像を読み込みたい¶
Imageクラスを使います。
InputStreamまたは文字列でURLを指定します。
- カレントディレクトリにあるファイルをURLで指定する場合
new Image("file:clockDial.png")
座標変換¶
拡大・縮小¶
ノードの左上位置を固定して拡大・縮小したい¶
あるノードに対して、scaleX()やscaleY()メソッドを呼び拡大または縮小すると、そのノードの中心の位置が拡大縮小の中心となります。
ここで、ノードの配置で左上隅の位置を保ったまま拡大縮小させるときは、拡大縮小の中心点(pivot)を、ノードの左上隅(通常は(0,0))に指定します。ただし、scaleXやscaleYメソッドにはpivotを指定する方法がないので、Scaleインスタンスを作って、ノードにgetTransforms().add(scale) で設定します。