まず、ペイントをオーバーライドする必要がdrawingpanel
あります。これは、円を描く場所です。現在、円はコンポーネントの上にペイントされているため、実行ボタンを押したときにのみ表示されます。
通常の描画中に、アプレット領域が描画され (これが現在のpaint
作業場所です)、追加したすべてのコンポーネントが、既に描画されたドットの上に描画されます。
プログラムの先頭dot
はnull
であるため、ペイントはそれを正しく描画できません。NullPointerException がスローされます。
Graphics インスタンスを「キャッシュ」する必要はありません。ペイントで提供される Graphics を常に使用してください。
円を移動する場合は、値を更新してから の再描画をスケジュールするように、別のスレッドを作成する必要がありますdrawingpanel
。
また、アプレット全体を再描画する必要はなく、drawingpanel
.
それでも助けが必要な場合は、コメントで質問してください。
編集:
drawingpanel
ドットが描かれている場所は次のとおりです。
Panel drawingpanel = new Panel() {
public void paint(Graphics g) {
if (dot == null) {
return;
}
g.drawOval(dot.leftOf(), dot.topOf(), dot.widthOf(), dot.heightOf());
g.fillOval(dot.leftOf(), dot.topOf(), dot.widthOf(), dot.heightOf());
};
};
また、アプレットはメソッドBounce
をオーバーライドしません。paint()
アニメーションを実装するRunnable
には、セクションにインターフェイスを追加しますimplements
。
別のフィールドを追加します。
volatile boolean running = false;
private Thread animationThread;
それでは、簡単なアニメーションを実装しましょう。
public void run() {
while (running) {
if (!showtails) {
dot.setColor(drawingpanel.getBackground());
}
update();// check if speed, size, or shape changed
draw();// draw next dot based on move(), or initial condition
pause();
move();// calculate and prepare the coordinates for the next
// iteration to be drawn
}
}
public void draw() {
drawingpanel.repaint();
}
public void pause() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void move() {
dot.left--;
dot.top--;
}
最後の詳細はアクション ハンドラです。
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == this.runbutton) {
running = !running;
if (animationThread == null) {
animationThread = new Thread(this);
}
if (running) {
dot = new CircDot(100, 100, sizebar.getValue(), Color.RED);
animationThread.start();
}
} else
...
}
仕組みは次のとおりです。アクション ハンドラーで実装が開始さrun()
れ、コントロールが EDT に返されなかったため、アプリケーションがハングしたように見え、メッセージの処理が停止しました。
[実行] ボタンをクリックすると、状態フィールドrunning
が反転し、新しいスレッドがまだ開始されていない場合は作成されます。スレッドはrun()
メソッドを実行します。したがって、while
body内のアクションは、にrunning
なるまで実行されますfalse
。
- ペイント操作をスケジュールする
repaint()
上でdraw メソッドを呼び出します。drawingpanel
メッセージ キューが空になると、システムはそのpaint
メソッドを呼び出してパネルを再描画します。
- 一時停止メソッドを呼び出し
Thread.sleep(500)
て、500 ミリ秒間実行を停止します。数字が小さいほど、ドットは速く移動します。ここでの値は、何らかの形で速度に依存します。loop を使用して一時停止を実装しないでください。プロセッサの時間を浪費するだけで、どれだけの時間がかかるかを予測できません。
- move は減少
top
しleft
、ウィンドウの左上隅に移動するようにドットの座標を調整します。
フィールドは他の同期手段なしで複数のスレッドからアクセスされるため、running
が宣言されていることに注意してください。volatile
そこにない場合、実行中のアニメーションは、アクション ハンドラーの EDT からの変更を認識しない可能性があります。