質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

786閲覧

[JavaFX]TextFieldの値取得ができない

Siroyan

総合スコア20

JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2017/12/20 12:34

###前提・実現したいこと
JavaFXでユーザーがTextFieldに入力した値をボタンを押した際に読み取りたい。
SceneBuilderにてfxmlを記述しています。
###発生している問題

FieldがstaticだとgetTextできない InvocationTargetExceptionが出てしまう。

###該当のソースコード

JAVA

1public class Controller{ 2 @FXML private static TextField NameField; 3 @FXML private Button OKBtn; 4 5 public void onOKBtnClicked(ActionEvent e){ 6 Model.setName(); 7 } 8 public void getName(){ 9 return NameField.getText(); //② 10 } 11} 12 13public class Model{ 14 String Name; 15 public void setName(){ 16 Name = Controller.getName(); //① 17 } 18}

###試したこと
色々検証した結果、NameFieldを非staticにすると、getTextはうまくいきました。
しかしそうすると上記ソースコードの①の場所でgetNameをstaticにするよう指示され、すると今度は②の場所でNameFieldをstaticにするよう指示されてしまいます。結果としてエラーをgetTextが出来なくなってしまう、というわけです。

###補足情報(言語/FW/ツール等のバージョンなど)
IDE : Eclipse Neon

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

JavaFXの@FXMLによるフィールドはstaticにすることはできないと思います。FXMLにより実体化されたビューのインスタンス(それはNodeインスタンスの階層となります)はコントローラーのインスタンスで制御されるため、インスタンスの属性でないもの(staticフィールドとか)とビューを結びつけることは適切でないと思います。

(FXMLLoaderはfx:id属性が付いているノードをコントローラーインスタンスの@FXML付きのインスタンスフィールドから探してノードの参照を自動設定してくれますが、そのようなフィールドがなかったりstaticになっていても何もエラーを発しないようです。エラーにしない目的があるのかも知れませんが、なんだか不親切な気もします・・・)


ところで最初にJavaの習慣を確認しておきましょう。インスタンスフィールドやメソッド名を大文字で始まる名前にするのは慎みましょう。第三者がみると非常に違和感を覚えます。話も通じにくくなるので以降ではフィールド名を小文字で始めます。

さて、ControllerクラスのnameFieldはstaticにできないのですが、それはつまりControllerクラスのインスタンスのフィールドになることを意味します。

またModelクラスにはgetNameというメソッドがありますが、これは「Modelクラスのインスタンス」に対して呼び出すべきメソッドですね。

getNameからnameFieldをアクセスするには「ModelクラスのインスタンスがControllerクラスのインスタンスを知っていればよい」ということになるのですが・・・

このコードは一部でしかないため実際のところどうすべきかは明確には答えられません。しかし個人的な意見としてはModel#setNameの考え方を変えた方がよい気がします。

名前からしてModelは何かのデータモデルでしょうから、それはコントローラーのインスタンスに依存した実装にすべきではないと思います。例えばsetNameの実装は以下のようなものであるべきだと思います。

java

1public class Model{ 2 String name; 3 4 public void setName(String value) { 5 name = value; 6 } 7}

どうやってGUI上のTextFieldの内容をこのモデルに設定するかと言えば、このModel自身がそれを意識するのではなくsetNameを呼び出す側が意識すべきだと思います。例えばそれはControllerインスタンスがやるべきでしょう。またそうするにはControllerインスタンスもまたModelのインスタンスを知らねばなりません。

ControllerインスタンスがどのようにしてModelインスタンスを知るように作るかは一概に言えませんが、もしこの画面が新たなモデルを生成するためのものなら、Controllerのインスタンスが生成されたタイミングで新たにModelのインスタンスも生成しControllerインスタンスがそれを保持するのも一つの方法と思います。

java

1public class Controller { 2 @FXML private TextField nameField; 3 @FXML private Button okBtn; 4 5 Model model = new Model(); 6 7 public void onOkBtnClicked(ActionEvent e){ 8 model.setName(nameField.getText()); 9 } 10}

ところで、質問者さんはクラスとインスタンスの理解が漠然としてはいないでしょうか?

例えば色々な解説で

  • XXXのMMMメソッドを呼び出す
  • XXXのFFFフィールドをアクセスする

なんて書き方になっていたりしますが、それは厳密に言えば

  • XXXクラスのインスタンスに対してMMMメソッドを呼び出す
  • XXXクラスのインスタンスのFFFフィールドをアクセスする

を意味するケースが多いと思います。一々「XXXクラスのインスタンスの~」というのが長ったらしく読みにくくなるため「インスタンスのことを言っているのだけど、そこはこの文脈を読者が解釈してくれるだろう」みたいな感覚で「XXXの~」と省略してしまう解説が実に多いです。自分で「クラス」のことを言っているのか「インスタンス」のことを言っているのかを文脈から正確に把握しないと混乱してしまうのでその点も注意した方がよいかも知れません。

投稿2017/12/20 13:32

KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問