java - 延迟在 Java 图形中不起作用

标签 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 秒的间隔在屏幕上一一绘制的所有点。

最佳答案

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

只是一个指针:永远不要 hibernate 绘画过程

而是使用 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 ,这是“迭代”之间的延迟时间,以及监听器中实际监听每隔 delay 触发的计时器事件的第二个参数之间的时间延迟。毫秒。所以上面的代码基本上所做的就是添加 PointpaintList取自bresenham列表,然后删除 repaint 项它调用 paintComponent 。当列表为空时,计时器将停止。

<小时/>

更新

这是一个完整的运行示例

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;

public class BresenhamPoints extends JPanel {

    private static final int D_W = 500;
    private static final int D_H = 500;

    private List<Point> bresenhamList;
    private List<Point> paintList;

    public BresenhamPoints() {
        bresenhamList = createRandomPoints();
        paintList = new ArrayList<>();

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

    private List<Point> createRandomPoints() {
        Random rand = new Random();
        List<Point> list = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            list.add(new Point(rand.nextInt(D_H), rand.nextInt(D_H)));
        }
        return list;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (Point p : paintList) {
            g.fillOval(p.x - 5, p.y - 5, 10, 10);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(D_W, D_H);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new BresenhamPoints());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

关于java - 延迟在 Java 图形中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22636362/

相关文章:

java - 如何使用 Google Analytics 分析 Java Swing 应用程序

html - 使用 CSS3 的水平幻灯片

ios - 沿键盘动画 UIView 出现动画

javascript - Jquery - 根据条件向左或向右 move 元素

java - 同时迭代和修改java队列

java - 无法使用 java 进程执行器执行单元脚本

java - 通过JOptionPane输入一个有字符限制的字符串

java - 使用 Tomcat 7、Apache Wink 和 Mongodb 在 WAR Deploy 上记录错误

java - 旋转图像(将其恢复到原始位置)

java - 我的 Jlists 没有发生滚动