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

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

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

Java ME(Java Platform, Micro Edition)はリソースが制限されたデバイス(携帯電話、PDA、テレビなど)用につくられたJavaプラットフォームである。

JavaFX

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

Java

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

Q&A

解決済

2回答

864閲覧

JavaFXのイベント処理について

Miyahala

総合スコア19

Java ME

Java ME(Java Platform, Micro Edition)はリソースが制限されたデバイス(携帯電話、PDA、テレビなど)用につくられたJavaプラットフォームである。

JavaFX

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

Java

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

0グッド

0クリップ

投稿2018/03/13 14:05

JavaFXを中心軸にJavaを学習しています。
コレクションクラスという物があることを知ったのですが。
ArrayListとTimeAPIを組み合わせれば、タイムスタンプを自作できると思い、実験として以下のコードを書きました。

 GUIのボタンが押されれば、その都度ArrayListの箱が増えていき、箱の中にnowされたその時の現在時刻が格納されていくと考えたためです。
ところが拡張for文で配列を回して箱の中身を出してみると、実験結果は予想に反して一個の時刻しか格納されていませんでした。

 これはイベントハンドラーが動作する度に初期化がされるということなのでしょうか、このような処理を実現するためには考え方としてやはりSQLなどのデーターベースの知識が必要となってくるのでしょうか?

Java

1package ArrayListとtimeAPIの実験; 2 3import java.time.LocalTime; 4import java.util.ArrayList; 5import javafx.application.Application; 6import javafx.event.ActionEvent; 7import javafx.event.EventHandler; 8import javafx.scene.Scene; 9import javafx.scene.control.Button; 10import javafx.scene.layout.StackPane; 11import javafx.stage.Stage; 12 13/** 14 * 15 * @author test 16 */ 17public class ArrayListTimeAPIの実験 extends Application { 18 19 @Override 20 public void start(Stage primaryStage) { 21 Button btn = new Button(); 22 btn.setText("ArrayListに現在時刻を格納する'"); 23 btn.setOnAction(new EventHandler<ActionEvent>() { 24 25 @Override 26 public void handle(ActionEvent event) { 27 28 ArrayList<LocalTime>timestamp=new ArrayList<LocalTime>(); 29 timestamp.add(LocalTime.now()); 30 for(LocalTime i:timestamp){ 31 System.out.println("格納された時刻"+i); 32 } 33 } 34 }); 35 36 StackPane root = new StackPane(); 37 root.getChildren().add(btn); 38 39 Scene scene = new Scene(root, 300, 250); 40 41 primaryStage.setTitle("タイムスタンプ"); 42 primaryStage.setScene(scene); 43 primaryStage.show(); 44 } 45 46 /** 47 * @param args the command line arguments 48 */ 49 public static void main(String[] args) { 50 launch(args); 51 } 52 53} 54

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

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

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

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

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

guest

回答2

0

ベストアンサー

これはイベントハンドラーが動作する度に初期化がされるということなのでしょうか、

YESともNOとも言い難いです。ざっくり答えると「プログラムの意味の把握がちょっと浅い」といったところでしょうか。

java

1btn.setOnAction(new EventHandler<ActionEvent>() { 2 @Override 3 public void handle(ActionEvent event) { 4 ArrayList<LocalTime> timestamp = new ArrayList<LocalTime>(); 5 timestamp.add(LocalTime.now()); 6 for (LocalTime i: timestamp){ 7 System.out.println("格納された時刻"+i); 8 } 9 } 10});

上のコードですが、ボタンが押された時handleメソッドが起動されるのはおわかりですね?timestampはローカル変数ですがローカル変数とは何かわかりますか?ローカル変数はいつ作られて、いつなくなるか分かりますか?

これをまずもっと簡単なコードで学んでください。JavaFXを抜いて単純化して考えましょう。

Java

1public class Main { 2 public static void main(String[] args) { 3 m1(); 4 m1(); 5 } 6 7 static void m1() { 8 List<Integer> list = new ArrayList<>(); 9 list.add(1); 10 for (int i: list) { 11 System.out.println("i=" + i); 12 } 13 } 14}

上の動作の把握が第一歩と思います。

このような処理を実現するためには考え方としてやはりSQLなどのデーターベースの知識が必要となってくるのでしょうか?

NO

ローカル変数だけでなくフィールドを覚えてください。というよりインスタンスとは何かを覚えましょう。おそらくそれがまだお分かりになっていない気がします。


追記:質問者さんのコードへの捕捉

JavaFXではラムダ式を使う場面が非常に多いと思いますので、コメントに書いた「ラムダ式の引数の型を省略していいことが多い」について補足します。

java

1// 型を指定してもよい (A) 2btn.setOnAction((ActionEvent event) -> { 3 timestamp.add(LocalTime.now()); 4 ... 5}); 6// しかし大抵の場合省略できる (B) 7btn.setOnAction(event -> { 8 timestamp.add(LocalTime.now()); 9 ... 10});

省略できないケースというのはラムダ式の引数の型の候補が複数ありえるようなケースです。例えばButtonクラスに定義されているのは下記(A)だけですが、もし(B)も定義されていたとしたら省略できないのですね。

Java

