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

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

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

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

Java

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

Q&A

解決済

1回答

1460閲覧

JavaFXによるタイマーの実装ができません(2画面)

k42um4

総合スコア5

JavaFX

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

Java

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

1グッド

0クリップ

投稿2019/12/16 13:39

前提・実現したいこと

 JavaとJavaFXを使って、メインウィンドウが出てからの経過時間をサブウィンドウで表示するプログラムを作っています。
サブウィンドウ用のfxmlファイルにminLabelとsecLabelを用意し、前者を1分ごとに、後者を1秒ごとにsetText()で更新しようと思っています(fx:idで紐づけてあります)。ラベルは横に3つ、minLabel、" : "が書かれたラベル、secLabelの順で並べてあります。
2つのウィンドウを出すことはできているのですが、時間計測の開始(timer.play())をどのタイミングですればよいかわかりませんし、そもそもtimer(今はTimerController.javaにあります)もどこに書くのかわかりません。

発生している問題・エラーメッセージ

サブウィンドウの表示が"00 : 00"のまま更新されません。

該当のソースコード

↓TimerController.java(サブウィンドウ用のコントローラーです)

java

1import java.net.URL; 2import java.util.ResourceBundle; 3import javafx.scene.control.Label; 4import javafx.scene.control.Alert; 5import javafx.scene.control.Alert.AlertType; 6import javafx.scene.control.ButtonType; 7import javafx.scene.control.Button; 8import javafx.animation.KeyFrame; 9import javafx.animation.Timeline; 10import javafx.event.ActionEvent; 11import javafx.event.EventHandler; 12import javafx.util.Duration; 13import javafx.fxml.Initializable; 14import javafx.fxml.FXML; 15 16public class TimerController implements Initializable{ 17 private int m = 0; 18 private int s = 0; 19 private int ms = 0; 20 private int secCounter = 0; 21 22 @FXML 23 private Label minLabel; 24 @FXML 25 private Label secLabel; 26 27 Timeline timer = new Timeline( //このtimerの置き場所もわかりません。 28 new KeyFrame(Duration.seconds(1), new EventHandler<ActionEvent>(){ 29 @Override 30 public void handle(ActionEvent event) { 31 countUp(s); 32 secCounter++; 33 secLabel.setText(castToString(s)); 34 } 35 }), 36 new KeyFrame(Duration.minutes(1), new EventHandler<ActionEvent>(){ 37 @Override 38 public void handle(ActionEvent event) { 39 countUp(m); 40 minLabel.setText(castToString(m)); 41 } 42 })); 43 44 45 @Override 46 public void initialize(URL url, ResourceBundle rb){ 47 secLabel.setText(castToString(s)); 48 minLabel.setText(castToString(m)); 49 } 50 51 public int getSecCounter(){return secCounter;} 52 53 public void startTimer(){ //使う場所がわからなかったので隔離しています。 54 timer.setCycleCount(Timeline.INDEFINITE); 55 timer.play(); 56 } 57 58 public String getTime(){ 59 return castToString(m) + " : " + castToString(s); 60 } 61 62 public void resetTimer(){ 63 timer.stop(); 64 m = 0; 65 s = 0; 66 secCounter = 0; 67 } 68 69 public void countUp(int t){ 70 t = (t == 59 ? 0 : t + 1); //1時間を超えることは確実にないと判断し、今はこうしてあります。 71 } 72 73 public String castToString(int i){ 74 return String.format("%02d", i); 75 } 76 77 public void evaluate(){ 78 timer.pause(); 79 showResult(getTime(), rank(secCounter)); 80 resetTimer(); 81 } 82 83 public void showResult(String time, int toggle){ 84 String message = null; 85 switch(toggle){ 86 case 0: 87 message = "Superb!"; 88 break; 89 case 1: 90 message = "Amazing."; 91 break; 92 case 2: 93 message = "Brilliant."; 94 break; 95 case 3: 96 message = "Cool."; 97 break; 98 case 4: 99 message = "Don't give up."; 100 break; 101 default: 102 message = "error."; 103 break; 104 } 105 String evaluation = message + "\nRECORD - " + time; 106 Alert result = new Alert(AlertType.NONE, evaluation, ButtonType.OK); 107 result.setTitle("RESULT"); 108 result.showAndWait(); 109 } 110 111 public int rank(int sec){ 112 int temp = sec / 10; 113 switch(temp){ 114 case 0: 115 return 0; 116 case 1: 117 return 0; 118 case 2: 119 return 1; 120 case 3: 121 return 2; 122 case 4: 123 return 3; 124 default: 125 return 4; 126 } 127 } 128} 129

↓MapGame.java(start()とmain()はここにあります)

Java

1import java.io.IOException; 2import java.util.ArrayList; 3import javafx.application.Application; 4import javafx.scene.Parent; 5import javafx.scene.Scene; 6import javafx.scene.control.Button; 7import javafx.scene.control.Label; 8import javafx.scene.control.TextField; 9import javafx.scene.layout.BorderPane; 10import javafx.scene.layout.Pane; 11import javafx.stage.Stage; 12import javafx.fxml.FXMLLoader; 13 14public class MapGame extends Application { 15 Stage stage; 16 Stage timerStage = new Stage(); 17 18 @Override 19 public void start(Stage primaryStage) throws Exception { 20 singleton = this; 21 stage = primaryStage; 22 primaryStage.setTitle("MAP GAME (STAGE 1)"); 23 Pane myPane_top = (Pane)FXMLLoader.load(getClass().getResource("MapGame.fxml")); 24 Scene myScene = new Scene(myPane_top); 25 primaryStage.setScene(myScene); 26 27 try{ 28 timerStage.initOwner(stage); 29 timerStage.setTitle(null); 30 Pane timerPane = (Pane)FXMLLoader.load(getClass().getResource("Timer.fxml")); 31 Scene timerScene = new Scene(timerPane); 32 timerStage.setScene(timerScene); 33 }catch(IOException e){ 34 e.printStackTrace(); 35 } 36 primaryStage.show(); 37 timerStage.show(); 38 timerStage.setX(stage.getX() + 1000); 39 } 40 41//関係ないので中略 42 43 public static void main(String[] args) { 44 launch(args); 45 } 46}

試したこと

 「Javafx タイマー」や、それに類するワードで検索し、簡単なプログラム(1秒ごとにラベルのテキストを更新するだけのもの)を実際に作り、動作の確認をしました。
javafx.animation.Timelineについても検索しました。

補足情報(FW/ツールのバージョンなど)

Java SE 8, JavaFX 8, Ubuntu

TN8001👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

サブウィンドウの表示が"00 : 00"のまま更新されません。

Java

1countUp(s); 2 3public void countUp(int t){ 4 t = (t == 59 ? 0 : t + 1); 5}

引数tを変えても元のm sは変わりません。

Java

1s = countUp(s); 2 3public int countUp(int t){ 4 return t == 59 ? 0 : t + 1; 5}

時間計測の開始(timer.play())をどのタイミングですればよいか

MapGameで何かのきっかけ(ゲームの開始等)で計時するんですよね?
その時にスタートなりリセットなり、することになりますね。

Java

1FXMLLoader loader = new FXMLLoader(getClass().getResource("Timer.fxml")); 2Scene timerScene = new Scene((Pane) loader.load()); 3TimerController timerController = (TimerController) loader.getController(); 4timerStage.setScene(timerScene); 5timerStage.show(); 6 7timerController.startTimer();

そもそもtimer(今はTimerController.javaにあります)もどこに書くのかわかりません。

時間の表示がTimer.fxmlだけならば、TimerControllerでいいんじゃないでしょうか。

投稿2019/12/16 20:02

編集2024/03/04 10:48
TN8001

総合スコア9315

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

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

k42um4

2019/12/17 01:28

動くようになりました。助かりました。ありがとうございます。 (ついで:貼ったコードではTimelineが1つ足りず、sをカウントアップしてからmのカウントアップをして……となっていました。)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問