2012-07-08 62 views
3

我正在編寫一些代碼來創建文本的彩色可視化。下面管理可視化面板,並從程序的其他地方(正確)調用setCT(String c)方法。Java:can not repaint()?

不幸的是,所需的可視化僅在窗口大小調整時發生。在那之前,可見面板只是保持黑色!到底是怎麼回事?我嘗試過使用validate()方法,並根據其他地方的指南創建一個新的Runnable(),但無濟於事。這裏是我的代碼:

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.geom.Rectangle2D; 
import java.awt.image.BufferedImage; 

import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 

public class Visualiser extends JPanel implements ActionListener { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = -3936526023655045114L; 
    public static final Color DEFAULT_BG_COL = Color.black; 
    private static Color bgCol; 
    private static String ct; 
    private static BufferedImage stat; 
    private static boolean doVis=false; 
    private Timer refreshTimer=new Timer(100, this); 

    public Visualiser() { 
     this(200, 250); 
    } 

    public Visualiser(int w, int h) { 

     super.setSize(new Dimension(w, h)); 
     super.setPreferredSize(new Dimension(w, h)); 
     bgCol = Visualiser.DEFAULT_BG_COL;  
     super.setBackground(bgCol); 
     stat = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); 
     refreshTimer.start(); 


    } 


    /*public void paint(Graphics g) { 
    * REPLACED BY paintComponent() METHOD AS PER SUGGESTION 
     super.paint(g); 
     if (Visualiser.doVis==true) { 
      System.out.println("passed doVis test"); 
      doVis(g); 
     } 

    }*/ 

    public void paintComponent(Graphics g) { 
     if(Visualiser.doVis) { 
      doVis(g); 
     } 
    } 

    public Color getBGCol() { 
     return bgCol; 
    } 

    public void setBGCol(Color b) { 
     bgCol = b; 
     super.setBackground(bgCol); 
    } 

    public void doVis(Graphics g) { 
     // all of my code to actually paint the visualisation is here 
     //doStatic(g); 
     // establish the block size and height using length of the string 
     int numBlocks = 3*ct.length(); 
     if (numBlocks != 0) { 
      int blockSize = (int) Math.sqrt((this.getWidth()*this.getHeight())/numBlocks) ; 
      Graphics2D g2 = stat.createGraphics(); 
      int blocksX=Math.round(this.getWidth()/blockSize); 
      int blocksY=Math.round(this.getHeight()/blockSize); 
      char chars[]=ct.toCharArray(); 
      int c=0; 
      int cc=0; 
      for(int i = 1; i< blocksX; i++) { 
       for(int j=1; j<blocksY; j++) { 
        cc=c+4; 
        if(cc < chars.length) { 
         //System.out.println("char length is: " + chars.length + " and c is: " + c); 
         g2.setColor(new Color((int) chars[c]%255, (int) chars[c+1]%255, (int)chars[c+2]%255)); 
         //System.out.println("color: " + g2.getColor().toString()); 
        } 
        g2.fill(new Rectangle2D.Double(i*blockSize, j*blockSize, blockSize, blockSize)); 
        c++; 
       } 
      } 

      g.drawImage(stat, 0, 0, this); 
     } 




    } 

    private void doStatic(Graphics g) { 
     Graphics2D g2 = stat.createGraphics(); 
     int x=this.getWidth(); 
     int y=this.getHeight(); 
     //System.out.println("x, y: " + x + " " + y); 
     for (int i=1; i<x; i++) { 
      for(int j=1; j<y; j++) { 
       g2.setColor(new Color(getRandom(0, 255), getRandom(0,255), getRandom(0,255))); 
       g2.fill(new Rectangle2D.Double(i, j, 1, 1)); 
      } 
     } 
     g.drawImage(stat, 0, 0, this); 

    } 


    private int getRandom(int min, int max) { 
     int random = min + (int) (Math.random() * (max - min)); 

     return random; 

    } 


    public void setCT(String c) { 
     Visualiser.doVis=true; 
     ct=c; 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       System.out.println("got to the new runnable thingie"); 

       repaint(); 
      } 
     }); 


    } 

    public void actionPerformed(ActionEvent e) { 
     if(e.getSource().equals(this.refreshTimer)) { 
      // the timer is the source so do some refreshing! 

      repaint(); 
     } 

    } 




} 

的doVis和CT變量都是公共靜態布爾&分別的這個字符串(Visualiser的)類和油漆方法決定畫什麼之前檢查doVis值。這部分是確定的。它迫使Java做一個適當的重繪,這是問題!

+0

你已經從'JPanel'擴展了,'setCT'-Method在這個擴展類中? – lhlmgr 2012-07-08 10:30:24

+0

聽起來像是你的代碼有問題,你是_not_顯示;-)時間爲SSCCE,演示問題... – kleopatra 2012-07-08 11:07:12

回答

2

隨着您在擴展JPanel,實現您所需的快速,簡單和乾淨的方法是替代執行渲染的方法JPanel.paintComponent()

如果你想自動刷新你的圖形用戶界面,那麼我建議你去擺動定時器,你現在需要撥打JPanel.validate()。您的面板可以像:

public class TextRendererPanel extends JPanel{ 
    protected void paintComponent(Graphics g){ 
     // Do your rendering stuff here. 
    } 
} 

創建之後,面板可被刷新這樣的:

TextRendererPanel textRendererPanel = new TextRendererPanel(); 
textRendererPanel.invalidate(); 

這裏是搖擺定時器,你可以開始tutorial

+0

我們的榮幸:)請參閱我的更新如何重寫'paintComponent'方法 – GETah 2012-07-08 11:30:59

+1

謝謝你答覆。我編輯了我的原始Q以顯示Visualiser類的完整代碼。關鍵是在調用這個可視化的類中創建一個定期刷新AND的定時器對象,我包含一個Visualiser.invalidate();在Visualiser.setCT()調用後直接調用。這似乎是訣竅! – user1509862 2012-07-08 11:46:13

+0

非常棒!很高興它的工作。如果您認爲它解決了您的問題,請不要忘記將其標記爲答案;) – GETah 2012-07-08 11:51:18