1public class Button ... { 2 public void setOnAction(EventHandler<ActionEvent> handler) { ... } // (C) 3 public void setOnAction(EventHandler<OtherType> handler) { ... } // (D) 4}

このようなオーバーライドメソッドが複数あるケースでは(B)のように引数を省略すると(C)の呼び出しなのか(D)の呼び出しなのか一意に決められないためラムダ式の引数の型を省略できません。(省略するとコンパイルエラーになります)

しかしながらJavaFX(多分他の多くの場面でも)こうしたオーバーライドメソッドがあることは稀で大抵の場合省略しても型が一意に決まります。若干微妙な例が

ObservableValue#addListener(ChangeListener<T> l);
ObservableValue#addListener(InvalidationListener<T> l);

なんですが、ChangeListnerの引数の型が3つでInvalidationListenerの引数の型が1つという違いがあるため、このケースでも方は省略できるということを覚えておくとよいかも知れません。

observable.addListner((observable, oldValue, newValue) -> {...}); (E)
observable.addListner((observable) -> {...}); (F)

引数の数が違うので(E)はChangeListener、(F)はInvalidationListnerであることをコンパイラーはちゃんと推測してくれコンパイルエラーにはならないのです。

投稿2018/03/13 14:33

編集2018/03/16 03:09
KSwordOfHaste

総合スコア18394

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

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

Miyahala

2018/03/13 23:35

ありがとうございます。
guest

0

フィールドを使用し意図通り動作するようになりました、回答し教えてくださった方にこの場を借りて感謝いたします。
なにぶん初学者なものでこのコードもプロの方々からみればこの書き方はちょっとな、と思われる点があるかもしれません、コメント欄で指摘してくだされば私としてはとても助かります。

名無しクラス(匿名クラス)を利用した場合の書き方

Java

1package arraylistとtimeapiの実験; 2 3import java.time.LocalTime; 4import java.util.ArrayList; 5import javafx.application.Application; 6import javafx.event.ActionEvent; 7import javafx.event.EventHandler; 8import javafx.scene.Scene; 9import javafx.scene.control.Button; 10import javafx.scene.layout.StackPane; 11import javafx.stage.Stage; 12 13public class ArrayListTimeAPIの実験 extends Application { 14 15//データ保持用にArrayListのインスタンスをフィールドとして宣言する(has-aの関係) 16 17 ArrayList<LocalTime>timestamp=new ArrayList<LocalTime>(); 18 19 @Override 20 public void start(Stage primaryStage) { 21 Button btn = new Button(); 22 btn.setText("ArrayListに現在時刻を格納する'"); 23 btn.setOnAction(new EventHandler<ActionEvent>() { 24 25 @Override 26 public void handle(ActionEvent event) { 27 28 timestamp.add(LocalTime.now()); 29 for(LocalTime i:timestamp){ 30 System.out.println("格納された時刻"+i); 31 } 32 } 33 }); 34 35 StackPane root = new StackPane(); 36 root.getChildren().add(btn); 37 38 Scene scene = new Scene(root, 300, 250); 39 40 primaryStage.setTitle("タイムスタンプ"); 41 primaryStage.setScene(scene); 42 primaryStage.show(); 43 } 44 45 /** 46 * @param args the command line arguments 47 */ 48 public static void main(String[] args) { 49 launch(args); 50 } 51} 52

Java8以降は以下のようにラムダ式を利用した方が望ましいとされている。

Java

1package arraylistとtimeapiの実験4; 2 3import java.time.LocalTime; 4import java.util.ArrayList; 5import javafx.application.Application; 6import javafx.event.ActionEvent; 7import javafx.event.EventHandler; 8import javafx.scene.Scene; 9import javafx.scene.control.Button; 10import javafx.scene.layout.StackPane; 11import javafx.stage.Stage; 12 13public class ArrayListTimeAPIの実験4 extends Application { 14 15 ArrayList<LocalTime>timestamp=new ArrayList<LocalTime>(); 16 17 @Override 18 public void start(Stage primaryStage) { 19 Button btn = new Button(); 20 btn.setText("ArrayListに現在時刻を格納する'"); 21 22 btn.setOnAction((ActionEvent event)-> { 23 24 timestamp.add(LocalTime.now()); 25 for(LocalTime i:timestamp){ 26 System.out.println("格納された時刻"+i); 27 } 28 }); 29 30 StackPane root = new StackPane(); 31 root.getChildren().add(btn); 32 33 Scene scene = new Scene(root, 300, 250); 34 35 primaryStage.setTitle("ラムダ式で書かれたタイムスタンプの例"); 36 primaryStage.setScene(scene); 37 primaryStage.show(); 38 } 39 /** 40 * @param args the command line arguments 41 */ 42 public static void main(String[] args) { 43 launch(args); 44 } 45}

参考書籍
スッキリわかるJava入門第2版
8.2.3属性の宣言方法
9.1.8クラス型をフィールドに用いる

投稿2018/03/16 02:36

Miyahala

総合スコア19

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

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

KSwordOfHaste

2018/03/16 02:50 編集

世のJavaプログラムの前提JRE(Java Runtime Environment)バージョンはJava8とは限らないので無名クラスを使うケースもあると思うのですが、JavaFXはJava8からの標準ということもあり、よほど特殊な事情がない限りJava8前提でよくそういう意味でラムダ式前提でよい気がします。なお、ラムダ式の引数の型は省略してもよいことが多いです。 btn.setOnAction(event -> {  timestamp.add(LocalTime.now());  ... });
KSwordOfHaste

2018/03/16 03:09

回答の方にも若干補足説明を追記しておきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問