Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
563 views
in Technique[技术] by (71.8m points)

swing - Delay is not working in java graphics

This is a code for drawing points on calculated locations by Bresenham's algorithm:

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()); 
         }
    }
}

The list 'bresenham' contains all the points which are pre-calculated with the help of Bresenham's line drawing algorithm. I want to set a delay of 1 second inside the 'for' loop so that each and every point is drawn after an interval of 1 second. The portion listed in the 'delay' section doesn't work. How to make 'delay' work? More specifically, I want to see all the points being drawn one by one on the screen in an interval of 1 second.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I'm assuming you're calling this method in a paint/paintComponent method.

Just a pointer: Never ever ever sleep the paint process

Instead use a javax.swing.Timer for repeated tasks. What I would do is

  • Have two Lists. Your List<Point> bresenham and another List<Point> paintList. The bresenham will hold your data, and the paintList will be initially empty.

  • Use the paintList to paint your points

    @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);
        }
    }
    
  • Though there's nothing initially in the paintList, you will add a new Point to the list every firing of a timer event.

    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();
    

    The basic timer of the constructor is firs the delay, which is the time delayed between "iterations", and second argument in the listener that actually listens for the timer event that is fired every delay milliseconds. So what the code above basically does is add a Point to the paintList taken from the bresenham list, then removes the item the repaint which calls the paintComponent. When the list is empty, the timer will stop.


UPDATE

Here's a complete running example

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);
            }
        });
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...