- PR -

LightWeight Component時のダブルバッファリングについて

1
投稿者投稿内容
会議室デビュー日: 2003/10/03
投稿数: 11
投稿日時: 2004-09-10 15:59
始めは、Canvasクラスを継承して作ったのですが、
ただ画像を表示させて動かすだけなので、動作を軽くするため
Canvasクラスを継承せず、Componentクラスを継承して作り直しました。

作り直した後、画像がチラつきだしたので、Componentを登録したクラスの
updateメソッドをオーバーライドして、塗りつぶしによるチラつきは、解決できたのですが
描画によるチラつきが解決できずに困っています。
描画なので、ImageObserverが関係しているだろうと思って直しているのですが
進展しないので、質問してみました。
aa
ぬし
会議室デビュー日: 2004/01/08
投稿数: 299
投稿日時: 2004-09-10 22:10
ソースもないのでさっぱり分からないのですが、自分でダブルバッファリングを作りたいのでしょうか?

Canvasクラスで同様の問題(ちらつき)が生じないのであれば、Canvasクラスのソースを調べてみてはいかがでしょうか?
さくらば
大ベテラン
会議室デビュー日: 2002/11/12
投稿数: 145
投稿日時: 2004-09-10 22:21
こんにちは、さくらばです。

引用:

aaさんの書き込み (2004-09-10 22:10) より:
Canvasクラスで同様の問題(ちらつき)が生じないのであれば、Canvasクラスのソースを調べてみてはいかがでしょうか?



Canvas クラスはダブルバッファリングしていないのですが......

一番簡単にダブルバッファリングを実現する方法は AWT を使わずに Swing で書き直す
という方法です。Swing は何もしなくてもデフォルトでダブルバッファリングを使うよ
うになっています。

どうしても自分でダブルバッファリングを作りたいのであれば、J2SE 1.3 以前ならば
BufferedImage を使用して行います。

J2SE 1.4 以降であれば VolatileImage クラスもしくは BufferStrategry を使って
ダブルバッファリングを行います。詳しくは下の Web を見てください。

VolatileImage
http://www5.airnet.ne.jp/sakuraba/java/laboratory/JDK1.4/Graphics/VolatileImage/VolatileImage.html

BufferStrategy
http://www5.airnet.ne.jp/sakuraba/java/laboratory/JDK1.4/Graphics/BufferStrategy/BufferStrategy.html
会議室デビュー日: 2003/10/03
投稿数: 11
投稿日時: 2004-09-11 11:31
お返事、ありがとうございます。

自分で調べた結果、ImageObserverではなく
描画をするContainerクラスのpaintメソッドに問題があるようです

以下、Containerクラスのpaintメソッドより抜粋
public void paint(Graphics g) {
if (isShowing()) {
if (printing) {
synchronized (this) {
if (printing) {
if (printingThreads.contains(Thread.currentThread())) {
return;
}
}
} GraphicsCallback.PaintCallback.getInstance().
runComponents(component, g, GraphicsCallback.LIGHTWEIGHTS);
}
}
}

注目したのは、runComponents(component, g, GraphicsCallback.LIGHTWEIGHTS)の部分。

ImageObserverに指定されたオブジェクトから呼び出す、imageUpdateメソッド内の
repaint(long tm, int x, int y, int width, int height)は、指定された矩形領域を
再描画するのに対して、
runComponents(component, g, GraphicsCallback.LIGHTWEIGHTS)は、コンポーネントを
全体を再描画するので、チラつきがでていると思われます。

自分なりの結論なんですが、Componentクラスを継承して作る場合は、
アニメーションさせたいものが、1つならできるが
複数ある場合は、1つ1つインスタンスを生成しなけらばならない。

で、あってます?

会議室デビュー日: 2003/10/03
投稿数: 11
投稿日時: 2004-09-11 11:37
すいません。
aaさんへの、返答が抜けていました。

オフスクリーンを作って、ダブルバッファリングを行っても、
チラつきがでるので、質問をしました。
会議室デビュー日: 2003/10/03
投稿数: 11
投稿日時: 2004-09-11 11:49
すいません。
さくらばさんへの、返答も抜けていました。

実行する環境がJ2SE 1.1 相当なのでBufferedImageを使いたいのですが
実行するJVMが、Graphics2DをサポートしていないのでBufferedImageが使えません。

実行環境を書かなかった自分の、責任です。
お手数をかけて、すいませんでした。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2004-09-11 12:17
unibon です。こんにちわ。

引用:

蔵さんの書き込み (2004-09-11 11:49) より:
実行する環境がJ2SE 1.1 相当なのでBufferedImageを使いたいのですが
実行するJVMが、Graphics2DをサポートしていないのでBufferedImageが使えません。


たんにバッファを確保したいだけならば、古くからある createImage でも良いと思います。
http://java.sun.com/j2se/1.4/ja/docs/ja/api/java/awt/Component.html#createImage(int,%20int)
今はバッファの確保はどうされているのでしょうか。

引用:

蔵さんの書き込み (2004-09-10 15:59) より:
作り直した後、画像がチラつきだしたので、Componentを登録したクラスの
updateメソッドをオーバーライドして、塗りつぶしによるチラつきは、解決できたのですが
描画によるチラつきが解決できずに困っています。
描画なので、ImageObserverが関係しているだろうと思って直しているのですが
進展しないので、質問してみました。


「描画によるチラつき」という意味が良く分かりません。「塗りつぶしによるチラつき」との違いは、Image を使うかどうかですよね。だから ImageObserver が登場しているのですよね。Image のロードの問題でしょうか。(Java Applet にしていて、) Image がローカルファイルになく、リモートから HTTP で取得していてロードに時間がかかる場面でしょうか。
そもそも Canvas でうまく動くのなら Component にしなくても良いような気もするのですが、Component のほうが「軽い」んでしょうか?私は違わないと思っているのですが。

引用:

蔵さんの書き込み (2004-09-11 11:31) より:
自分なりの結論なんですが、Componentクラスを継承して作る場合は、
アニメーションさせたいものが、1つならできるが
複数ある場合は、1つ1つインスタンスを生成しなけらばならない。


これもちょっと良く分かりませんでした。インスタンスとはどのクラスのインスタンスでしょうか?Component から継承したクラスということのようですが、複数作ることは普通はあまりしないのではないでしょうか。

#「でしょうか」ばかりになってしまった。
Kissinger
ぬし
会議室デビュー日: 2002/04/30
投稿数: 428
お住まい・勤務地: 愛知県
投稿日時: 2004-09-11 20:53
蔵さん、こんにちは。

既にオフスクリーンによるダブルバッファを試したようですが、
それでチラつきはなくなると思います。
ただしその場合、かならず update()もオーバライドしなけれ
ば効果がありません。
paint()は update()から呼び出されますが、paint()を呼び出す
前にコンポーネントの背景をクリアしてしまいますから。
(Canvasもそうだったはずですが。)

試しに、
コード:
public update(Graphics g) {
	paint(g);
}


をオフスクリーンによるダブルバッファのコンポーネントクラ
スに追加してみてください。
1

スキルアップ/キャリアアップ(JOB@IT)