Java:无法重新绘制()?
我正在写一些代码来创建文本的彩色可视化。下面的代码管理可视化面板,并从程序中的其他位置(正确)调用setCT(String c)方法 不幸的是,所需的可视化仅在调整窗口大小时发生。在此之前,vis面板一直保持黑色!发生了什么事?我尝试过使用validate()方法,还按照其他地方的指南创建了一个新的Runnable(),但没有成功。这是我的密码:Java:无法重新绘制()?,java,swing,jpanel,repaint,paintcomponent,Java,Swing,Jpanel,Repaint,Paintcomponent,我正在写一些代码来创建文本的彩色可视化。下面的代码管理可视化面板,并从程序中的其他位置(正确)调用setCT(String c)方法 不幸的是,所需的可视化仅在调整窗口大小时发生。在此之前,vis面板一直保持黑色!发生了什么事?我尝试过使用validate()方法,还按照其他地方的指南创建了一个新的Runnable(),但没有成功。这是我的密码: import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics;
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();
}
}
}
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.geom.Rectangle2D;
导入java.awt.image.buffereImage;
导入javax.swing.JPanel;
导入javax.swing.SwingUtilities;
导入javax.swing.Timer;
公共类Visualiser扩展JPanel实现ActionListener{
/**
*
*/
私有静态最终长serialVersionUID=-3936526023655045114L;
公共静态最终颜色默认值\u BG\u COL=Color.black;
专用静态彩色bgCol;
专用静态串ct;
私有静态缓冲区图像统计;
私有静态布尔doVis=false;
专用定时器刷新定时器=新定时器(100,此);
公共可视化器(){
这(200250);
}
公共可视化器(int w,int h){
超级设定尺寸(新尺寸(w,h));
super.setPreferredSize(新尺寸(w,h));
bgCol=visualizer.DEFAULT\u BG\u COL;
超级挫折背景(bgCol);
stat=新的BuffereImage(w,h,BuffereImage.TYPE_INT_ARGB);
refreshTimer.start();
}
/*公共空间涂料(图g){
*根据建议,替换为paintComponent()方法
超级油漆(g);
if(visualizer.doVis==true){
System.out.println(“通过doVis测试”);
多维斯(g);
}
}*/
公共组件(图形g){
if(Visualiser.doVis){
多维斯(g);
}
}
公共颜色getBGCol(){
返回bgCol;
}
公共交通工具(b色){
bgCol=b;
超级挫折背景(bgCol);
}
公共空间doVis(图g){
//我所有绘制可视化的代码都在这里
//恒剂量(g);
//使用字符串的长度确定块大小和高度
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;
对于(int i=1;i 对于(int j=1;j当您扩展JPanel
时,实现所需功能的快速、简单且干净的方法是覆盖执行渲染的JPanel.paintComponent()
方法
如果您想自动刷新GUI,那么我建议您选择swing计时器,在该计时器中,您可以不时调用JPanel.validate()
。您的面板可以如下所示:
public class TextRendererPanel extends JPanel{
protected void paintComponent(Graphics g){
// Do your rendering stuff here.
}
}
创建面板后,可以按如下方式刷新面板:
TextRendererPanel textRendererPanel = new TextRendererPanel();
textRendererPanel.invalidate();
这是一个可以开始使用的摆动计时器。您已经从JPanel
扩展,并且setCT
-方法在这个扩展类中?听起来好像您没有显示的代码中有错误;-)是时候做一个SSCCE来演示这个问题了……我们的荣幸:)请看我关于如何覆盖paintComponent
方法的更新谢谢你的回答。我已经编辑了我的原始Q,以显示Visualiser类的完整代码。关键是创建一个定时对象,定期刷新,并在调用这个visuali的类中首先,我包括一个Visualiser.invalidate();在Visualiser.setCT()调用之后直接调用。这似乎很管用!太棒了!很高兴它成功了。如果您认为它解决了您的问题,请不要忘记将其标记为一个答案;)@GETah:这只是一个小建议,在重写paintComponent()时保持封装完整
尽可能保持访问说明符
与父类/基类
中使用的相同,该说明符受保护,因此它是受保护的组件(…)
+1尽管对于其余部分:-)@user1509862和GETah:paintComponent实现在这两个方面都无效:-)JPanel的不透明度默认为true,即它负责始终完全填充其背景。因此,要么更改为返回false,要么调用super.paintComponent或任何其他方法填充背景