- PR -

効率の良い描画方法とは?

投稿者投稿内容
ボム
ベテラン
会議室デビュー日: 2003/07/25
投稿数: 61
投稿日時: 2003-08-21 08:55
Ken-Lab様、ocean様、ご意見ありがとうございました。

Ken-Lab様より引用***************************************************************
>この状況から察すると処理が重いためではなく、とも様のご指摘やデバイスドライバのバグ
>が原因している可能性は考えられるかもしれません。
こうなってしまうと、どうしようもないですね・・・

>なお、確認後このアドレスは抹消します。
あぁー、確認前に抹消されてしまいました・・・
できればもう一度お願いできませんか?
*******************************************************************************


ocean様より引用*****************************************************************
>これを読むと、パネルがフォーカス可能かは実装しだいだが、Sunとしてはフォーカス不能な
>ように推奨しているようです。
>マウスでクリックしても、うんともすんとも言わなかったためです。
JDK1.4はフォーカス部分が強化されたと聞いた事があります。また描画部分も・・・

http://www-6.ibm.com/jp/developerworks/java/020308/j_j-awtfocus.htmlより引用****
>コードの多くが完全に書き直され、ある部分では、下位換性を犠牲にしてまで改善が行われて
>います
ここに書かれていましたね、思いっきり変更したんですね・・・。しかし仕様上JDK1.2でなんとか考えなくてはならないのです。

ご丁寧にソースまで見せていただき、ありがとうございました。是非参考にさせていただきます。
*******************************************************************************


ボム
ベテラン
会議室デビュー日: 2003/07/25
投稿数: 61
投稿日時: 2003-08-21 08:55
Ken-Lab様、ocean様、ご意見ありがとうございました。

Ken-Lab様より引用***************************************************************
>この状況から察すると処理が重いためではなく、とも様のご指摘やデバイスドライバのバグ
>が原因している可能性は考えられるかもしれません。
こうなってしまうと、どうしようもないですね・・・

>なお、確認後このアドレスは抹消します。
あぁー、確認前に抹消されてしまいました・・・
できればもう一度お願いできませんか?
*******************************************************************************


ocean様より引用*****************************************************************
>これを読むと、パネルがフォーカス可能かは実装しだいだが、Sunとしてはフォーカス不能な
>ように推奨しているようです。
>マウスでクリックしても、うんともすんとも言わなかったためです。
JDK1.4はフォーカス部分が強化されたと聞いた事があります。また描画部分も・・・

http://www-6.ibm.com/jp/developerworks/java/020308/j_j-awtfocus.htmlより引用****
>コードの多くが完全に書き直され、ある部分では、下位換性を犠牲にしてまで改善が行われて
>います
ここに書かれていましたね、思いっきり変更したんですね・・・。しかし仕様上JDK1.2でなんとか考えなくてはならないのです。

ご丁寧にソースまで見せていただき、ありがとうございました。是非参考にさせていただきます。
*******************************************************************************


未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-08-21 09:22
おはようございます。お疲れ様です。
引用:

Casperさんの書き込み (2003-08-21 08:55) より:
>この状況から察すると処理が重いためではなく、とも様のご指摘やデバイスドライバのバグ
>が原因している可能性は考えられるかもしれません。
こうなってしまうと、どうしようもないですね・・・

>なお、確認後このアドレスは抹消します。
あぁー、確認前に抹消されてしまいました・・・
できればもう一度お願いできませんか?



いえ、まだ降ろしてないです。セッション数がオーバーして表示されなかった可能性が
ありますので、再度ご覧いただければと思います。

別件です。逆に質問しちゃいますが、ハードまたはOSに起因しているかどうかの判断は
Casperさんご自身どのような手法で調査しますか?概念的な表現で構いません。
お手数おかけしますが、よろしくお願いします。
ボム
ベテラン
会議室デビュー日: 2003/07/25
投稿数: 61
投稿日時: 2003-08-21 10:20
Ken-Lab様、ご意見ありがとうございました。

Ken-Lab様より引用***************************************************************
>いえ、まだ降ろしてないです
そうでしたか、すみません。直に確認します。

>ハードまたはOSに起因しているかどうかの判断はCasperさんご自身どのような手法で調査し
>ますか?
特にこれといった調査は行っていません。ただ、"clearRect()"を入れる前のデバックでテストPCだと問題なく、本番機だと文字列が重なるという違いを見てハードやOSも原因の一つになりうるのでは?と思ったわけです。
*******************************************************************************

*先ほど確認したのですが、"■sample1 (clearRectなし、repaint 10回コール)"
と"■sample2 (clearRectあり、repaint 1回コール)"の各下に灰色の四角が表示される
だけでした。

また、マウスカーソルをそれぞれの四角に合わせるとIE画面の下の状態表示バー?(ページが表示されましたとかが表示される場所)に一瞬、"load:class sample5 not found"と"load:class bad sample not found"と表示されます。
考えられる理由はなんでしょうか?
IEのバージョンは6.0です。

