アプリ版:「スタンプのみでお礼する」機能のリリースについて

勉強を始めたばかりなので稚拙な質問ですがお許しください。

ユーザーからの入力→repaint→画面に反映→プログラムが処理→repaint→画面に反映
というターン制のような動かし方をしたいのですが、実際にはユーザーの入力の後、プログラムの処理を待ってからまとめてrepaintしてしまいます。
repaint()は再描画を要求しているだけに過ぎず、repaint()と書いた場所で即時に再描画されるわけではないそうですが、では具体的にすぐ再描画してほしい場合はどうすればいいのでしょうか?

例えばですが、「ボタンを押すとcountの値が+1され、四角がcount個描画される。その一秒後に、こちらが何もしなくてもcountが+2されてもう一度四角がcount個(つまりこの時点で合計三個)描画される」というのを作ってみました。

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

public class question extends Applet implements ActionListener{
Button bt1;
int count = 0;

public void init(){
bt1 = new Button("start");
add(bt1);
bt1.addActionListener(this);
}

public void actionPerformed(ActionEvent e) {
if (e.getSource() == bt1) {
bt1.setEnabled(false);
count += 1;
repaint();

try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
}

count += 2;
repaint();
bt1.setEnabled(true);
}
}

public void paint(Graphics g){
for(int i = 0; i < count; i++){
g.drawRect(10, 10, 10 + i * 5, 10 + i * 5);
}
}
}

これではボタンを押すたびに3つずつ四角が増えているように外見上見えてしまいます。
ボタンを押すとしっかり1つ四角を表示してから一秒待って、2つ四角を増やす。という風にするためにはどうすればよいのでしょうか? どなたかご教示ください。

ちなみにpaintImmediatelyというものを見つけましたが、何故か使えず……(メソッドpaintImmediatelyは未定義ですと言われてしまう)

A 回答 (1件)

ひとつのイベントハンドラの中でスリープして2回に分けても


ひとつにまとめられてしまうというのはありそうなことです。
それにイベントハンドラの中でスリープするのはよくないです。

Swing Timerを使って、こんなふうにしてはどうでしょう。
http://ideone.com/y0mQ5
期待通りに動きましたよ。


import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;

import javax.swing.Timer;

public class question extends Applet implements ActionListener{
Button bt1;
int count = 0;
Timer timer;

public void init(){
bt1 = new Button("start");
add(bt1);
bt1.addActionListener(this);
timer = new Timer(1000, this);
}

public void actionPerformed(ActionEvent e) {
if (e.getSource() == bt1) {
bt1.setEnabled(false);
count += 1;
repaint();
timer.start();
} else if (e.getSource() == timer) {
count += 2;
repaint();
bt1.setEnabled(true);
timer.stop();
}
}

public void paint(Graphics g){
for(int i = 0; i < count; i++){
g.drawRect(10, 10, 10 + i * 5, 10 + i * 5);
}
}

}

参考URL:http://ideone.com/y0mQ5
    • good
    • 0
この回答へのお礼

おお、まさにこんな感じに動かしたかったのです!
swingにtimerというものがあるんですね、便利そうです。
swing timerで調べてみると色々なサンプルがあったので、これらも参考にしつつ作っていきたいと思います。
イベントハンドラ内のスリープが推奨されない理由も、調べてみて少し分かったような気持ちになりました。EDTがsleep中になってしまうと、例えばもう一度ボタンを押したとき固まったような感じになってしまうわけですね。
色々と本当にありがとうございます!まだまだひよっこですが、頑張ります。

お礼日時:2012/07/15 15:10

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!