2012-04-04 8 views
5

別のスレッドから受け取ったデータに基づいてパネルに画像を描画したかったのですが、私はデータとその結果のピクセル配列がうまくいくと確信していますが、repaint()は決してうまくいかないでしょう。誰かここで何がうまくいかないのか教えてもらえますか?repaint()が機能しない

import javax.swing.*; 
import java.awt.*; 
import java.awt.image.*; 

/** Create an image from a pixel array. **/ 
public class PicturePlaza extends JApplet 
{ 
    ImagePanel fImagePanel; 
    ReadCom readComPort; 
    Thread readPortThread; 

    public void init() { 
    // initiate the read port thread so that it can receive data 
    readComPort = new ReadCom(); 
    readPortThread = new Thread(readComPort,"ReadCom"); 
    readPortThread.start(); 

    Container content_pane = getContentPane(); 
    fImagePanel = new ImagePanel(); 
    content_pane.add (fImagePanel); 

    } 

    // Tell the panel to create and display the image, if pixel data is ready. 
    public void start() { 
     while(true){ 
      if(readComPort.newPic){ 
       fImagePanel.go(); 
      } 
      try { 
        Thread.sleep(4000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 


/** Create an image from a pixel array. **/ 
    class ImagePanel extends JPanel{ 
     Image fImage; 
     int fWidth = ReadCom.row, fHeight = ReadCom.col;  

     void go() {   
        //update the image if newPic flag is set to true     
        fImage = createImage (new MemoryImageSource (fWidth, fHeight, ReadCom.fpixel, 0, fWidth)); 
        repaint(); 
        readComPort.newPic = false; //disable the flag, indicating the image pixel has been used                
     } 

     /** Paint the image on the panel. **/ 
     public void paintComponent (Graphics g) { 
     super.paintComponent (g);  
     g.drawImage (fImage, 0, 0, this); 
     } 
    } 
} 

おかげ

+9

'Thread.sleep(4000);' EDT(Event Dispatch Thread)をブロックしないでください。このとき、GUIはフリーズします。 を呼び出す代わりに、 'Thread.sleep(n)'はタスクを繰り返すためのスイング 'Timer'や長時間実行するタスクのための' SwingWorker'を実装します。 詳細については、[同時実行性](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)を参照してください。 –

+0

あなたの瞬時の対応に感謝します。しかし、単にThread.sleep(4000)ステートメントを削除しても、うまく動作しません。その理由は何ですか? – Daniel

+1

私が提供したリンクを読み、推奨事項を実装すれば、どうなるでしょうか? –

答えて

0

repaint();を試してみて、あなたのアプレット(PicturePlaza)でvalidate();

1

repaint()にちょっと注意してください。 repaint()は画面の再描画をスケジュールしますが、私の経験では必ずしも直ちにそれを行うとは限りません。私は最高の解決策は直接paint()自分自身を呼び出すことがわかった。

Graphics g; 
g = getGraphics(); 
paint(g); 

私はこれを直ちにペイントしたいときに私のコードを呼び出すための新しい関数としてこれを入れました。また、これは画面上の以前のグラフィックスを消去しないので、手動で行う必要があります。