[ メッセージ編集済み 編集者: Casper 編集日時 2003-08-21 10:33 ]
未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-08-21 11:41
引用:

Casperさんの書き込み (2003-08-21 10:20) より:
*先ほど確認したのですが、"■sample1 (clearRectなし、repaint 10回コール)"
と"■sample2 (clearRectあり、repaint 1回コール)"の各下に灰色の四角が表示される
だけでした。


お手数おかけしました。経路途中でアプレットがブロックされている可能性があると思います。
これにお時間かけてもなんですので、スクリーンショットに変更しました。

さて、ストライクを投げられればいいのですが、どうも押し出しのフォアボールになって
しまっているので、 このスレの参加はこれで最後にします。

ちょっと気がかりだったのは、Casper様ご自身がどのようにこの問題を分析しているのか
というところにあるような気がします。
回答者はCasper様が書かれた文字情報をもとに頭の中でバーチャルなオブジェクトを
生成し、それを基準に考える以外方法がありません。リアルはCasper様の手中です。
一番は、Casper様がまず問題の発生源がどこにあるのかを見極めることです。

その手段として消去法なんていうのがありますよね。
また逆に小さいところから積み上げていってどこで問題が生じるのかをみるとか(加算法?)。
で、問題のブロックを絞り込んで、そのソースを公開するといったような持っていきかた
をしないと余計な手間が増えて解決までに時間がかかります。
# プログラムを制作されているので、それは技術的に可能ではないでしょうか?
ボム
ベテラン
会議室デビュー日: 2003/07/25
投稿数: 61
投稿日時: 2003-08-21 13:22
Ken-Lab様、ご意見ありがとうございました。

たくさんのご意見、本当にありがとうございました。
描画に関してはもちろんですが、このような場での質問方法や問題解決の為に私ができる事、する事など大変に勉強になりました。

ありがとうございました。
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2003-08-21 13:28
oceanさん同様mouse clickによるfocus取得。アンド、文字列のスクロールサンプルを作ってみました。一応ある程度の同期処理は行っています。

このサンプルうちの環境(Pen III-450MHz, 4年落ちnote PC)では切れかかった蛍光灯のように、中途半端にちらつきます。VolatileImage使わずに、ちらつきを抑える良い方法ってあります?

ちょっと長めです
コード:
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.awt.event.*;

public class MyApp {
    public static void main(String[] inArgs) {
        final Frame f = new Frame();
		
		Panel panel = new Panel() {
			public void update(Graphics g) {
				paint(g);
			}
		};
		
		f.add(panel);
		
		panel.setLayout(new GridLayout(2, 1));
		panel.add(new MyPanel("No. 1"));
		panel.add(new MyPanel("No. 2"));
		
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
		
        f.pack();
        f.show();
    }
}

class MyPanel extends Component {
    private static final Font sFont = new Font("Serif", Font.BOLD, 32);

    private final String mText;
    private Rectangle mBounds;
    private Image mOffImage;
	private Graphics mOffGraphics;
	private int mOffsetX = 0;
	private int mOffsetY;
	private Object mLock = new Object();
	private boolean mModified;
	
    public MyPanel(String text) {
        mText = text;

		addFocusListener(new FocusHandler());
		addMouseListener(new MouseHandler());
        
        setFont(sFont);
        FontMetrics fm = getFontMetrics(sFont);
        mOffsetY = fm.getAscent();
        
        Rectangle2D aBounds = fm.getStringBounds(mText, getGraphics());
        mBounds = new Rectangle((int)aBounds.getX(), (int)aBounds.getY(), (int)aBounds.getWidth(), (int)aBounds.getHeight());
		mBounds.translate(0, mOffsetY);
		
        setBounds(mBounds);
        
        setModified(true);
    }
		
	public Dimension getPreferredSize() {
		return new Dimension(mBounds.width, mBounds.height);
	}
	
    public void paint(Graphics g) {
    	if (null == mOffImage) {
    		mOffImage = createImage(mBounds.width, mBounds.height);
	        if (null == mOffImage) {
	      		mOffImage = new BufferedImage(mBounds.width, mBounds.height, BufferedImage.TYPE_INT_RGB);
	      	}
  			mOffGraphics = mOffImage.getGraphics();
    	}
    	
    	synchronized(mLock) {
    		if (isModified()) {
	    		mOffGraphics.setColor(Color.white);
	    		mOffGraphics.fillRect(mBounds.x, mBounds.y, mBounds.width, mBounds.height);
	    		mOffGraphics.setColor(Color.black);
       			mOffGraphics.drawString(mText, mOffsetX, mOffsetY);
	        }
	        
	        g.drawImage(mOffImage, 0, 0, this);
	        
	        setModified(false);
	    }
    }

    private boolean isModified() {
    	return mModified;
    }
    
    private void setModified(final boolean inModified) {
    	mModified = inModified;
    }
    
    private class FocusHandler implements FocusListener {
    	private AnimateRunner mRunner;
    	
