简体   繁体   中英

animate line drawing between two points in java using a Swing Timer

I am almost ready to give up.

I have a JPanel, with various lines and circles drawn on it. There are three JButtons, each button invokes a different action. When one of these is clicked, a new line and circle is added to the panel. How can I make it so that when this new circle is added, that the line is slowly drawn, and then the circle is added. It has to be with a swing timer rather than a thread.

This is my main class

import java.awt.BorderLayout;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class AnimateNode implements ActionListener {

    NodePane nodePane = new NodePane();
    JButton jb1, jb2, jb3;  
    JTextField tf;

    public static void main(String[] args) {

        AnimateNode animate = new AnimateNode();

    }

    public AnimateNode() {

        JFrame frame = new JFrame("Version13");     
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());

        JPanel jp1 = new JPanel();      

        tf = new JTextField(3);
        jb1 = new JButton("Search");
        jb2 = new JButton("Insert");
        jb3 = new JButton("Delete");
        jb1.addActionListener(this);
        jb2.addActionListener(this);
        jb3.addActionListener(this);
        frame.add(jp1, BorderLayout.SOUTH);
        jp1.add(tf);
        jp1.add(jb1);
        jp1.add(jb2);
        jp1.add(jb3);

        nodePane.setPreferredSize(new Dimension(1000, 600));
        frame.add(nodePane, BorderLayout.CENTER);
        frame.pack();
        frame.setLocationRelativeTo(null);
        nodePane.initialise();
        frame.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        String input = tf.getText();
        int numbInput = (int) ((Double.parseDouble(input)));

        if (e.getSource() == jb1) {
            // impement later
            tf.setText("");
        }

        if (e.getSource() == jb2) {
            nodePane.insert(numbInput);
            tf.setText("");

        }

        if (e.getSource() == jb3) {
            //implement later
            tf.setText("");

        }

    }

}

In a separate class "NodePane" is where the paintComponent method is. It iterates through a queue of nodes drawing circles for each and lines between them. I only want the last node added to use a timer. The last node added can be identified, but I am very confused as to how I implement a timer.

the code for paint component is a little like this :

public void paintComponent(Graphics g){
    super.paintComponent(g);
    Graphics2D g2D = (Graphics2D) g.create();
        root.level = 0;
        Queue<NodeForm<T>> queue = new LinkedList<NodeForm<T>>();
        queue.add(root);
        while (!queue.isEmpty()) {
            NodeForm<T> node = queue.poll();
            Point p = node.getLocation();
            paintLine(node, g2D);
            paintNode(node, p, g2D);
            int level = node.level;
            NodeForm<T> left = node.getLeft();
            NodeForm<T> right = node.getRight();
            if (left != null){
                left.level = level + 1;
                queue.add(left);
            }
            if (right != null){
                right.level = level + 1;
                queue.add(right);
            }
        }
    }

I am soon confused! I don't want the timer to effect every line and circle... just the last one. I really hope someone can help :)

For slowing down the drawing you need to create a Thread or you may use a timer . The trick is that you draw the line and sleep the Thread for some interval and draw longer line . It seems that line is slowly drawn.

class painter implements Runnable {

   @Override
   public void run() {

      // the Swing call below must be queued onto the Swing event thread
      SwingUtilities.invokeLater(new Runnable(){
         @Override
         public void run() {
            while(cond..){
               // OK To make Swing method calls here
               length_of_line++;
               yourPanel.repaint();
            }
         }
      });
      try {
         Thread.sleep(1000);
      } catch (InterruptedException e) {
        // ....
      }
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM