2011-01-03 7 views
2

ちょっと、私はプログラムで作業していますし、デバッグの目的で、ディスプレイの一部のスクリーンショットを取得するようにプログラムを取得しようとしています。ディスプレイを更新したいのですが、動作させることができません。私はそれが簡単な問題だと確信していますが、Javaアプレットでの私の経験は非常に小さいです。イメージをリフレッシュするためにJFrameを取得できません。

は、ここで私はとの問題を抱えている部分です:私が言ったように

... 
Thread.sleep(5000); 
    try {gb = new GameBoard(frame.getBounds());} 
    catch(Exception e){System.out.println("Error.");} // Make "gameboard" Object 

    while (true) 
    { 
     Thread.sleep(1000); 
     gb.grabImage(); // use java.awt.Robot's createScreenCapture() 

     ImageIcon icon = new ImageIcon(gb.image()); // wrap the image 
     JLabel label = new JLabel(icon, JLabel.CENTER); 
     frame.getContentPane().add(label,BorderLayout.EAST); //display the image (works) 
     //JOptionPane.showMessageDialog(null, label, "icon", -1); 
     label.repaint(); //update the display?? 
     frame.repaint(); 
     frame.getContentPane().repaint(); 
    } 

、画像が表示され、私はアプレットのサイズを変更する場合は、新しいものを作成しますが、私は常に変化し、画像を必要としています。

ありがとうございます!

+1

これはアプレットであり、アプリケーションではありませんか?私はデフォルト設定では、アプレットでjava.awt.Robotを作成することを禁止しています。 –

+1

これをやってみてください... 'label.revalidate(); label.repaint(); ' – Favonius

答えて

5

ループのたびに新しいJLabelを作成して追加しています。コンポーネントツリーの構造を変更しているので、フレームのコンテンツペインでrevalidateと呼ぶ必要があります。

もっと良い解決策は、単一のJLabelでイメージを変更することです。 1つのラベルを作成して追加し、ループ内でJLabel.setIconrepaintを使用します。

+1

ちなみに、Swingをスレッドで使用する方法については、SwingUtilities.invokeLater'と 'SwingUtilities.invokeAndwait'を使用して、イベントディスパッチスレッドのすべてのGUI変更を行う必要があります。スイングコンポーネントはスレッドセーフではないため、コンポーネントツリーの変更やSwingコンポーネントのsetter呼び出しは、他のスレッドから行うと安全ではありません。 –

2

@RDのように、createScreenCapture()は、アプレットが署名されていないとSecurityExceptionを投げます。イベントディスパッチスレッドでスリープ状態になると、更新がブロックされている可能性があります。このexampleは、マウスがドラッグされるときに画面イメージをキャプチャします。そのBufferedImageはキャプチャされた最後の画像を「記憶」する。

+1

微妙な疑問:信頼できない場合、アプレットはSecurityExceptionをスローします。これには、両方が署名されている必要があり、その時にユーザは署名されたコードを受け入れることができ、受け入れることを決定します。たとえば、JCPは、検証済みのセキュリティ証明書で署名されたコードを受け入れることができるように設定できますが、開発者が純粋に生成したコードでは受け付けないように設定できるため、これは微妙ですが重要な違いです。 –

+0

@Andrew Thompson:これを拡大してくれてありがとう! – trashgod

0

私が覚えていることは、repaint()はJavaで実際にinvalidate()と呼ばれているはずです。実際にはウィンドウを再描画しません。次の機会にOSによって再ペイントされるように、それを無効にするだけです。私はあなたのコードを慎重に見ていないが、これは問題かもしれないと思う。私は再描画を強制する方法はわかりませんが、考え方は関数から戻ってタイマーに割り込みさせてペイントしてください。そうすれば、OSはウィンドウをペイントする機会を得ます。

+1

'repaint'はコンポーネントをペイントする必要があるとマークします。 'invalidate'は、レイアウトを再計算する必要があるとマークします。もしあなたが**本当に**今すぐ再描画したいのであれば 'repaintImmediately'メソッドがありますが、あなたがやっていることについて絶対に確かめない限り、それを使いたくないのです。 –

+0

Javaで 'invalidate'メソッドがあるのを知らなかった - Windowsで(' InvalidateRect() 'のように)' invalidate'を参照し、.NET Framework( 'Control.Invalidate()'のように) )、それは塗装とレイアウトではないことを指しています。しかし、それを指摘してくれてありがとう、混乱のために申し訳ありません。 – Mehrdad

関連する問題