I am really struggling with a a project that I am working on. The eventual outcome should be an animation that shows algorithms in AVLTrees. I have managed to display a tree using values input by a user. But I am worried that they I have done it may prevent me being able to animate it. Each time a node is added, the entire tree is re drawn (up to a depth of four at the moment), is there a way (I assume after a lot of "if" statements) do gradually animate the new line added, and then have the new node appear? I apologise in advance if this is the worst code ever seen on here, I"m very new to java and struggling a lot!
package dissV12;
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("Version12");
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);
frame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
String input = tf.getText();
int numbInput = (int) ((Double.parseDouble(input)));
if (e.getSource() == jb1) {
tf.setText("");
}
if (e.getSource() == jb2) {
nodePane.insert(numbInput);
tf.setText("");
}
if (e.getSource() == jb3) {
tf.setText("");
}
}
}
This next class is where the drawing takes place. So I assume this is where I put the timer??? Beyond that, I have no idea what I'm doing but feel I have read everything on the internet :/
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.Timer;
public class NodePane extends JPanel implements ActionListener {
private Timer t;
AVLTree12<Integer> tree;
Node adding;
public NodePane() {
tree = new AVLTree12<Integer>();
adding = null;
t = new Timer(1000, this);
t.start();
}
public void addingNode(Node n) {
adding = n;
}
public void insert(int n) {
tree.insert(n);
tree.updateLevels();
Node nd = tree.getNodeSearch(n);
System.out.println(nd);
addingNode(nd);
repaint();
}
public void delete(int n){
if(tree.search(n)){
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g.create();
if (adding != null) {
Queue<Node> queue = new LinkedList<Node>();
queue.add(tree.root);
while (!queue.isEmpty()) {
Node node = queue.poll();
int level = node.getLevel();
if (level == 1) {
Point p = paintLevelOne(node, g2D);
paintNode(node, p, g2D);
}
if (level == 2) {
Node parent = node.getParent();
if (node.compareTo(parent) > 0) {
Point p = paintLevelTwo(node, 2, g2D);
paintLine(node, g2D);
paintNode(node, p, g2D);
}
if (node.compareTo(parent) < 0) {
Point p = paintLevelTwo(node, 1, g2D);
paintLine(node, g2D);
paintNode(node, p, g2D);
}
}
if (level == 3) {
Node parent = node.getParent();
Node gParent = parent.getParent();
if (node.compareTo(parent) < 0 && parent.compareTo(gParent) < 0) {
Point p = paintLevelThree(node, 1, g2D);
paintLine(node, g2D);
paintNode(node, p, g2D);
}
if (node.compareTo(parent) > 0 && parent.compareTo(gParent) < 0) {
Point p = paintLevelThree(node, 2, g2D);
paintLine(node, g2D);
paintNode(node, p, g2D);
}
if (node.compareTo(parent) < 0 && parent.compareTo(gParent) > 0) {
Point p = paintLevelThree(node, 3, g2D);
paintLine(node, g2D);
paintNode(node, p, g2D);
}
if (node.compareTo(parent) > 0 && parent.compareTo(gParent) > 0) {
Point p = paintLevelThree(node, 4, g2D);
paintLine(node, g2D);
paintNode(node, p, g2D);
}
}
if(level == 4){
Node parent = node.getParent();
Node gParent = parent.getParent();
Node gGParent = gParent.getParent();
if (node.compareTo(parent) < 0 && parent.compareTo(gParent) < 0 && gParent.compareTo(gGParent)<0) {
Point p = paintLevelFour(node, 1, g2D);
paintLine(node, g2D);
paintNode(node, p, g2D);
}
if (node.compareTo(parent) > 0 && parent.compareTo(gParent) < 0 && gParent.compareTo(gGParent)<0) {
Point p = paintLevelFour(node, 2, g2D);
paintLine(node, g2D);
paintNode(node, p, g2D);
}
if (node.compareTo(parent) < 0 && parent.compareTo(gParent) > 0 && gParent.compareTo(gGParent)<0) {
Point p = paintLevelFour(node, 3, g2D);
paintLine(node, g2D);
paintNode(node, p, g2D);
}
if (node.compareTo(parent) > 0 && parent.compareTo(gParent) > 0 && gParent.compareTo(gGParent)<0){
Point p = paintLevelFour(node, 4, g2D);
paintLine(node, g2D);
paintNode(node, p, g2D);
}
if (node.compareTo(parent) < 0 && parent.compareTo(gParent) < 0 && gParent.compareTo(gGParent)>0) {
Point p = paintLevelFour(node, 5, g2D);
paintLine(node, g2D);
paintNode(node, p, g2D);
}
if (node.compareTo(parent) > 0 && parent.compareTo(gParent) < 0 && gParent.compareTo(gGParent)>0) {
Point p = paintLevelFour(node, 6, g2D);
paintLine(node, g2D);
paintNode(node, p, g2D);
}
if (node.compareTo(parent) < 0 && parent.compareTo(gParent) > 0 && gParent.compareTo(gGParent)>0) {
Point p = paintLevelFour(node, 7, g2D);
paintLine(node, g2D);
paintNode(node, p, g2D);
}
if (node.compareTo(parent) > 0 && parent.compareTo(gParent) > 0 && gParent.compareTo(gGParent)>0){
Point p = paintLevelFour(node, 8, g2D);
paintLine(node, g2D);
paintNode(node, p, g2D);
}
}
Node left = node.getLeft();
Node right = node.getRight();
if (left != null) {
queue.add(left);
}
if (right != null) {
queue.add(right);
}
}
}
}
public void paintNode(Node n, Point p, Graphics2D g2d) {
if (n != null) {
FontMetrics fm = g2d.getFontMetrics();
int radius = (fm.getHeight()) * 2;
Ellipse2D circ = new Ellipse2D.Float(p.x, p.y, radius, radius);
g2d.draw(circ);
String text = String.valueOf(n.getData());
int xTextPos = p.x + ((radius - fm.stringWidth(text)) / 2);
int yTextPos = p.y
+ (((radius - fm.getHeight()) / 2) + fm.getAscent());
g2d.drawString(text, xTextPos, yTextPos);
}
}
public void paintLine(Node n, Graphics2D g2d) {
FontMetrics fm = g2d.getFontMetrics();
int radius = (fm.getHeight()) * 2;
Node parent = n.getParent();
Point p = parent.getLocation();
int xPar = p.x + (radius/2);
int yPar = p.y + radius;
Point pP = new Point(xPar, yPar);
Point pc = n.getLocation();
int xC = pc.x+(radius/2);
int yC = pc.y;
Point pC = new Point(xC, yC);
g2d.draw(new Line2D.Float(pP, pC));
}
public Point paintLevelOne(Node n, Graphics2D g2d) {
FontMetrics fm = g2d.getFontMetrics();
int radius = (fm.getHeight()) * 2;
int x = (getWidth() / 2) - (radius / 2);
int y = radius;
Point p = new Point(x, y);
n.setLocation(p);
return p;
}
public Point paintLevelTwo(Node n, int l2, Graphics2D g2d) {
FontMetrics fm = g2d.getFontMetrics();
int radius = (fm.getHeight()) * 2;
int x = (l2 * (getWidth() / 3)) - (radius / 2);
int y = 3 * radius;
Point p = new Point(x, y);
n.setLocation(p);
return p;
}
public Point paintLevelThree(Node n, int l3, Graphics g2d) {
FontMetrics fm = g2d.getFontMetrics();
int radius = (fm.getHeight()) * 2;
int x = (l3 * (getWidth() / 5)) - (radius / 2);
int y = 5 * radius;
Point p = new Point(x, y);
n.setLocation(p);
return p;
}
public Point paintLevelFour(Node n, int l4, Graphics g2d){
FontMetrics fm = g2d.getFontMetrics();
int radius = (fm.getHeight()) * 2;
int x = (l4 * (getWidth() / 9)) - (radius / 2);
int y = 8 * radius;
Point p = new Point(x, y);
n.setLocation(p);
return p;
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
I assume I won't need to show the Node Class and the Tree class.
If anyone can help I would cry much appreciate it :)
Aucun commentaire:
Enregistrer un commentaire