2012-07-08 59 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