延迟在java图形中不起作用

时间:2014-03-25 13:40:05

标签: java swing animation paintcomponent thread-sleep

这是使用Bresenham算法在计算位置绘制点的代码:

public void drawBresenhamPoints(Graphics2D g2, List<Point> bresenham) throws InterruptedException
{
       Graphics2D g = (Graphics2D) g2;

    if(bresenham == null)
        return;

    g.setColor(Color.DARK_GRAY);

    for(int i = 0; i < bresenham.size(); i = i+20)
    {
        int x = bresenham.get(i).x - pointWidth1/2;
        int y = bresenham.get(i).y - pointWidth1/2;

        int ovalW = pointWidth1;
        int ovalH = pointWidth1;

        g.fillOval(x, y, ovalW, ovalH);

            // delay
         try 
         {
             Thread.sleep(10);
         } 
         catch(Throwable e) 
         {
         System.out.println(e.getMessage()); 
         }
    }
}

列表'bresenham'包含在Bresenham的线绘制算法的帮助下预先计算的所有点。我想在'for'循环内设置1秒的延迟,以便在1秒的间隔后绘制每个点。 “延迟”部分中列出的部分不起作用。如何让'延迟'工作?     更具体地说,我希望在屏幕上以1秒的间隔逐个显示所有点。

2 个答案:

答案 0 :(得分:4)

我假设您在paint/paintComponent方法中调用此方法。

只是一个指针:永远不会睡觉油漆过程

而是使用javax.swing.Timer来执行重复任务。 会做的是

  • 有两个Lists。您的List<Point> bresenham和另一个List<Point> paintListbresenham将保留您的数据,paintList最初将为空。

  • 使用paintList绘制积分

    @override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
    
        for (Point p : paintList) {
            int x = bresenham.get(i).x - pointWidth1/2;
            int y = bresenham.get(i).y - pointWidth1/2;
    
            int ovalW = pointWidth1;
            int ovalH = pointWidth1;
    
            g.fillOval(x, y, ovalW, ovalH);
        }
    }
    
  • 虽然paintList中最初没有任何内容,但每次触发计时器事件时,您都会在列表中添加新的Point

    Timer timer = new Timer(100, new ActionListener(){
        @Override
        public void actionPerformed(ActionEvent e) {
            if (bresenham.isEmpty()) {
                ((Timer)e.getSource()).stop();
            } else {
                paintList.add(bresemham.get(0));
                bresenham.remove(0);
            }
            repaint();  
        }
    });
    timer.start();
    

    构造函数的基本计时器是delay,这是&#34;迭代&#34; 之间延迟的时间,以及实际侦听的侦听器中的第二个参数每delay毫秒触发的计时器事件。那么上面的代码基本上做的是为从Point列表中取出的paintList添加bresenham,然后移除调用repaint的{​​{1}}项。当列表为空时,计时器将停止。


<强>更新

这是一个完整的运行示例

paintComponent

答案 1 :(得分:0)

sleep方法的值为毫秒,因此您正在睡眠10毫秒。将其更改为1000将产生更明显的中断。

正如所指出的那样,你不应该在EDT上花费任何时间或更糟糕的锁定机制,因为它会挂起你的整个应用程序。您可以使用Timer来触发事件并一次绘制一个点。 This以前的SO帖子应该做你需要的。