【JavaFX】さくっとコンボボックスに項目を設定してみる

2017年9月28日Java,開発

おはようございます。

今回は、JavaFXの基本的な構成や仕組みなどを学ぶために
とりあえずコンボボックスに項目を設定して選択できるようにしてみます。

開発環境については以前の記事を参考にしてください。

スポンサーリンク

画面の作成

画面は SceneBuilder にて作成します。
(WPF で作成した画面と同等のものを作ってみたいと思います。)

WPF編はこちら

初期状態では、「BorderPane」が設置されていますが、
それを削除して「AnchorPane」を設置し、その上にコントロールを配置していきます。

AnchorPane というのは、
簡単に言うとコントロールを座標(絶対位置)で配置できるレイアウトになります。

その他のレイアウトについてはそのうち紹介できればします。

画面へコントロールを配置

SceneBuilder上で CTRL + P を押すとプレビュー表示することができます。

プレビュー表示

eclipse で Java プリケーションの実行をしなくても起動後の画面がサクッと表示されます。
(プログラムは動かないのでコントロールの位置確認のみ)

Sample.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane fx:id="mainPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="350.0" prefWidth="530.0"
        xmlns="http://javafx.com/javafx/8.0.111"
        xmlns:fx="http://javafx.com/fxml/1"
        fx:controller="application.SampleController"><!-- ← コントローラクラスと紐付 -->
        <children>
                 <!-- 名前 -->
                <Label fx:id="lbName" layoutX="14.0" layoutY="33.0" text="名前:" />
                <TextField fx:id="txName" layoutX="58.0" layoutY="29.0" />
                 <!-- 種別 -->
                <Label fx:id="lbKind" layoutX="221.0" layoutY="33.0" text="種別:" />
                <ComboBox fx:id="cbKind" layoutX="264.0" layoutY="29.0" prefWidth="150.0" />
                 <!-- 検索ボタン -->
                <Button fx:id="btSearch" layoutX="456.0" layoutY="29.0" mnemonicParsing="false" text="検索" />
                 <!-- 一覧 -->
                <TableView fx:id="tvCat" layoutX="14.0" layoutY="63.0" prefHeight="273.0" prefWidth="498.0">
                        <columns>
                                <TableColumn maxWidth="50.0" minWidth="50.0" prefWidth="50.0" resizable="false" text="No" />
                                <TableColumn maxWidth="100.0" minWidth="100.0" prefWidth="100.0" text="名前" />
                                <TableColumn maxWidth="40.0" minWidth="40.0" prefWidth="40.0" text="性別" />
                                <TableColumn maxWidth="40.0" minWidth="40.0" prefWidth="40.0" text="年齢" />
                                <TableColumn minWidth="120.0" prefWidth="120.0" text="種別" />
                                <TableColumn minWidth="145.0" prefWidth="147.0" text="好物" />
                        </columns>
                         <columnResizePolicy>
                                <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
                         </columnResizePolicy>
                </TableView>
         </children>
</AnchorPane>

コントローラクラスの実装

JavaFX では、
基本的に fxml (画面定義)と対応するコントローラー(クラス)を作成し、
コントローラーにてイベントなどを処理するような構成となります。

fxml に記述した

    fx:controller="application.SampleController"

でコントローラを指定し、コントローラークラスには
画面に設置したコントロールをメンバーとして定義することが必要。

こうすることで、
コントローラークラスにて画面のコントロールを操作することが可能となります。

SampleController.java

package application;

import java.net.URL;
import java.util.ResourceBundle;

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;

public class SampleController implements Initializable{

        /** パネル:メイン */
        @FXML
        private AnchorPane mainPane;

        /** ラベル:名前 */
        @FXML
        private Label lbName;

        /** テキストフィールド:名前 */
        @FXML
        private TextField txName;

        /** ラベル:種別 */
        @FXML
        private Label lbKind;

        /** コンボボックス:名前 */
        @FXML
        private ComboBox<String> cbKind;

