大家好,我正在做一个线程来更新JFrame上的球,所以我重新绘制屏幕...然后将球更新到它的位置......然后再次绘制屏幕...绘制球和相同的周期......这是代码
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
Thread t = new Thread()
{
public void run()
{
while(true)
{
repaint();
b2.update(ob,2);
b2.paint(ob.getGraphics());
b2.setT(b2.getT() + 1);
try {
Thread.sleep(50);
} catch (InterruptedException ex) {
System.out.println("Error in Sleeping");
}
}
}
};
t.start();
}
但问题是我没有看到球...屏幕的油漆总是覆盖球,球就像在Jframe下面......
答案 0 :(得分:6)
如果您想在Swing中使用动画,建议使用的类是javax.swing.Timer
。此类允许您定期对事件调度线程执行操作。
Timer
tutorial 答案 1 :(得分:2)
一些一般规则
repaint
请求更新,但在尝试更新显示时,切勿直接致电update
和paint
。Graphics
上下文是一个共享资源,不保证在绘制周期之间是相同的,你永远不应该保持对它的引用。您也不应该依赖JComponent#getGraphics
的结果,此方法能够返回null。示例解决方案
您有多种选择,具体取决于您最终要达到的目标。
您可以使用SwingWorker
,但考虑到您所有进入无限循环的事实并且更容易使用SwingUtilities#invokeLater
然后实际使用publish
方法,方法实际上会更多的工作。
您也可以使用Thread
,但最终会遇到与使用SwingWorker
对于您所呈现的内容,simpliset解决方案实际上是javax.swing.Timer
public class Blinky {
public static void main(String[] args) {
new Blinky();
}
public Blinky() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new BlinkyPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
protected class BlinkyPane extends JPanel {
private JLabel blinkyLabel;
private boolean blink = false;
public BlinkyPane() {
setLayout(new GridBagLayout());
blinkyLabel = new JLabel("I'm blinking here");
blinkyLabel.setBackground(Color.RED);
add(blinkyLabel);
Timer timer = new Timer(250, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
blink = !blink;
if (blink) {
blinkyLabel.setForeground(Color.YELLOW);
} else {
blinkyLabel.setForeground(Color.BLACK);
}
blinkyLabel.setOpaque(blink);
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 100);
}
}
}
您可以查看Swing Timer和Concurrency in Swing了解详情
答案 2 :(得分:0)
如果您访问EDT(事件调度线程)之外的GUI组件,那么您可能会遇到奇怪的问题,如果您在EDT中执行长时间运行的任务,那么您也会遇到问题。
查看this帖子,了解有关GUI Threading in Java