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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

JavaFX

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

Java

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

Q&A

解決済

1回答

3805閲覧

[JAVAFX]TextFiledに入力された値の取得方法

shibayun

総合スコア12

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

JavaFX

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

Java

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

0グッド

1クリップ

投稿2018/02/05 02:50

編集2018/02/06 01:47

前提・実現したいこと

何度も質問すみません。
実現したい内容は下の画像になります。
イメージ説明

今作成しているプログラムは画面A、画面B、画面Aコントローラクラス、画面Bコントローラクラスにて構成されています。
画面AにはTextFieldとButton、画面BではTableViewがあり、Button押下で画面Bに遷移します。

画面遷移やdatabaseからのデータ取得をし単純にTableViewに表示することはできましたが、FXML内のTextFiledに値を入力し、他のコントローラクラスにその入力された値を渡す方法が分からず悩んでいます。
可能な方法がありましたらどうかご教授願います。

### 試したこと [画面Aクラス]puclic staticにてString型変数を宣言し、変数 = textfield名.getText();  →[画面BクラスS]System.out.print(画面Aクラス.変数); 結果は何も表示されませんでした。 ------- 追記:画面A ![![イメージ説明](cf4599d01de9b633655ac33d64dd48ee.png)](31b9b64b02af9b1ad8267c825446577f.png)

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

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

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

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

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

guest

回答1

0

ベストアンサー

ユーザーとの対話をするための小さな画面を一般にダイアログと呼びます。多分画面Aはダイアログとして設計できると思います。

ダイアログを実装するためには通常の画面(JavaFXではStage)と同様にもできます。質問者さんはおそらくそういうイメージをお持ちであろうと思います。しかしながら大抵のGUIライブラリーと同様JavaFXもダイアログを簡便に実装するための特化機能が用意されておりそちらを使う方がより簡単と思います。

JavaFXでのダイアログはjavafx.scene.control.Dialogというベースクラスおよびその派生として定義することが想定されていますが、本件のように文字列テキストの入力なら専用クラスjavafx.scene.control.TextInputDailogが用意されていますのでそれを使うのがよいと思います。

簡単な例を挙げてみますと以下のようになります。

java

