2012-04-04 28 views
5

Chciałem narysować obraz na moim panelu na podstawie danych, które otrzymuję z innego wątku. Jestem pewien, że dane i wynikowa macierz pikseli działa dobrze, ale funkcja repaint() nigdy nie będzie działać. Czy ktoś może mi powiedzieć, co tu jest nie tak?repaint() nie działa

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); 
     } 
    } 
} 

Dzięki

+9

'Thread.sleep (4000);' Nie blokuj EDT (wątku wysyłki zdarzeń) - GUI "zamrozi", kiedy to nastąpi. Zamiast wywoływania 'Thread.sleep (n)' implementuj Swing 'Timer' dla powtarzania zadań lub' SwingWorker' dla długotrwałych zadań. Więcej informacji można znaleźć w temacie [Współbieżność w Swingu] (http://docs.oracle.com/javase/tutorial/uiswing/concurenrency/). –

+0

Dziękujemy za natychmiastową reakcję. Ale jeśli po prostu usunę komunikat Thread.sleep (4000), to również nie działa. Jaki jest tego powód? – Daniel

+1

Jeśli po prostu czytasz linki, które podałem i wdrażam zalecenia, co się dzieje? –

Odpowiedz

0

Spróbuj repaint(); a następnie validate(); w apletu (PicturePlaza).

1

Tylko mała uwaga na repaint(). repaint() planuje odświeżenie ekranu, nie zawsze zrobi to natychmiast w moim doświadczeniu. Uważam, że najlepszym rozwiązaniem jest bezpośrednie wywołanie paint().

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

Uczyniłem to jako nową funkcję, aby wywołać mój kod, kiedy chciałem go od razu malować. Również to nie spowoduje usunięcia poprzedniej grafiki na ekranie, będziesz musiał to zrobić ręcznie.