    	public void focusGained(FocusEvent inEvent) {
    		System.out.println(MyPanel.this.getClass() + " : " + mText + " (gained)");
    		mRunner = new AnimateRunner();
    		new Thread(mRunner, "animate").start();
    	}
    	
    	public void focusLost(FocusEvent inEvent) {
    		System.out.println(MyPanel.this.getClass() + " : " + mText + " (lost)");
    		mRunner.stop();
    	}
    }
	
	private class AnimateRunner implements Runnable {
		private boolean mStoped = false;
		
		public void run() {
			synchronized(mLock) {
				while(! isStoped() || mOffsetX != 0) {
					long aStartTime = System.currentTimeMillis();
					
					try {
						// Thread.sleep()がmonitorの所有権を離さないって書かれていたので、
						// wait()で指定した時間待ってみるようにした。
						long aTime = 0;
						do {
							mLock.wait(1);
							aTime = System.currentTimeMillis();
						}
						while (aTime - aStartTime < 30);
				
						mOffsetX = mBounds.width > mOffsetX ? ++mOffsetX : -mBounds.width;
						setModified(true);
						repaint(mBounds.x, mBounds.y, mBounds.width, mBounds.height);
					}
					catch (InterruptedException e) {
					}
				}
			}
		}
		
		synchronized void stop() {
			mStoped = true;
		}
		
		synchronized boolean isStoped() {
			return mStoped;
		}
	}
	
	private class MouseHandler implements MouseListener {
		public void mousePressed(MouseEvent inEvent) {
			FocusEvent aEvent = new FocusEvent(MyPanel.this, FocusEvent.FOCUS_GAINED);
			Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(aEvent);
		}
		
		public void mouseClicked(MouseEvent inEvent) {}
		public void mouseReleased(MouseEvent inEvent) {}
		public void mouseEntered(MouseEvent inEvent) {}
		public void mouseExited(MouseEvent inEvent) {}
	}
}

ocean
ベテラン
会議室デビュー日: 2003/07/06
投稿数: 65
投稿日時: 2003-08-22 13:56
AWTのフォーカスシステムは良くできていて、デフォルトでフォーカス不能でも、フォーカス可能なようにオーバーライドできるようです。1.2.2(win)で確認しました。これでも文字が重なったりしますか?

コード:

package test;

import java.awt.*;
import java.awt.event.*;

class MeApp
{
public static void main(String[] args)
{
final MeFrame f = new MeFrame();

f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});

f.pack();
f.show();
}
}

class MeFrame extends Frame
{
public MeFrame()
{
setLayout(new GridLayout(2, 5, 5, 5));

for (int i = 0; i < 10; ++i)
{
add(new MePanel("Panel#" + i));
}
}
}

class MePanel extends Component
{
private static final Font _font = new Font("Serif", Font.BOLD, 20);

private final Image _image1;
private final Image _image2;
private final String _text;

private Image _currentImage;
private String _currentText;

public MePanel(String text)
{
enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK);

_text = text;

_image1 =
Toolkit.getDefaultToolkit().createImage(
getClass().getResource("1.jpg"));

_image2 =
Toolkit.getDefaultToolkit().createImage(
getClass().getResource("2.jpg"));

final MediaTracker tracker = new MediaTracker(this);
tracker.addImage(_image1, 0);
tracker.addImage(_image2, 0);

try
{
tracker.waitForID(0);
}
catch (InterruptedException e)
{
throw new Error(e.getMessage());
}

handleFocus(false);
}

public Dimension getPreferredSize()
{
return new Dimension(94, 100);
}

public void paint(Graphics g)
{
g.setFont(_font);
g.drawImage(_currentImage, 0, 0, 94, 100, null);
g.drawString(_currentText, 15, 50);
}

private void handleFocus(boolean value)
{
if (value) // focus gained
{
_currentImage = _image2;
_currentText = "Focus";
}
else // focus lost
{
_currentImage = _image1;
_currentText = _text;
}

repaint();
}

/////////////////////////////////
// focus

public boolean isFocusTraversable() // after 1.4 deprecated (replace by isFocusable())
{
return true;
}

protected void processMouseEvent(MouseEvent e)
{
if (e.getID() == MouseEvent.MOUSE_PRESSED)
{
requestFocus();
}

super.processMouseEvent(e);
}

protected void processFocusEvent(FocusEvent e)
{
switch (e.getID())
{
case FocusEvent.FOCUS_GAINED:
handleFocus(true);
break;
case FocusEvent.FOCUS_LOST:
handleFocus(false);
break;
}

super.processFocusEvent(e);
}
}



#追記

これとか、これとかは関係ないのでしょうか?Linuxは使ったことがないので、よくわかりませんが・・・

#追記
Component.isFocusable()は1.4以降のメソッドでした。1.3以前ではisFocusTraversable()です。これで、タブでもフォーカスを移せます。

[ メッセージ編集済み 編集者: ocean 編集日時 2003-08-22 15:38 ]

[ メッセージ編集済み 編集者: ocean 編集日時 2003-08-22 19:01 ]


[ メッセージ編集済み 編集者: ocean 編集日時 2003-08-22 19:19 ]

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