        /** ボタン:検索 */
        @FXML
        private Button btSearch;

        /** テーブルビュー:一覧 */
        @FXML
        private TableView<String> tvCat;

        /**
         * @return mainPane
         */
        public AnchorPane getMainPane() {
                return mainPane;
        }

        /**
         * @param mainPane セットする mainPane
         */
        public void setMainPane(AnchorPane mainPane) {
                this.mainPane = mainPane;
        }

        /**
         * @return lbName
         */
        public Label getLbName() {
                return lbName;
        }

        /**
         * @param lbName セットする lbName
         */
        public void setLbName(Label lbName) {
                this.lbName = lbName;
        }

        /**
         * @return txName
         */
        public TextField getTxName() {
                return txName;
        }

        /**
         * @param txName セットする txName
         */
        public void setTxName(TextField txName) {
                this.txName = txName;
        }

        /**
         * @return lbKind
         */
        public Label getLbKind() {
                return lbKind;
        }

        /**
         * @param lbKind セットする lbKind
         */
        public void setLbKind(Label lbKind) {
                this.lbKind = lbKind;
        }

        /**
         * @return cbKind
         */
        public ComboBox<String> getCbKind() {
                return cbKind;
        }

        /**
         * @param cbKind セットする cbKind
         */
        public void setCbKind(ComboBox<String> cbKind) {
                this.cbKind = cbKind;
        }

        /**
         * @return btSearch
         */
        public Button getBtSearch() {
                return btSearch;
        }

        /**
         * @param btSearch セットする btSearch
         */
        public void setBtSearch(Button btSearch) {
                this.btSearch = btSearch;
        }

        /**
         * @return tvCat
         */
        public TableView<String> getTvCat() {
                return tvCat;
        }

        /**
         * @param tvCat セットする tvCat
         */
        public void setTvCat(TableView<String> tvCat) {
                this.tvCat = tvCat;
        }

        /*
         * (非 Javadoc)
         * @see javafx.fxml.Initializable#initialize(java.net.URL, java.util.ResourceBundle)
         */
        @Override
        public void initialize(URL location, ResourceBundle resources) {

                // コンボボックスに項目を追加
                cbKind.getItems().add("指定なし");
                cbKind.getItems().add("キジトラ");
                cbKind.getItems().add("長毛種(不明)");
                cbKind.getItems().add("ミケ(っぽい)");
                cbKind.getItems().add("サビ");
                cbKind.getItems().add("その他");

                // 初期選択状態を設定
                cbKind.getSelectionModel().select(0);

        }

}

 

メインクラスの修正

ちょっと嵌ったんですが
fxml で AnchorPane のサイズをいくら変更しても
いざ起動してみるとその通りのサイズになってくれませんでした。

よくよく見なおしてみると、メインクラスにて、
Scene のインスタンスを初期化する際に、幅と高さを指定していたことが原因でした。
(デフォルトでそうなっている)

幅と高さの指定を取り除いたら問題なく fxml で指定したサイズで表示されるようになりました。

Main.java

package application;

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

public class Main extends Application {
        @Override
        public void start(Stage primaryStage) {
                try {
                        AnchorPane root = (AnchorPane) FXMLLoader.load(getClass().getResource("Sample.fxml"));
                        // 幅と高さを指定してインスタンスを生成
                        //Scene scene = new Scene(root, 400, 400);
                        // 幅と高さを指定せずにインスタンスを生成
                        Scene scene = new Scene(root);
                        scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
                        primaryStage.setScene(scene);
                        primaryStage.show();
                } catch (Exception e) {
                        e.printStackTrace();
                }
        }

        public static void main(String[] args) {
                launch(args);
        }
}

 

起動してみる

コンボボックスに項目が設定された画面

とりあえずコンボボックスへ項目を設定することができました。

次回は、データベースから取得したデータを設定してみたいと思います。

ではでは。

 

スポンサーリンク


関連するコンテンツ

2017年9月28日Java,開発Java,JavaFX,プログラミング

Posted by doradora