- - PR -
LightWeight Component時のダブルバッファリングについて
1
| 投稿者 | 投稿内容 | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-09-10 15:59
始めは、Canvasクラスを継承して作ったのですが、
ただ画像を表示させて動かすだけなので、動作を軽くするため Canvasクラスを継承せず、Componentクラスを継承して作り直しました。 作り直した後、画像がチラつきだしたので、Componentを登録したクラスの updateメソッドをオーバーライドして、塗りつぶしによるチラつきは、解決できたのですが 描画によるチラつきが解決できずに困っています。 描画なので、ImageObserverが関係しているだろうと思って直しているのですが 進展しないので、質問してみました。 | ||||||||||||
|
投稿日時: 2004-09-10 22:10
ソースもないのでさっぱり分からないのですが、自分でダブルバッファリングを作りたいのでしょうか?
Canvasクラスで同様の問題(ちらつき)が生じないのであれば、Canvasクラスのソースを調べてみてはいかがでしょうか? | ||||||||||||
|
投稿日時: 2004-09-10 22:21
こんにちは、さくらばです。
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 | ||||||||||||
|
投稿日時: 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つインスタンスを生成しなけらばならない。 で、あってます? | ||||||||||||
|
投稿日時: 2004-09-11 11:37
すいません。
aaさんへの、返答が抜けていました。 オフスクリーンを作って、ダブルバッファリングを行っても、 チラつきがでるので、質問をしました。 | ||||||||||||
|
投稿日時: 2004-09-11 11:49
すいません。
さくらばさんへの、返答も抜けていました。 実行する環境がJ2SE 1.1 相当なのでBufferedImageを使いたいのですが 実行するJVMが、Graphics2DをサポートしていないのでBufferedImageが使えません。 実行環境を書かなかった自分の、責任です。 お手数をかけて、すいませんでした。 | ||||||||||||
|
投稿日時: 2004-09-11 12:17
unibon です。こんにちわ。
たんにバッファを確保したいだけならば、古くからある createImage でも良いと思います。 http://java.sun.com/j2se/1.4/ja/docs/ja/api/java/awt/Component.html#createImage(int,%20int) 今はバッファの確保はどうされているのでしょうか。
「描画によるチラつき」という意味が良く分かりません。「塗りつぶしによるチラつき」との違いは、Image を使うかどうかですよね。だから ImageObserver が登場しているのですよね。Image のロードの問題でしょうか。(Java Applet にしていて、) Image がローカルファイルになく、リモートから HTTP で取得していてロードに時間がかかる場面でしょうか。 そもそも Canvas でうまく動くのなら Component にしなくても良いような気もするのですが、Component のほうが「軽い」んでしょうか?私は違わないと思っているのですが。
これもちょっと良く分かりませんでした。インスタンスとはどのクラスのインスタンスでしょうか?Component から継承したクラスということのようですが、複数作ることは普通はあまりしないのではないでしょうか。 #「でしょうか」ばかりになってしまった。 | ||||||||||||
|
投稿日時: 2004-09-11 20:53
蔵さん、こんにちは。
既にオフスクリーンによるダブルバッファを試したようですが、 それでチラつきはなくなると思います。 ただしその場合、かならず update()もオーバライドしなけれ ば効果がありません。 paint()は update()から呼び出されますが、paint()を呼び出す 前にコンポーネントの背景をクリアしてしまいますから。 (Canvasもそうだったはずですが。) 試しに、
をオフスクリーンによるダブルバッファのコンポーネントクラ スに追加してみてください。 | ||||||||||||
1
