JavaFXでテキストフィールドに値を入れたり取得したり
Java を勉強してみるぞシリーズ第 5 段。テキストフィールドを追加して、値を入れたり、入っている値を取得したりしてみます。
関連記事
- 初めてJavaを触った人間がEclipseでJavaFXのGUIアプリを起動するまで
- JavaFX Scene BuilderでのContainers(土台)部の違いについて
- JavaFXでウィンドウにボタンを配置してクリックでメッセージを出力する
- JavaFXでインプットダイアログの結果をアラートで表示する
- JavaFXでテキストフィールドに値を入れたり取得したり ←NOW!
順番に見てもらったほうがわかりやすいと思います。
書いたときの環境
- JDK 8u121
- Eclipse4.6 NEON
- Scene Builder 8.3.0
- Windows7/10
です。
TextFieldを追加して使えるようにする
今までこんな形のボタン 1 つをクリックするだけだったので、テキストフィールドを追加してみましょう。
Form.fxml を右クリックして、Scene Builder で開きます。
Scene Builder
ボタンを増やして、TextField を追加します。
TextField に任意の ID をつけます。
ボタンを 2 つにしたので、こちらのアクションイベントは onInputButtonClick にしてみました。
こっちは onGetButtonClick です。
これを保存すると、.fxml が以下のようになります。
Form.fxml
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.Button?> <?import javafx.scene.control.TextField?> <?import javafx.scene.layout.AnchorPane?> <AnchorPane prefHeight="200.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.FormController"> <children> <TextField fx:id="testTextField" layoutX="30.0" layoutY="60.0" /> <Button layoutX="54.0" layoutY="140.0" mnemonicParsing="false" onAction="#onInputButtonClick" text="入力" /> <Button layoutX="107.0" layoutY="140.0" mnemonicParsing="false" onAction="#onGetButtonClick" text="取得" /> </children> </AnchorPane>
Scene Builder で設定した TextField の ID や、ボタンのアクションイベント名が反映されています。
FormController.java
コントローラ側へ、上記のコントロールを使えるように記述します。
package application; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.TextField; public class FormController { @FXML private TextField testTextField; @FXML protected void onInputButtonClick(ActionEvent evt) { //「入力」ボタンクリック } @FXML protected void onGetButtonClick(ActionEvent evt) { //「取得」ボタンクリック } }
これで、テキストフィールドと 2 つのボタンが使えるようになりました。
かんたんに入力/取得する
とりあえず、一番シンプルに書いてみます。
package application; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.TextField; public class FormController { @FXML private TextField testTextField; @FXML protected void onInputButtonClick(ActionEvent evt) { //「入力」ボタンクリック testTextField.setText("サンプルテキスト"); } @FXML protected void onGetButtonClick(ActionEvent evt) { //「取得」ボタンクリック System.out.println(testTextField.getText()); } }
実行します。
「入力」ボタンを押すと、
onInputButtonClick が走って、指定した「サンプルテキスト」という文字列が TextField に入ります。
この状態で今度は「取得」ボタンを押すと、
onGetButtonClick が走って、TextField の値がコンソールに出力されます。
値をチェック → 結果を Label へ
ちょっと改造して、
ボタンを Check にして、
ラベルを1つ追加します。
FormController.java
Controller のほうのラベルを追加したり、ボタンのアクションイベントを直します。ボタンをクリックすると、TextField の値をチェックして、相応のテキストが Label に表示されるという想定です。
package application; import java.net.URL; import java.util.ResourceBundle; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Label; import javafx.scene.control.TextField; public class FormController implements Initializable { @FXML private TextField testTextField; @FXML private Label testLabel; //ラベル追加 @Override public void initialize(URL url, ResourceBundle rb) { testTextField.setText("初期テキスト"); } @FXML protected void onCheckButtonClick(ActionEvent evt) { //「Check」ボタンクリック String resultText = "TextFieldの値をチェックしたテキスト"; //ここは後で実装 testLabel.setText(resultText); //結果をラベルに入れる } }
ハイライト部のように書くと、初期値を設定することができます。この状態で実行してみると、
テキストが入った状態で表示されます。
@Override public void initialize(URL url, ResourceBundle rb) { testTextField.setPromptText("入力してください"); //未入力テキスト testTextField.setFocusTraversable(false); //フォーカスアウト }
ちなみに.setPromptText()
を使うと、未入力のときに表示される説明文みたいなのを入れることができます。ただこれはフォーカスが入っていると表示されないのでフォーカスアウトしておきます。
実行するとこんな感じ。
Task.java
さて、では「TextField の値をチェックして、相応のテキストを返す」部分を作ります。Controller に書くのはいただけないと思うので、新しくクラスを作ってみます!
ツールバーから新しいクラスを作って、
名前は…、、思いつかなかったので「Task」にしちゃいました。ほんとはもっと具体的な名前がよいと思います!
できた。
package application; public class Task { //フィールド private String tgtText; //コンストラクタ public Task(String tgt_text) { tgtText = tgt_text; } //メソッド public String getResultText(){ //結果を返す String resultText = ""; if ( tgtText.equals("") ) { //空白だったら resultText = "未入力です"; } else if ( !isNumber(tgtText) ){ //数値じゃなかったら resultText = "数値ではありません"; } else { //それ以外 int tgtInt = Integer.parseInt(tgtText); //数値変換 if ( 10 <= tgtInt && tgtInt <= 20 ) { //範囲内かチェック resultText = "OK!"; } else { resultText = "範囲外です"; } } return resultText; } public boolean isNumber(String val) { //数値チェック try { Integer.parseInt(val); return true; } catch (NumberFormatException ex) { return false; } } }
中身はこんな感じにしてみました。new されたときにテキストをもらってくる想定で…。Java 初心者がネットでググりまくって書いてる感じなので、変な書き方だなとおもったらぜひ教えてください!!
内容としては、getResultText()
メソッドで引数の中身をチェックして、それに対応するテキストを返しています。チェック内容は、10 ~ 20 の整数かどうかです。
FormController.java
また Controller に戻って、Task クラスを使ってテキストを受け取る部分を書きます。
package application; import java.net.URL; import java.util.ResourceBundle; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Label; import javafx.scene.control.TextField; public class FormController implements Initializable { @FXML private TextField testTextField; @FXML private Label testLabel; @Override public void initialize(URL url, ResourceBundle rb) { testTextField.setPromptText("入力してください"); //未入力テキスト testTextField.setFocusTraversable(false); //フォーカスアウト } @FXML protected void onCheckButtonClick(ActionEvent evt) { //「Check」ボタンクリック Task task1 = new Task(testTextField.getText()); //インスタンス化 String resultText = task1.getResultText(); //対応テキストを受け取る testLabel.setText(resultText); //ラベルに入れる } }
24 行目で Task クラスのtask1
というインスタンスを作って TextField の値を引き渡して、その後 25 行目でgetResultText()
メソッドを呼び出して対応テキストを受け取ります。
最後にラベルに入れて終了です。
実行したところ。
数値を入れてボタンをクリックすると、10 ~ 20 の整数かチェックして下に結果が出ます。
ダメな例。
あとがき的な
とりあえず初心者的なエントリはこのあたりで終了かなと思っています。
基本がわかってきたので TableView を使ってみたりとか、ProgressIndicator を使ったマルチスレッド処理とか、そういうアプリを自分用でいくつか作ってみてるんですが、いかんせん自分1人しか使ってないので「これでいいのか感」が拭えなくてまだまだ不安…。
もうちょっといろいろやってみて自信がついてきたらまた小出しに書いていきたいとおもいます!
参考
不適切な部分や間違ってるぞコノヤロウ的なところがありましたらご指摘ください!
コメントは承認制ですので、反映までしばらくお待ち下さい。(稀にスパムの誤判定にて届かないこともあるようですので、必要な際はお問い合わせからお願い致します。)
YouTubeでQ&Aコンテンツを企画しています
運営しているYouTubeチャンネルで、ご相談やご質問を募集しています。動画のコメントやお問い合わせページからお気軽にご相談をお寄せください。