- PR -

1.4→1.3 で再描画おかしい

1
投稿者投稿内容
cap
会議室デビュー日: 2003/08/19
投稿数: 15
投稿日時: 2003-08-19 14:22
宜しくお願いします

現在、画像を取り込み、JPanel上に任意に回転・拡大し描画する
アプリケーションを作っています。

バージョンを当初1_4_1_03で作っていたのですが、
設計の都合で1_3_1_01に落とすことになりました。

バージョンを落としてから、画面の再描画がおかしくなりました。
ウインドウ上での操作(マウスやらボタンやら)で再描画するのは問題ないのですが、
ウインドウサイズを変えたり、
別の関係ないウインドウに隠してからもう一度前に出すと画像の表示位置がずれてしまいます。

画面構成として画像表示のパネルの上方(北?)に画像を操作するパネルを置いているのですが、
この操作パネルの高さ分、上にずれているように見えます。
(Frameの原点がJPanelの原点になっているように見えます。)

表示位置をずらさない方法をご存知の方
どなたかご教授お願いします。



ocean
ベテラン
会議室デビュー日: 2003/07/06
投稿数: 65
投稿日時: 2003-08-19 16:43
こんにちは。

たぶん違うと思いますが、1.4でビルドしたクラスファイルを1.3で動かすということでしょうか?だとしたら、1.3でビルドし直したほうが安全だと思います。

あと、動作可能なサンプルコードがあると検討しやすいです。
cap
会議室デビュー日: 2003/08/19
投稿数: 15
投稿日時: 2003-08-19 17:16
oceanさん 返信ありがとうございます

>1.3でビルドし直したほうが安全だと思います。
はい、ビルドはし直してあります。

>あと、動作可能なサンプルコードがあると検討しやすいです。
忠告ありがとうございます。全公開は業務上無理なのでpaint()メソッドだけ、
こんな感じです.

public void paint(Graphics g){
int midx;
int midy;
int width;
int height;
int ownerw;
int ownerh;
Image image;
Graphics2D g2;

if(isloading==false){

ownerw = this.getWidth();
ownerh = this.getHeight();

image = createImage(ownerw,ownerh);
image = ImageCalc.recalcImage(baseimg, contrast, blight,this);//コントラストの変更(別の自作クラスより)

g2=(Graphics2D)g;
AffineTransform at = new AffineTransform();
g2.setTransform(at);//空間を元に戻す

//イメージ表示端指定
width = (int)(w * scale);
height = (int)(h * scale);
midx = (ownerw - width)/2;
midy = (ownerh - height)/2;

//反転
if((rev & 1)==1){
at.concatenate(new AffineTransform(-1.0, 0.0, 0.0, 1.0, ownerw,0.0));
}
if((rev & 2)==2){
at.concatenate(new AffineTransform(1.0, 0.0, 0.0, -1.0, 0.0, ownerh));
}
g2.setTransform(at); //反転

//回転前に消す
g.setColor(Color.black);//背景色セット
g.fillRect(0,0,ownerw,ownerh+height);// 背景出し

//回転
g2.rotate(Math.toRadians(roll),ownerw/2,ownerh/2);

//表示
((Graphics)g2).drawImage(image, midx, midy, width, height, this); // 縮尺変更&画像の出力中央へ
}
}

多分無駄の多いソースだと思うので、御指摘かねがね
宜しくお願いします
ocean
ベテラン
会議室デビュー日: 2003/07/06
投稿数: 65
投稿日時: 2003-08-19 17:53
うーん。これだけではなんとも・・・

回転の部分のコードを消していくとか、単にイメージを描画しただけでも位置がずれるかとか、単純化していってください。そうすれば、原因が絞り込めると思います。

気になる点を2つ。
1.Swingでは、paint()よりpaintComponent()のオーバーライドが推奨されます。
2.super.paint()を呼ばないと、描画がおかしくなると思います。(パネル全体を画像が覆っている場合を除く)


[ メッセージ編集済み 編集者: ocean 編集日時 2003-08-19 18:55 ]
ocean
ベテラン
会議室デビュー日: 2003/07/06
投稿数: 65
投稿日時: 2003-08-19 19:20
実は、Graphics2Dを使ったことがなかったのですが・・・

コード:

protected void paintComponent(Graphics g)
{
super.paintComponent(g);

final Graphics2D g2 = (Graphics2D)g;

g2.setTransform(new AffineTransform()); // ※

g2.drawImage(_image, 0, 0, null);
}


という風にしたところ、おっしゃるような、フレームに原点があるような描画になりました。※の部分を除去すると、普通にパネルに原点があるような描画になります。これって、AffineTransform としては正しいのでしょうか?1.3.1_01でも、1.4.2でも同じ結果が得られました。

#追記

リファレンスによると、setTransform()は現在保持しているTransform値を上書きして、transform()は現在保持しているTransoform値に乗じるらしいです。

想像ですが、パネルを原点に持つこと自体が平行移動のTransformであり、g2 はそれを保持しているので、それを上書きしてしまうとフレーム原点になってしまうのではないでしょうか。そうだとすると、setTransform()ではなく、transform()を使うとうまくいくと思います。

あと、最初の「座標空間を戻す」は必要ないと思います。Graphicsはその都度新規作成されるので、デフォルトの座標空間に設定されているはずです。



[ メッセージ編集済み 編集者: ocean 編集日時 2003-08-19 19:40 ]
cap
会議室デビュー日: 2003/08/19
投稿数: 15
投稿日時: 2003-08-19 20:05
ocean さん ありがとうございました

返信書いてる間に解決してしまった・・・

おっしゃるとおり transform でやったらうまくいきました。
また 元に戻す も不要でした。

何度もフォローをいただきありがとうございました。
1

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