忍者ブログ

≪ 前の記事

次の記事 ≫

  • [PR]

    ×

    [PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

    comments

  • FXMLの要素・属性定義

    FXML内でよく目にする「fx:controller」や「fx:id」といった要素・属性がありますが、今回はその「fx:」を接頭辞に持つ要素・属性についてまとめます。

    fx:controller	Controllerの参照
    ・fx:id		Controller内の変数の参照
    ・fx:constant	クラス定数の参照
    ・fx:define		メインの構造体から参照するオブジェクトを定義する
    ・fx:reference	既存のfx:id要素を参照する
    ・fx:copy		既存のfx:id要素をコピーする
    ・fx:factory	クラスインスタンスを作成する
    ・fx:value		クラスインスタンスの値を設定する
    ・fx:script		スクリプトを埋め込む
    ・fx:include	別のFXMLファイルを読み込む
    ・fx:root		ルートコンテナを設定する
    



    拍手[0回]


    fx:controller

    FXMLからJavaプログラムを参照するための宣言で、
    記述方式は「fx:controller="パッケージ名.クラス名"」
    他ファイルの参照ではあるが、ファイルの拡張子「.java」は記述不要。



    fx:id

    Controllerに登録した変数名をこのfx:id要素に書くことで
    FXMLとJavaプログラムとを繋げることができる。
    Controllerにはfx:idとの連携と分かるよう「@FXML」アノテーションを付ける

    どうやらFXML内で定義したものよりも、
    Controller内のinitializeで初期化したものの方が優先度は高いらしい。
    <VBox prefWidth="400" prefHeight="200" xmlns:fx="http://javafx.com/fxml/" fx:controller="application.Controller">
    	<children>
    		<Button fx:id="button0"/>
    		<Button fx:id="button1"/>
    		<Button text="BUTTON2" fx:id="button2"/>
    		<Button prefHeight="10" prefWidth="20" fx:id="button3"/>
    	</children>
    </VBox>
    
    public class Controller implements Initializable{
    	@FXML Button button0;
    	@FXML Button button1;
    	@FXML Button button2;
    	@FXML Button button3;
    	
    	public void initialize(URL url, ResourceBundle resourceBundle) {
    		//initializeは変数の初期化をするメソッド
    		button0.setText("Button0");
    		button1.setText("Button1");
    		button2.setText("Button2");
    		button3.setText("Button3");
    
    		button0.setPrefSize(200, 50);
    		button1.setPrefSize(200, 50);
    		button2.setPrefSize(200, 50);
    		button3.setPrefSize(200, 50);
    	}
    }
    


    fx:constant

    クラス定数を参照するために使用する。
    「ボタンの大きさは固定で ○○px 」というようにルール化する時に有効。

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import javafx.scene.layout.*?>
    <?import javafx.scene.control.*?>
    <?import application.InitialValue?>
    	
    <VBox prefWidth="400" prefHeight="200" xmlns:fx="http://javafx.com/fxml/">
    	<children>
    		<Button text="Button">
    			<prefWidth>
    				<InitialValue fx:constant="BUTTON_W"/>
    			</prefWidth>
    			<prefHeight>
    				<InitialValue fx:constant="BUTTON_H"/>
    			</prefHeight>
    		</Button>
    	</children>
    </VBox>
    
    package application;
    
    public class InitialValue{
    	public static final int BUTTON_W = 100;
    	public static final int BUTTON_H = 40;
    }
    



    fx:define

    FXMLの階層外で前もって宣言しておくための要素。
    ボタンや画像などのレイアウト部品だけでなく、ラジオボタンのグループなどもこれを使うことでFXML内に書くことが出来る。



    fx:reference

    既存の要素を参照する。
    ただし、1つの要素を使用できるのは1回のみで再利用は出来ない。

    <VBox prefWidth="400" prefHeight="200" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.SampleController">
    	<fx:define>
    		<Text fx:id="text" text="テキスト"/>
    	</fx:define>
    	<children>
    		<fx:reference source="text"/>
    	</children>
    </VBox>
    



    fx:copy

    既存の要素のコピーを作成する・・・らしいが、まだ実装されていない。



    fx:factory

    FXML上でオブジェクトを生成することが出来る。
    後述の fx:value が必須?



    fx:value

    String型のインスタンスを生成することが出来る。
    valueOf(String)メソッドが提供されているクラスしか使用できない。

    <VBox prefWidth="400" prefHeight="200" xmlns:fx="http://javafx.com/fxml/1">
    	<children>
    		<ChoiceBox>
    			<items>
    				<FXCollections fx:factory="observableArrayList">
    					<String fx:value="choice0"/>
    					<String fx:value="choice1"/>
    					<String fx:value="choice2"/>
    				</FXCollections>
    			</items>
    		</ChoiceBox>
    	</children>
    </VBox>
    



    fx:script

    JavaScript等のスクリプトを埋め込むための要素。
    最初に<?language    ?>タグでどのスクリプト言語を使用するか宣言し、スクリプトを配置したいウィンドウペイン直下に<fx:script>を追加する。
    source属性でスクリプトを記述したファイルを読み込むか、
    <fx:script>~</fx:script>内に直接コードを書くことも出来る。

    <?xml version="1.0" encoding="UTF-8"?>
    <?language javascript?>
    	
    <?import javafx.scene.layout.*?>
    <?import javafx.scene.control.*?>
    	
    <VBox prefWidth="400" prefHeight="200" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.SampleController">
    	<fx:script source="sample.js" charset="UTF-8"/>
    	<children>
    		<Button text="Click Here" onAction="buttonAction();"/>
    	</children>
    </VBox>
    



    fx:include

    別のFXMLファイルをインポートする。

    <VBox prefWidth="400" prefHeight="200" xmlns:fx="http://javafx.com/fxml/1" ">
    	<children>
    		<fx:include source="menubar.fxml"/>
    		<Button text="Button"/>
    	</children>
    </VBox>
    <MenuBar xmlns:fx="http://javafx.com/fxml/1">
    	<menus>
    		<Menu text="メニュー1">
    			<items>
    				<MenuItem text="メニューアイテム1-1"/>
    				<MenuItem text="メニューアイテム1-2"/>
    			</items>
    		</Menu>
    		<Menu text="メニュー2">
    			<items>
    				<MenuItem text="メニューアイテム2-1"/>
    				<MenuItem text="メニューアイテム2-2"/>
    			</items>
    		</Menu>
    		<Menu text="メニュー3">
    			<items>
    				<MenuItem text="メニューアイテム3-1"/>
    				<MenuItem text="メニューアイテム3-2"/>
    			</items>
    		</Menu>
    	</menus>
    </MenuBar>
    



    fx:root

    コンテナクラス(下記の例ではVBox)をfx:rootに置き換える

    使用方法としては、まず fx:root の type にコンテナクラスを設定します。
    そうしたら type 属性に、コンテナクラスを継承した Controllerクラス(下記ではSampleComponent)を作成し、最後にSampleComponent のインスタンスを生成して Scene に読みこめば完了。

    今の自分ではこれの価値が見出だせません。
    root要素を使うことでクラスのインスタンスを作るだけでFXMLとControllerが読み込むことができ、メインクラスを簡略化させることが目的?

    <fx:root type="javafx.scene.layout.VBox" prefWidth="400" prefHeight="200" xmlns:fx="http://javafx.com/fxml/">
    		<Button fx:id="button0"/>
    </fx:root>
    

    class SampleComponent extends VBox implements Initializable{
    	@FXML Button button0;
    	
    	public void initialize(URL arg0, ResourceBundle arg1) {
    		button0.setText("Button0");
    		button0.setPrefSize(200, 50);
    	}
    	
    	SampleComponent(){
    		try {
    			FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Test.fxml"));
    			fxmlLoader.setRoot(this);
    			fxmlLoader.setController(this);
    			fxmlLoader.load();
    		} catch(Exception e) {
    			e.printStackTrace();
    		}
    	}
    }
    

    public class Main extends Application {
    	@Override
    	public void start(Stage primaryStage) {
    		try {
    			SampleComponent component = new SampleComponent();
    			Scene scene = new Scene(component,400,200);
    			primaryStage.setScene(scene);
    			primaryStage.show();
    		} catch(Exception e) {
    			e.printStackTrace();
    		}
    	}
    	public static void main(String[] args) {
    		launch(args);
    	}
    }
    

    0 comments

Comment