我正在编写一些代码来创建彩色文本可视化效果。下面的代码负责可视化面板,并且 setCT(String c) 方法会被程序中的其他地方(正确地)调用。
不幸的是,在窗口大小未改变时,所需的可视化效果并没有发生。在那之前,该可视化面板只会保持黑色!出了什么问题?我尝试使用 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变量分别是该(可视化器)类的公共静态布尔值和字符串,paint方法在决定要绘制什么之前检查doVis的值。这部分没问题。强制Java进行适当的重绘才是问题所在!
JPanel
扩展了,而且setCT
方法在这个扩展类中吗? - lhlmgr