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

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

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

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

Q&A

解決済

2回答

1295閲覧

キッチンタイマーの出力された秒数を更新したい

kaito071831

総合スコア2

Java

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

0グッド

1クリップ

投稿2021/07/07 04:36

前提・実現したいこと

JavaのGUIを用いてキッチンタイマーを作ってたのですが、タイマーをスタートさせた時に秒数を格納している変数は毎秒1ずつ減少するのですが、時間を出力するテキストエリアの文字が更新されなくて困っています。どう変更すればうまく動作するでしょうか?

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

なし

該当のソースコード

Java

1import java.awt.*; 2import java.awt.event.*; 3import javax.swing.*; 4 5/** 6 * Timer 7 * @author kaito071831 8 */ 9public class Timer { 10 public static void main(String[] args) { 11 12 //フレームを生成 13 JFrame frame = new JFrame("キッチンタイマー"); 14 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 15 frame.setSize(400, 200); 16 frame.setLayout(new BorderLayout()); 17 18 //時間出力部分をtimeIOパネルに追加してパネルをフレームに追加 19 JPanel timeIO = new JPanel(); 20 timeIO.setLayout(new FlowLayout()); 21 22 JLabel timeMl = new JLabel("分"); 23 JLabel timeSl = new JLabel("秒"); 24 25 JTextArea timeM = new JTextArea(1, 10); 26 timeM.setText("00"); 27 28 JTextArea timeS = new JTextArea(1, 10); 29 timeS.setText("00"); 30 31 timeIO.add(timeMl); 32 timeIO.add(timeM); 33 timeIO.add(timeSl); 34 timeIO.add(timeS); 35 frame.add(timeIO, BorderLayout.NORTH); 36 37 //タイマー操作ボタンをactionパネルに追加してからフレームに設定 38 JButton reset = new JButton("Reset"); 39 frame.add(reset, BorderLayout.WEST); 40 41 JPanel action = new JPanel(); 42 action.setLayout(new BoxLayout(action, BoxLayout.Y_AXIS)); 43 frame.add(action, BorderLayout.EAST); 44 45 JButton start = new JButton("Start"); 46 start.setMaximumSize(new Dimension(80,80)); 47 action.add(start); 48 49 JButton stop = new JButton("Stop"); 50 stop.setMaximumSize(new Dimension(80,80)); 51 action.add(stop); 52 53 //時間設定ボタン定義する。buttonAパネルにbuttonLayoutパネルを追加してフレームに設定 54 JPanel buttonA = new JPanel(); 55 JPanel buttonLayout = new JPanel(); 56 57 buttonLayout.setLayout(new BoxLayout(buttonLayout, BoxLayout.Y_AXIS)); 58 frame.add(buttonA, BorderLayout.CENTER); 59 buttonA.add(buttonLayout); 60 61 JButton m10 = new JButton("10分"); 62 m10.setMaximumSize(new Dimension(100,50)); 63 64 JButton m1 = new JButton("1分"); 65 m1.setMaximumSize(new Dimension(100,50)); 66 67 JButton s10 = new JButton("10秒"); 68 s10.setMaximumSize(new Dimension(100,50)); 69 70 JButton s1 = new JButton("1秒"); 71 s1.setMaximumSize(new Dimension(100,50)); 72 73 //時間の値を設定するためにコンストラクタ生成 74 Time time = new Time(); 75 76 //10分追加ボタンのイベント処理 77 m10.addMouseListener(new MouseAdapter(){ 78 public void mouseClicked(MouseEvent e){ 79 80 time.min += 10; 81 82 if(time.min >= 60){ 83 time.min -= 60; 84 time.minO = Integer.toString(time.min); 85 timeM.replaceRange("0" + time.minO, 0, 2); 86 }else{ 87 time.minO = Integer.toString(time.min); 88 timeM.replaceRange(time.minO, 0, time.minO.length()); 89 } 90 91 } 92 }); 93 94 //1分追加ボタンのイベント処理 95 m1.addMouseListener(new MouseAdapter(){ 96 public void mouseClicked(MouseEvent e){ 97 98 time.min += 1; 99 100 if(time.min >= 60){ 101 time.min -= 60; 102 } 103 104 time.minO = Integer.toString(time.min); 105 106 if(time.minO.length() < 2){ 107 timeM.replaceRange(time.minO, 1, time.minO.length() + 1); 108 }else{ 109 timeM.replaceRange(time.minO, 0, time.minO.length()); 110 } 111 112 } 113 }); 114 115 //10秒追加ボタンのイベント処理 116 s10.addMouseListener(new MouseAdapter(){ 117 public void mouseClicked(MouseEvent e){ 118 119 time.sec += 10; 120 121 if(time.sec >= 60){ 122 time.sec -= 60; 123 time.secO = Integer.toString(time.sec); 124 timeS.replaceRange("0" + time.secO, 0, 2); 125 }else{ 126 time.secO = Integer.toString(time.sec); 127 timeS.replaceRange(time.secO, 0, time.secO.length()); 128 } 129 130 } 131 }); 132 133 //1秒追加ボタンのイベント処理 134 s1.addMouseListener(new MouseAdapter(){ 135 public void mouseClicked(MouseEvent e){ 136 137 time.sec += 1; 138 139 if(time.sec >= 60){ 140 time.sec -= 60; 141 } 142 143 time.secO = Integer.toString(time.sec); 144 145 if(time.secO.length() < 2){ 146 timeS.replaceRange(time.secO, 1, time.secO.length() + 1); 147 }else{ 148 timeS.replaceRange(time.secO, 0, time.secO.length()); 149 } 150 151 } 152 }); 153 154 //リセットボタンのイベント処理 155 reset.addMouseListener(new MouseAdapter(){ 156 public void mouseClicked(MouseEvent e){ 157 158 time.min = 0; 159 time.sec = 0; 160 time.totalSec = 0; 161 162 timeM.replaceRange("00", 0, timeM.getText().length()); 163 timeS.replaceRange("00", 0, timeS.getText().length()); 164 165 } 166 }); 167 168 //スタートボタンのイベント処理 169 start.addMouseListener(new MouseAdapter(){ 170 public void mouseClicked(MouseEvent e){ 171 172 int totalSec = time.getTotalSec(); 173 int ctotalSec = time.getTotalSec(); 174 175 for(int i=0; i<totalSec;i++){ 176 177 try { 178 179 Thread.sleep(1000); 180 time.sec--; 181 ctotalSec--; 182 183 //秒数が0未満になるとき分を1減らして秒数を59増やす 184 if(time.sec < 0){ 185 time.sec += 59; 186 time.min--; 187 time.minO = Integer.toString(time.min); 188 189 //分数が0未満のとき分の出力エリアの表示を00で固定する 190 if(time.min < 0){ 191 timeM.replaceRange("00", 0, time.minO.length()); 192 } 193 } 194 195 System.out.println(ctotalSec); 196 time.secO = Integer.toString(time.sec); 197 198 if(time.sec < 10){ 199 timeS.replaceRange("0" + time.secO, 0, time.secO.length() + 1); 200 }else{ 201 timeS.replaceRange(time.secO, 0, time.secO.length()); 202 } 203 204 } catch (Exception f) { 205 System.out.println(f); 206 } 207 208 } 209 } 210 }); 211 212 //時間設定ボタンをbuttonLayoutパネルに追加 213 buttonLayout.add(m10); 214 buttonLayout.add(m1); 215 buttonLayout.add(s10); 216 buttonLayout.add(s1); 217 218 frame.setVisible(true); 219 } 220} 221

Java

1public class Time { 2 3 int min; 4 int sec; 5 int totalSec; 6 String minO; 7 String secO; 8 9 public Time(){ 10 min = 0; 11 sec = 0; 12 totalSec = 0; 13 minO = "0"; 14 secO = "0"; 15 } 16 17 public int getMin(){ 18 return min; 19 } 20 21 public String outputTime(int minI){ 22 minO = Integer.toString(minI); 23 return minO; 24 } 25 26 public int getSec(){ 27 return sec; 28 } 29 30 public int getTotalSec(){ 31 return totalSec = min*60+sec; 32 } 33 34} 35

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

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

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

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

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

guest

回答2

0

解決されたようですが、気になった点の補足。

javax.swing.Timerのほうがいいと思います(動いているならいいですが^^;
java.util.Timer (Java Platform SE 8 )
javax.swing.Timer (Java Platform SE 8 )

ボタンのクリックは、通常MouseListenerでなくActionListenerを使用します。
JButton#addActionListener (Java Platform SE 8 )

class Time(時間量)に当たるものはすでに用意されています。
Duration (Java Platform SE 8 )

replaceRangeのためにJTextAreaを使用したと思いますが、入力するわけでないしJLabelでいいんじゃないですかね?

Java

1import java.awt.BorderLayout; 2import java.awt.Dimension; 3import java.awt.Font; 4import java.awt.GridLayout; 5import java.awt.Toolkit; 6import java.awt.event.ActionEvent; 7import java.awt.event.ActionListener; 8import java.time.Duration; 9import javax.swing.Box; 10import javax.swing.JButton; 11import javax.swing.JFrame; 12import javax.swing.JLabel; 13import javax.swing.JPanel; 14import javax.swing.Timer; 15 16 17public class TimerApp extends JFrame implements ActionListener { 18 public static void main(String[] args) { 19 new TimerApp().setVisible(true); 20 } 21 22 private final Timer timer; 23 private final JLabel label = new JLabel(); 24 25 private Duration duration = Duration.ZERO; 26 27 TimerApp() { 28 super("キッチンタイマー"); 29 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 30 setSize(400, 200); 31 setLocationRelativeTo(null); 32 33 timer = new Timer(1000, this); 34 35 label.setHorizontalAlignment(JLabel.CENTER); 36 label.setFont(new Font(Font.DIALOG, Font.BOLD, 20)); 37 add(label, BorderLayout.NORTH); 38 update(); 39 40 41 JButton reset = new JButton("Reset"); 42 reset.addActionListener(new ActionListener() { 43 @Override public void actionPerformed(ActionEvent e) { 44 timer.stop(); 45 duration = Duration.ZERO; 46 update(); 47 } 48 }); 49 add(reset, BorderLayout.WEST); 50 51 52 Box action = Box.createVerticalBox(); 53 add(action, BorderLayout.EAST); 54 55 JButton start = new JButton("Start"); 56 start.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE)); 57 // 以下ラムダを使用 reset.addActionListenerでやっているのの短縮形 58 start.addActionListener(e -> { 59 if (0 < duration.toSeconds()) { 60 timer.start(); 61 } 62 }); 63 action.add(start); 64 65 JButton stop = new JButton("Stop"); 66 stop.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE)); 67 stop.addActionListener(e -> timer.stop()); 68 action.add(stop); 69 70 71 JPanel buttonLayout = new JPanel(new GridLayout(0, 1)); 72 JPanel panel = new JPanel(); 73 panel.add(buttonLayout); 74 add(panel, BorderLayout.CENTER); 75 76 JButton m10 = new JButton("10分"); 77 m10.addActionListener(e -> { 78 duration = duration.plusMinutes(10); 79 update(); 80 }); 81 buttonLayout.add(m10); 82 83 JButton m1 = new JButton("1分"); 84 m1.addActionListener(e -> { 85 duration = duration.plusMinutes(1); 86 update(); 87 }); 88 buttonLayout.add(m1); 89 90 JButton s10 = new JButton("10秒"); 91 s10.addActionListener(e -> { 92 duration = duration.plusSeconds(10); 93 update(); 94 }); 95 buttonLayout.add(s10); 96 97 JButton s1 = new JButton("1秒"); 98 s1.addActionListener(e -> { 99 duration = duration.plusSeconds(1); 100 update(); 101 }); 102 buttonLayout.add(s1); 103 } 104 105 // タイマーイベント 106 @Override public void actionPerformed(ActionEvent e) { 107 duration = duration.minusSeconds(1); 108 update(); 109 110 if (duration.toSeconds() <= 0) { 111 timer.stop(); 112 System.out.println("時間です"); 113 Toolkit.getDefaultToolkit().beep(); // 手元ではうまく鳴らなかった^^; 114 } 115 } 116 117 // 時間の更新 118 private void update() { 119// int seconds = duration.toSecondsPart(); // Java 9以降 120 int seconds = (int) (duration.toSeconds() % 60); 121 122 String text = String.format("%02d分 %02d秒", duration.toMinutes(), seconds); 123 label.setText(text); 124 } 125}

投稿2021/07/07 09:23

TN8001

総合スコア9862

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

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

kaito071831

2021/07/07 15:02

回答していただきありがとうございます。 仰る通りだと思うところもありながら、 自分の知らなかった知識もありとても勉強になりました!
guest

0

自己解決

#解決しました。
###Thread.sleepやfor文を利用することをやめてTimerクラスのscheduleメソッドを用いて1000ミリ秒に1回周期的にカウントの処理を行うことようにすることでうまく動作しました。

投稿2021/07/07 05:44

kaito071831

総合スコア2

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問