1TextInputDialog dialog = new TextInputDialog("") { 2 { 3 setTitle("filtering"); 4 setHeaderText("input filtering text"); 5 } 6}; 7Optional<String> optInput = dialog.showAndWait(); 8if (!optInput.isPresent()) { 9 // キャンセルが押された場合optInputは値を持たない 10 System.out.println("cancelled"); 11} else { 12 // OKが押された場合はoptInputは値を持ち、それはgetにより得られる。 13 System.out.println("input text = " + optInput.get()); 14}

上記ではデフォルトから2点のみ動作を変えています。一つはダイアログタイトルで、もう一つはヘッダーテキストです。様々なカスタマイズをするためにはjavafx.control.Dialogの機能を調べるとやり方がわかってきますが、とりあえずはデフォルトの振る舞いがどのようになっているかを観察してみるとよいでしょう。

他のコントローラクラスにその入力された値を渡す方法が分からず悩んでいます。

ダイアログを用いる場合、ユーザーの入力結果はshowAndWaitメソッドの戻り値になるので、それを用いることになります。本件の場合、画面Bのコントローラーインスタンスへなんらかの方法で渡すのが自然と思います。渡し方は画面Bをどうやって生成・表示するかによって若干のバリエーションがありますが、FXMLとFXMLLoaderにより画面を生成する方法を用いるなら、以下のようにFXMLロード後にコントローラーインスタンスを取得しそこに定義したメソッドを通じて設定という流れが典型的な方法の一つだと思います。

java

1FXMLLoader loader = new FXMLLoader(...); 2loader.load(); 3ControllerB controllerB = loader.getController(); 4controllerB.setFilterText(optInput.get());

追記:
回答コメントから質問者さんの想定がダイアログではないようですので、各画面のStage, コントローラーを画面遷移の都度生成する前提に注意しつつ、画面遷移方法を考えてみました。以下の例は唯一の方法でもベストなものというわけではありません。やりかたには微妙なバリエーションがあるでしょう。つまり「ある画面から別の画面へ情報を引き渡す」実装例の一つです。

画面遷移メソッド(アプリケーションクラスに用意する例)

java

1public class MyApp extends Application { 2 private static MyApp app; 3 4 public static MyApp getInstance() { 5 return Objects.requireNonNull(app); 6 } 7 8 public MyApp() { app = this; } 9 10 HashMap<Class<? extends Initializable>, String> fxmlMap = new HashMap<>(); 11 12 @Override 13 public void start(Stage stage) { 14 fxmlMap.put(AController.class, "A.fxml"); 15 fxmlMap.put(BController.class, "B.fxml"); 16 17 try { 18 Parent root = FXMLLoader.load(getClass().getResource("Main.fxml")); 19 stage.setScene(new Scene(root)); 20 stage.show(); 21 } catch (IOException e) { 22 throw new UncheckedIOException(e); 23 } 24 } 25 26 public <C extends Initializable> C showStage(Class<C> controllerClass) throws IOException { 27 FXMLLoader loader = new FXMLLoader(getClass().getResource(fxmlMap.get(controllerClass))); 28 Parent parent = loader.load(); 29 Stage stage = new Stage(); 30 stage.setScene(new Scene(parent)); 31 stage.show(); 32 return loader.getController(); 33 } 34}

画面Aから画面Bへの遷移処理(検索ボタンのアクション)

java

1public class AController implements Initializable { 2 @FXML 3 private TextField filterText; 4 5 @Override 6 public void initialize(URL location, ResourceBundle resources) { 7 8 } 9 10 @FXML 11 private void onShowB(ActionEvent ev) throws IOException { 12 Stage stage = (Stage)((Node)ev.getSource()).getScene().getWindow(); 13 stage.hide(); 14 BController bController = MyApp.getInstance().showStage(BController.class); 15 bController.setFilterText(filterText.getText()); 16 } 17}

画面Bにて検索条件を受け取るメソッド

java

1public class BController implements Initializable { 2 @FXML 3 TableView<Model> tableView; 4 5 @Override 6 public void initialize(URL location, ResourceBundle resources) { 7 ... 8 } 9 10 public void setFilterText(String text) { 11 // 指定テキストによりモデルを生成する(DBアクセスしてモデルインスタンスのリストを生成) 12 // 時間がかかる処理ならバックグラウンドスレッドで行うべきだが、ここでは簡単のため 13 // アプリケーションスレッドでやると想定 14 List<Model> modelList = ...; 15 tableView.getItems().setAll(modelList); 16 } 17}

自分が考えた点は以下です。

  • 多数の画面があるなら遷移処理を共通化したい

アプリケーションクラスでshowStageというメソッドを用意し各画面ではこれを使う想定としました。また本質問の目的にあるように画面間での情報の引き渡しを遷移元と遷移先のコントローラーインスタンス間で行えるよう、画面遷移メソッドは遷移先のコントローラーを返すようにしています。

  • ステージのshowとコントローラークラスへの情報のやりとり順序

例を簡単にするため共通メソッド(showStage)は無条件に生成したstageをshowし、その後にstageに結び付いたコントローラーインスタンスに対して情報設定メソッドを呼び出すと想定しています。viewがいかなる状態であろうと(表示前であろうと表示後であろうと)コントローラーやモデルの状態を変更した際にビューが適切に追従するように作ることは難しくないのですが、モデルの生成に時間がかかるような場合、画面を表示後にしばらくして表示内容が変わるのか、表示内容を確定させてから画面を表示させるかで見栄えが変わると思います。そうした点は細かなチューニング対象だと思います。

  • staticの仕様は最小限にする(追記2)

本例ではアプリケーションインスタンスをシングルトンとしてMyApp#app及びMyApp#getInstanceのみstaticにしています。こうしておくと(殆どの定義がインスタンスフィールド、インスタンスメソッドのため)アプリケーションインスタンスを複数生成するような設計に変更する場合でも変更の影響を最小限にできると思います。Javaに限らずstatic(=グローバル)はできるだけ避けるという考え方があると思いますのでそれに倣ったつもりです。そういう想定が必要ないならこうした点をいちいち気にせず適宜staticにしてもよいとは思います。

投稿2018/02/05 05:05

編集2018/02/06 09:21
KSwordOfHaste

総合スコア18394

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

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

shibayun

2018/02/06 01:45

回答ありがとうございます。 ダイアログを用いるという考え方は無かったので、とても参考になりました。一度試してみます。 ですが、ダイアログだと前画面に戻るためのボタンなどの配置はできないのでしょうか? 質問では二画面で説明しましたが、実際には10画面以上あるので...。 現在制作してある画面Aを追記しました。
shibayun

2018/02/06 01:56

ちなみに画面Bの画面を生成する方法としてはFXMLLoader.loadを用いてFXMLをロードして表示しています。
KSwordOfHaste

2018/02/06 02:54

質問へ追記されている画面イメージを拝見するに、画面Aはダイアログではなく互いに遷移可能な通常のアプリケーション画面の一つとして考えておられるようです。どのようにするかは画面Aの振る舞いとそれに沿ったコントローラーインスタンス(以下単にコントローラーAと呼びます)のライフサイクルを明確にした方がよさそうです。画面Aの「検索」ボタンを押した際に、コントローラーAをリリースする(次にこの画面を表示する際に新たなコントローラーAを生成する)か、コントローラーAをずっとどこかに覚えておくか両方のやり方があります。どちらで行うかによって適切な方法が変わると思います。複雑な画面が多数あるようなら画面が消えるタイミングでコントローラーAやシーングラフをリリースする方がよいかも知れません。どちらにするか意識しておられるでしょうか?
KSwordOfHaste

2018/02/06 03:03

もう一つ、追記しておられる画像を拝見すると各画面はそれぞれスクリーン全体の大きさを占めるぐらいの大きさで、複数の画面が同時に表示されることはないと想像します。とすれば、全部の画面でStageを共有するか、それぞれの画面でStageを別個に生成するのかも知りたい気がします。自分が何画面もあるアプリ(かつ後で画面が増えるかも知れない)を設計するならStageを一つだけにするかも知れませんが、複数の画面を同時に見せたいということがあるなら当然stageは画面ごとに生成します。どちらを想定しておられますか?
shibayun

2018/02/06 03:24

一つ目のリリースするのか記憶しておくのか、ということに関してはリリースするようにしています。現段階では記憶する必要がないので。 例えば「戻る」ボタンを押下した場合は1つ前の画面(FXMLファイル)をFXMLLoader.loadで呼び出しています。
shibayun

2018/02/06 03:29

二つ目について そうですね、複数の画面を表示するような動作はありません。 Stageについては、私が知識不足なばかりに現状は各画面でStage生成をしてしまっています。共有はしていません。
KSwordOfHaste

2018/02/06 05:44

ダイアログにする前提の回答でしたが、ダイアログでない回答を追記してみました。なお、質問者さんが試されたことがうまくいかない原因についてはもう少し周りのコードがないと答えづらくコメントしておりません。追加した回答は単に「自分ならこういうふうに考える」という例を挙げたものに過ぎません。
KSwordOfHaste

2018/02/06 09:22

回答の最後の方に「staticをなるべく避ける」ことについて追記しました。
shibayun

2018/02/07 07:46

様々な回答ありがとうございます。ここ最近調べながら頑張って理解しているところです。 申し訳ないのですが、BControllerの 'List<Model> modelList = ...;' とはいったい何なのでしょうか?度々すみません。
KSwordOfHaste

2018/02/07 08:05

それはTableViewへ表示すべきモデル群(Modelのリスト)を求めると想定して書いたものです。 本件ですと引数に渡された検索条件に従ってDBアクセスし、結果セットの各行をModelクラスのインスタンスへと変換しそれをListとして蓄積するイメージです。TableViewは「なんらかのモデルクラスのインスタンス」を各行として表示しますよね?DBアクセスした結果の行をモデルクラスのインスタンスと見做すのはそういう意味合いです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問