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

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

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

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

Java

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

Q&A

解決済

1回答

4356閲覧

JavaFXのanimationクラスのTimelineの停止の仕方がわからない。

Miyahala

総合スコア19

JavaFX

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

Java

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

0グッド

0クリップ

投稿2018/09/08 13:03

JavaFXでストップウォッチを、TimeAPIとDurationクラスを使う事にこだわって作成しようとしています。
なんとかここまで作って来たのですが、ストップボタンを押したときの動作がうまく行きません。
timeline.stop()の使い方に誤りがあるようだと考えて、stopSWメゾット内にtimeline.stop()を記述したり、if文を用いたり色々手を尽くしてみましたがどうにもうまくいきません、それで質問させて頂くことにしました。どのようにすればtimeline.stop()を動作させる事が出来るのでしょうか?

Java

1package miyastopwatch9; 2 3import java.awt.Insets; 4import java.time.*; 5import java.time.format.DateTimeFormatter; 6import javafx.animation.KeyFrame; 7import javafx.animation.Timeline; 8import javafx.application.Application; 9import javafx.event.ActionEvent; 10import javafx.event.EventHandler; 11import javafx.animation.KeyFrame; 12import javafx.animation.Timeline; 13import javafx.geometry.Pos; 14import javafx.scene.Scene; 15import javafx.scene.control.Button; 16import javafx.scene.control.Label; 17import javafx.scene.layout.VBox; 18import javafx.scene.layout.HBox; 19import javafx.scene.text.Font; 20import javafx.stage.Stage; 21 22/** 23 * 24 * @author miya 25 */ 26public class MiyaStopwatch9 extends Application { 27 28 //フィールドの類 29 30 //時間計算用のInstant型が2つ 31 Instant timeA; 32 Instant timeB; 33 34 //結果のデータ出力用にInstant型とDuration型それぞれ1つ 35 Instant ans; 36 Duration durationans; 37 38 //ストップウオッチの制御用にboolean型を1つ 39 boolean stopSW=false; 40 41 //GUIの表示用にString型を1つ 42 String display; 43 44 /*Stringへの型変換用のフォーマット用変数を宣言、 45 フォーマッタの準備、変数formatter1にフォーマッタの代入をしている。*/ 46 DateTimeFormatter formatter1=DateTimeFormatter.ofPattern("H:mm:ss"); 47 48 //続いてGUIの類です。 49 Label labelTime1=new Label("00"); 50 LocalTime now=LocalTime.of(0, 0, 0, 0); 51 Button btnSTA = new Button("Strat"); 52 Button btnSTO=new Button("Stop"); 53 54 //ラムダ式でstartSWとstopSWのイベント処理を書きました。 55 @Override 56 public void start(Stage primaryStage) { 57 58 btnSTA.setOnAction(event-> { 59 60 startSW(); 61 }); 62 63 btnSTO.setOnAction(event->{ 64 65 stopSW(); 66 }); 67 68 //フォントサイズの指定 69 labelTime1.setFont(new Font(50)); 70 71 //レイアウトはHBoXとVBoxの組み合わせで行いました。 72 73 HBox HBox=new HBox(); 74 HBox.setAlignment(Pos.CENTER); 75 //HBox、横方向(H)にlabelTime1を整列させよ 76 HBox.getChildren().addAll(labelTime1); 77 78 HBox HBox2=new HBox(); 79 HBox2.setAlignment(Pos.CENTER); 80 //HBox2、横方向(H)にlbtnSTAとbtnSTOを整列させよ 81 HBox2.getChildren().addAll(btnSTA,btnSTO); 82 83 VBox VBox = new VBox(); 84 VBox.setAlignment(Pos.CENTER); 85 VBox.setSpacing(20.0); 86 //VBox、縦方向(V)にHBoxとHbox2を整列させよ 87 VBox.getChildren().addAll(HBox,HBox2); 88 89 Scene scene = new Scene(VBox,300, 250); 90 91 primaryStage.setTitle("ストップウォッチ"); 92 primaryStage.setScene(scene); 93 primaryStage.show(); 94 } 95 96 //各呼び出され側のメゾットの内容です。 97 public void startSW(){ 98 System.out.println(" startSWメゾット起動"); 99 this.timeA=Instant.now(); 100 pendulum(); 101 //pendulum 和訳「振り子」 102 } 103 104 public void pendulum() { 105 System.out.println("pendulumメゾット起動"); 106 107 /*Timelineインスタンス作成、同時にKeyFrameインスタンスも作成し、 108 1000millisごとのアニメーション動作を指定*/ 109 Timeline timeline = 110 new Timeline( 111 new KeyFrame( 112 javafx.util.Duration.millis(1000), 113 /*KeyFrameのコンストラクタの引数である、 114 インターフェースEventHandler<actionevent>を実装、 115 (ActionEvent型の引数としてeventを渡す)*/ 116 event->{ 117 //現在時刻を取得 118 this.timeB=Instant.now(); 119 timecalcu(); 120 labelTime1.setText(display); 121 } 122 ) 123 ); 124 //アニメーションの作動時間は無限とする。 125 timeline.setCycleCount(Timeline.INDEFINITE); 126 //アニメーション開始 127 timeline.play(); 128 129 /*もしストップボタンのスイッチがtrueであるならばStopせよ*/ 130 if(stopSW==true){ 131 132 timeline.stop(); 133 System.out.println("お願いだから止っておくれ"); 134 135 } 136 137 138 } 139 public void timecalcu(){ 140 System.out.println("timecalcuメゾット起動"); 141 142 //ローカル変数 143 long longans; 144 LocalTime LocalTimeans; 145 Instant Instantans; 146 ZonedDateTime ZonedDatetimeans; 147 148 //Duration.betweenに2つの瞬間時間を引渡し、かかった時間をduratonansにリターンさせる。 149 this.durationans=Duration.between(timeA,timeB); 150 151 /*2018年7月現在、Durationクラスには文字列へのフォーマッタが準備されていない(!) 152 仕方がないのでlong型と他の日付クラスを介してString型に変換する。*/ 153 154 // longans=durationans.getSeconds(); これだとうまくいかない。 155 156 //duration型からlong型に変換する。 157 longans=durationans.toMillis(); 158 159 /*<参考> this.display=""+longans; 160 JDKの自動型変換のルールを利用してlong型からStrng型へ変換する方法も見つけた。*/ 161 162 //long型からInstant型へ変換する。 163 Instantans=Instant.ofEpochMilli(longans); 164 165 //Instant型からZonedDateTimeTime型へ変換する。 166 ZonedDatetimeans=Instantans.atZone(ZoneId.of("Asia/Tokyo")); 167 168 //ZonedDateTimeTime型からLocalTime型へ変換する。 169 LocalTimeans=ZonedDatetimeans.toLocalTime(); 170 171 //9時間の時差の分を調整する。 172 LocalTimeans=LocalTimeans.minusHours(9); 173 174 //LocalTime型からString型へ変換する。(予め準備しておいたformatter1を使用している) 175 display=formatter1.format(LocalTimeans); 176 177 System.out.println(display); 178 } 179 180 public void stopSW() { 181 System.out.println("stopSWメゾット起動"); 182 this.stopSW=true; 183 System.out.println(this.stopSW); 184 185 //event->{timeline.stop()}; 186 187 } 188 189 //JavaFXはmainから起動する。 190 public static void main(String[] args) { 191 launch(args); 192 } 193} 194

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

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

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

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

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

guest

回答1

0

ベストアンサー

変数:timelineをインスタンス変数に変更し各処理で呼び出せばよいかと。

1,Timeline timelineインスタンス変数で宣言。

Java

1 Timeline timeline;

2,pendulumメソッドの変数:timelineへの代入部分をstartメソッドに移動

Java

1 VBox.getChildren().addAll(HBox,HBox2); 2 timeline = 3 new Timeline( 4 new KeyFrame( 5 javafx.util.Duration.seconds(1), // 変更 6 event->{ 7 //現在時刻を取得 8 this.timeB=Instant.now(); 9 timecalcu(); 10 labelTime1.setText(display); 11 } 12 ) 13 ); 14 //アニメーションの作動時間は無限とする。 15 timeline.setCycleCount(Timeline.INDEFINITE); 16 Scene scene = new Scene(VBox,300, 250); 17 // 後略 18

3,stopSWメソッドはtimeline.stop();を呼び出す。

Java

1 public void stopSW() { 2 System.out.println("stopSWメゾット起動"); 3 this.stopSW=true; 4 System.out.println(this.stopSW); 5 timeline.stop(); // 追加 6 }

Java

1 Button btnSTA = new Button("Strat"); 2 Button btnSTO=new Button("Stop"); 3 //ストップウオッチの制御用にboolean型を1つ 4 boolean stopSW=false;

内部の状態が1つかないのであればトグル・ボタンが使えます。


◆質問分のソースコードを改造しました。
1, ToggleButtonクラスを使用。
2, StopWatchクラスを作成。
3, bindする形に変更したソースコードです。
ご参考まで。

Java

1package miyastopwatch9; 2 3import java.time.Instant; 4import java.time.LocalTime; 5import java.time.ZoneId; 6import java.time.ZonedDateTime; 7import java.time.format.DateTimeFormatter; 8 9import javafx.animation.KeyFrame; 10import javafx.animation.Timeline; 11import javafx.application.Application; 12import javafx.beans.binding.Bindings; 13import javafx.beans.property.DoubleProperty; 14import javafx.beans.property.SimpleStringProperty; 15import javafx.beans.property.StringProperty; 16import javafx.geometry.Pos; 17import javafx.scene.Scene; 18import javafx.scene.control.Label; 19import javafx.scene.control.ToggleButton; 20import javafx.scene.layout.VBox; 21import javafx.scene.layout.HBox; 22import javafx.scene.text.Font; 23import javafx.stage.Stage; 24import javafx.util.Duration; 25 26/** 27 * @author miya 28 */ 29public class MiyaStopwatch9 extends Application { 30 //フィールドの類 31 private final StopWatch stopWatch = new StopWatch(); 32 //続いてGUIの類です。 33 private final Label labelTime1 = new Label(); 34 private final ToggleButton button = new ToggleButton(); 35 36 @Override 37 public void start(final Stage primaryStage) { 38 // ※bind 39 labelTime1.textProperty().bind(stopWatch.timeProperty()); 40 // ※StopとStartのラベル変更をbind ToggleButton#setText()と同じ 41 button.textProperty().bind(Bindings.when(button.selectedProperty()).then("Stop").otherwise("Start")); 42 button.setOnAction(event -> { 43 final ToggleButton source = (ToggleButton) event.getSource(); 44 if (source.isSelected()) { 45 stopWatch.start();// ストップウォッチを開始 46 } else { 47 stopWatch.stop();// ストップウォッチを終了 48 } 49 }); 50 //フォントサイズの指定 51 labelTime1.setFont(new Font(50)); 52 53 //レイアウトはHBoXとVBoxの組み合わせで行いました。 54 final HBox HBox = new HBox(); 55 HBox.setAlignment(Pos.CENTER); 56 //HBox、横方向(H)にlabelTime1を整列させよ 57 HBox.getChildren().addAll(labelTime1); 58 59 final HBox HBox2 = new HBox(); 60 HBox2.setAlignment(Pos.CENTER); 61 //HBox2、横方向(H)にbuttonを整列させよ 62 HBox2.getChildren().addAll(button); 63 // ※setSpacingはコンストラクタでも設定可能です。 64 final VBox VBox = new VBox(20.0); 65 VBox.setAlignment(Pos.CENTER); 66 //VBox、縦方向(V)にHBoxとHbox2を整列させよ 67 VBox.getChildren().addAll(HBox, HBox2); 68 69 final Scene scene = new Scene(VBox, 300, 250); 70 primaryStage.setTitle("ストップウォッチ"); 71 primaryStage.setScene(scene); 72 primaryStage.show(); 73 } 74 75 //JavaFXはmainから起動する。 76 public static void main(String[] args) { 77 launch(args); 78 } 79} 80 81class StopWatch { 82 private final Timeline timeline; 83 84 //private final Duration START_TIME = Duration.hours(2); // 2時間 // 表示テスト用 85 //private final Duration START_TIME = Duration.minutes(3); // 3分 // 表示テスト用 86 private final Duration START_TIME = Duration.ZERO; 87 private Duration elapsed_time = START_TIME; 88 private final DateTimeFormatter formatter1 = DateTimeFormatter.ofPattern("H:mm:ss"); 89 90 private final StringProperty total_time = new SimpleStringProperty(format(elapsed_time)); 91 92 StopWatch() { 93 // ※pendulumから移動 94 // javafx.util.Duration.millis(1000) → Duration.seconds(1) 95 timeline = new Timeline(new KeyFrame(Duration.seconds(1), e -> { 96 final Duration duration = ((KeyFrame) e.getSource()).getTime(); 97 elapsed_time = elapsed_time.add(duration); 98 final String s = format(elapsed_time); 99 // デバック用 100 //System.out.println(s); 101 total_time.set(s); 102 })); 103 //アニメーションの作動時間は無限とする。 104 timeline.setCycleCount(Timeline.INDEFINITE); 105 } 106 107 public StringProperty timeProperty() { 108 return total_time; 109 } 110 111 public String format(final Duration duration) { // timecalcu 112 System.out.println("formatメソッド起動"); 113 //duration型からlong型に変換する。 114 long longans = (long) duration.toMillis(); 115 116 Instant Instantans = Instant.ofEpochMilli(longans); 117 ZonedDateTime ZonedDatetimeans = Instantans.atZone(ZoneId.of("Asia/Tokyo")); 118 119 //ZonedDateTimeTime型からLocalTime型へ変換する→9時間の時差の分を調整する。 120 LocalTime LocalTimeans = ZonedDatetimeans.toLocalTime().minusHours(9); 121 return formatter1.format(LocalTimeans); 122 } 123 124 public void start() { // startSW 125 System.out.println("startメソッド起動"); 126 elapsed_time = START_TIME; 127 final String s = format(elapsed_time); 128 total_time.set(s); 129 timeline.play(); 130 } 131 132 public void stop() { // stopSW 133 System.out.println("stopメソッド起動"); 134 timeline.stop(); 135 } 136}

投稿2018/09/08 13:36

編集2018/09/09 03:57
umyu

総合スコア5846

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

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

Miyahala

2018/09/09 14:16

timelineをインスタンス変数に置き換えて使用するという発想が初学者の私にはなくとても驚きでした。 トグル・ボタンの有用性も教えて下さり本当にありがとうございます。 書かれましたコードをまだ理解把握出来ていない部分も多いのですが、自分の以前のコードと見比べならら学習しプログラミングの技術を向上させていきたいと思います。 またどうしてもダメな時はどうぞ質問させてください。(^^;) 感謝致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問