【发布时间】:2015-02-04 04:04:33
【问题描述】:
我试图从另一个类调用这个构造函数,但是当我创建新线程时,它不会调用重绘。如果我只是从类中的 main 方法调用 run() 方法,它会完全按预期工作。似乎我的 repaint() 方法没有从其他类中调用。我担心我的其他班级还在做计算,但即使把它放在一个线程中,我也没有运气。
代码:
public class MakeTransparent implements Runnable{
private int i;
private static int dollars;
private float transparency;
public MakeTransparent(int dollars){
this.setDollars(dollars);
this.transparency = 1;
this.i = 300;
}
@Override
public void run() {
JFrame frame = new JFrame("Tiddlybiscuits"){
private static final long serialVersionUID = 1L;
public void paint(Graphics arg0) {
Graphics2D g2 = (Graphics2D)arg0;
super.paint(g2);
g2.setColor(getBackground());
g2.fillRect(0, 0, this.getWidth(),this.getHeight());
g2.setColor(Color.CYAN);
g2.setFont(g2.getFont().deriveFont(50, 200F));
//System.out.println(arg0.getFontMetrics());
String string = "+$";
Composite c = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getTransparency());
g2.setComposite(c);
g2.drawString(string + getDollars(), 30, getI());
try {Thread.sleep(40);} catch (InterruptedException e) {}
setI(getI()-5);
setTransparency(getTransparency()-.03f);
repaint();
}
};
frame.setSize(500,500);
frame.setLocationRelativeTo(null);
frame.setUndecorated(true);
frame.setBackground(new Color(1,55,134,0));
frame.setLayout(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try { Thread.sleep(1400); } catch (InterruptedException e) { }
frame.dispose();
}
【问题讨论】:
-
这个
try {Thread.sleep(40);} catch (InterruptedException e) {}和setTransparency(getTransparency()-.03f);和repaint();不应该在任何paint方法中被调用。不要覆盖paint的JFrame或任何其他顶级容器,而是创建一个从JPanel类扩展的自定义类并覆盖它的paintComponent方法 -
为什么在paint()方法中调用repaint()?
-
Swing 也是一个单线程环境并且不是线程安全的,您应该只在事件调度线程的上下文中创建和修改您的 UI
-
根据您的描述,您似乎阻塞了事件调度线程。查看Concurrency in Swing 和Worker Threads and SwingWorker 了解更多详情。您不能简单地创建另一个线程并假设您的 UI 代码将在其中独占运行,这不是它的工作原理。大多数 UI 框架都有一个线程(主线程或事件线程),负责处理事件和管理更新。
-
仔细查看 Painting in AWT and Swing 和 Performing Custom Painting 了解更多关于如何在 Swing 中进行绘画的详细信息
标签: java multithreading swing class repaint