java-beginner.com ブログ

プログラミングを学習するブログ(Javaをメインに)

JavaFXのLabelで掛け算九九

投稿日:

最終更新日:2016年09月01日

アイキャッチ

こんにちは。「Javaを復習する初心者」です。

今回はJavaFXで掛け算九九の表を表示するプログラムを作ってみました。

JavaFXのアプリケーションを作るときは、以下の開発環境を使ってます。

  • Eclipse Luna + e(fx)clipse – IDEプラグイン
  • JavaFX Scene Builder 8.2.0

動作

アプリケーションの動作は以下のようにしました。

init

初期表示。

inputDialog

「入力」ボタン押下時のダイアログ。2桁以内で数値を入力。

output

ダイアログで「2」を入力した後の出力結果。

errorDialog

エラーダイアログ。入力チェックでエラーの場合に出力。

JavaFXでは画面の定義をfxmlファイルというxmlファイルで定義できます。このファイルは「JavaFX Scene Builder」で編集できます。今回はBorderPaneを配置し、そのtopとcenterにPaneを配置しました。topのPaneには「入力」Button、「開始」Label、入力値を表示するTextFieldを配置しました。TextFieldには内容が空の状態の場合に表示するテキストのためのpromptTextという属性があります。この属性に「入力ボタンをクリック」を設定しました。個の文字列は初期画面で薄く表示されます。

fxmlファイルとjavaファイル

以下が今回使ったfxmlファイルです。

fxml

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.Pane?>

<BorderPane prefHeight="400.0" prefWidth="680.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="matrixTest.AppController">
   <top>
      <Pane prefHeight="71.0" prefWidth="600.0" BorderPane.alignment="CENTER">
         <children>
            <Button layoutX="14.0" layoutY="23.0" mnemonicParsing="false" onAction="#input" text="入力" />
            <Label layoutX="77.0" layoutY="27.0" text="開始" />
            <TextField fx:id="textFieldStartNum" editable="false" layoutX="111.0" layoutY="23.0" promptText="入力ボタンをクリック" />
         </children>
      </Pane>
   </top>
   <center>
      <Pane fx:id="targetPane" prefHeight="283.0" prefWidth="343.0" BorderPane.alignment="CENTER" />
   </center>
</BorderPane>

BorderPaneでfx:controller属性を設定しています。matrixTest.AppControllerと書いてあるのはjavaファイル(classファイル)へのパスです。具体的な記述は以下です。

AppController

package matrixTest;

import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.TextInputDialog;
import javafx.scene.layout.Pane;


public class AppController {

    @FXML Pane targetPane;

    @FXML TextField textFieldStartNum;

    @FXML
    private void input(ActionEvent event) {

        // 初期化設定
        clear();

        // 入力ダイアログ
        TextInputDialog textInputDialog = new TextInputDialog();
        textInputDialog.setTitle("入力");
        textInputDialog.setHeaderText(null);
        textInputDialog.setContentText("2桁までの数値を入力してください。");
        textInputDialog.showAndWait();

        // 値受け取り
        String value = textInputDialog.getResult();

        // 未入力でないこと
        if (value == null || value.isEmpty()) {
            showAlertDialog("未入力です。");
            return ;
        }

        // 数値であること
        if (!value.matches("\\d+")) {
            showAlertDialog("数値を入力してください。");
            return ;
        }

        // 2桁以内であること
        if (value.length() > 2) {
            showAlertDialog("2桁以内で入力してください。");
            return ;
        }

        // 出力
        printMatrix(Integer.parseInt(value));

        // テキストフィールドに設定
        textFieldStartNum.setText(value);

    }

    private void printMatrix(int numStart) {

        ObservableList<Node> list = targetPane.getChildren();

        int count = 9;
        String styel = "-fx-alignment: center-right; -fx-font-family: monospace;";
        String format = "%5d";
        for (int i = 0; i <count; i++) {
            for (int j = 0; j <count; j++) {
                Label label = new Label(String.format(format, (numStart + i) * (numStart + j)));
                label.setLayoutX(70 * i);
                label.setLayoutY(30 * j);
                label.setStyle(styel);
                list.add(label);
            }
        }

    }

    private void clear() {

        textFieldStartNum.setText(null);

        ObservableList<Node> list = targetPane.getChildren();
        list.clear();

    }

    private void showAlertDialog(String contentText) {

        Alert alert = new Alert(AlertType.ERROR);
        alert.setContentText(contentText);
        alert.showAndWait();

    }

}

fxmlファイルでButtonのonAction属性に「#input」を設定しています。上記javaファイルでinputメソッドに@FXMLアノテーションを付与しています。これでButton押下時に呼び出されるメソッドがバインドされます。

ダイアログ

今回のプログラムではダイアログを使っています。ダイアログは以下の3種類があります。

  • Alert
  • ChoiceDialog
  • TextInputDialog

値を入力してもらうためにTextInputDialogクラスを使ってます。また、入力チェックでエラーの場合はAlertクラスを使ってます。showAlertDialog()メソッドで共通化しています。

実際に掛け算の結果を出力している個所はprintMatrix()メソッドです。public ObservableList<Node> getChildren()メソッドでPaneの子のリストを取得しています。このリストにコンポーネントを追加することでPaneに描画されます。今回はLabelを追加しています。addメソッドで追加が可能です。これで掛け算の結果が出力できます。Labelの位置はsetLayoutX()メソッド、setLayoutYメソッドで設定できます。今回は適当に調節しました。また、setStyle()メソッドを使っていますが、これはCSSの設定です。以下の2つのプロパティを設定しています。

  • -fx-alignment: center-right;
  • -fx-font-family: monospace;

上記は「JavaFX CSS」の項目です。-fx-alignmentは文字列の並びの位置を調節できます。center-rightで上下中央の右寄せになります。-fx-font-familyはフォントファミリーの設定です。monospaceで等幅フォントになります。この設定をしていることと、Labelに文字列を設定するときに書式文字列を利用していることにより文字列が全体として縦に揃っています。