栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

插入二进制搜索树时对节点的颜色进行动画处理

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

插入二进制搜索树时对节点的颜色进行动画处理

好的,这花了我想要的时间(10个月大的孩子没有
耐心)

在此处输入图片说明

基本概念围绕着一个想法,即您需要
在一段时间内从一种状态更改为另一种状态。

在给定开始时间和当前时间的情况下,我们可以计算
动画运行的时间,并在给定动画总时间的情况下,计算
当前进度。

借助此方法(以及一些巧妙的数学方法),我们可以计算从
开始状态到目标状态的当前状态。

我也做了动作,所以可能会有点过头,但是基本
前提保持不变。

我在动画
属性类中放置了有关需要更改的节点的有状态信息,并使用ajavax.swing.Timer标记了动画(以
合理的稳定速率)。然后,我根据需要更新每个节点的状态
并重新绘制屏幕。

import java.awt.BorderLayout;import java.awt.Color;import java.awt.Dimension;import java.awt.EventQueue;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.event.MouseAdapter;import java.awt.event.MouseEvent;import java.awt.geom.Ellipse2D;import java.awt.geom.Line2D;import java.text.NumberFormat;import java.util.HashMap;import java.util.Map;import java.util.Random;import javax.management.StringValueExp;import javax.swing.JComponent;import javax.swing.Jframe;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.Timer;import javax.swing.UIManager;import javax.swing.UnsupportedLookAndFeelException;public class AnimateNode {    public static void main(String[] args) {        new AnimateNode();    }    public AnimateNode() {        EventQueue.invokeLater(new Runnable() { @Override public void run() {     try {         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());     } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {     }     Jframe frame = new Jframe("Testing");     frame.setDefaultCloseOperation(Jframe.EXIT_ON_CLOSE);     frame.setLayout(new BorderLayout());     frame.add(new NodePane());     frame.pack();     frame.setLocationRelativeTo(null);     frame.setVisible(true); }        });    }    public interface Node {        public void paint(JComponent parent, Graphics2D g2d);        public void setColor(Color color);        public Color getColor();        public Node getParent();        public Node getLeft();        public Node getRight();        public void setLeftNode(Node node);        public void setRightNode(Node node);        public Point getLocation();        public void setLocation(Point p);    }    public class DefaultNode implements Node {        private int number;        private Node parent;        private Node left;        private Node right;        private Point location;        private Color color;        public DefaultNode(int number, Node parent) { this.parent = parent; color = UIManager.getColor("Panel.background"); this.number = number;        }        public void setLeftNode(Node left) { this.left = left;        }        public void setRightNode(Node right) { this.right = right;        }        public Node getParent() { return parent;        }        public Node getLeft() { return left;        }        public Node getRight() { return right;        }        @Override        public Point getLocation() { return location;        }        @Override        public void setLocation(Point location) { this.location = location;        }        @Override        public void paint(JComponent parent, Graphics2D g2d) { FontMetrics fm = g2d.getFontMetrics(); int radius = fm.getHeight(); Point p = getLocation(); int x = p.x - (radius / 2); int y = p.y - (radius / 2); Ellipse2D node = new Ellipse2D.Float(x, y, radius, radius); g2d.setColor(getColor()); g2d.fill(node); g2d.setColor(Color.GRAY); g2d.draw(node); String text = String.valueOf(number); x = x + ((radius - fm.stringWidth(text)) / 2); y = y + (((radius - fm.getHeight()) / 2) + fm.getAscent()); g2d.drawString(text, x, y);        }        @Override        public void setColor(Color color) { this.color = color;        }        @Override        public Color getColor() { return color;        }        @Override        public String toString() { return number + " @ " + getLocation();        }    }    public class AnimationProperties {        private Point startPoint;        private Point targetPoint;        private Color startColor;        private Color endColor;        private Node node;        public AnimationProperties(Node node) { this.node = node;        }        public Node getNode() { return node;        }        public void setTargetColor(Color endColor) { this.endColor = endColor;        }        public void setStartColor(Color startColor) { this.startColor = startColor;        }        public void setStartPoint(Point startPoint) { this.startPoint = startPoint;        }        public void setTargetPoint(Point targetPoint) { this.targetPoint = targetPoint;        }        public Color getTargetColor() { return endColor;        }        public Color getStartColor() { return startColor;        }        public Point getStartPoint() { return startPoint;        }        public Point getTargetPoint() { return targetPoint;        }        public Point getLocation(float progress) { return calculateProgress(getStartPoint(), getTargetPoint(), progress);        }        public Color getColor(float progress) { return blend(getStartColor(), getTargetColor(), 1f - progress);        }        public void update(float progress) { node.setLocation(getLocation(progress)); node.setColor(getColor(progress));        }    }    public class NodePane extends JPanel {        private int number;        private Node root;        private Map<Node, AnimationProperties> aniProperties;        private Timer animationTimer;        private Timer startTimer;        private long startTime;        private int runTime = 1000;        public NodePane() { aniProperties = new HashMap<>(25); root = addLeftNode(null); root.setColor(getBackground()); addMouseListener(new MouseAdapter() {     private Random rand;     @Override     public void mouseClicked(MouseEvent e) {         generateNextNode(root);         revalidate();//         repaint();     }     protected void generateNextNode(Node parent) {         Node child = null;         if (rand == null) {  rand = new Random(System.currentTimeMillis());         }         boolean left = rand.nextBoolean();         if (left) {  child = parent.getLeft();         } else {  child = parent.getRight();         }         if (child == null) {  if (left) {      addLeftNode(parent);  } else {      addRightNode(parent);  }         } else {  generateNextNode(child);         }     } }); startTimer = new Timer(250, new ActionListener() {     @Override     public void actionPerformed(ActionEvent e) {         stopAnimation();         startTime = -1;         animationTimer.start();     } }); startTimer.setRepeats(false); animationTimer = new Timer(40, new ActionListener() {     @Override     public void actionPerformed(ActionEvent e) {         if (startTime < 0) {  startTime = System.currentTimeMillis();         }         float progress = 1f;         long duration = System.currentTimeMillis() - startTime;         if (duration >= runTime) {  ((Timer) e.getSource()).stop();         } else {  progress = (float) duration / (float) runTime;         }         for (AnimationProperties ap : aniProperties.values()) {  ap.update(progress);         }         repaint();         if (progress == 1f) {  aniProperties.clear();         }     } }); animationTimer.setRepeats(true); animationTimer.setCoalesce(true);        }        protected void stopAnimation() { if (animationTimer.isRunning()) {     animationTimer.stop();     for (AnimationProperties ap : aniProperties.values()) {         Node node = ap.getNode();         ap.setStartColor(node.getColor());         ap.setStartPoint(node.getLocation());     } }        }        public Point getStartPoint(Node node) { Point startPoint = node.getLocation(); while (startPoint == null) {     node = node.getParent();     startPoint = node.getLocation(); } return startPoint;        }        protected void layoutNode(Node node, int x, int y) { if (node != null) {     FontMetrics fm = getFontMetrics(getFont());     int nodeHeight = fm.getHeight();     if (node.getParent() != null) {         Point p = new Point(x, y);         Point sp = getStartPoint(node);         if (node.getLocation() == null) {  System.out.println("new node " + node);         }         if (node.getLocation() == null || !p.equals(node.getLocation())) {  AnimationProperties ap = new AnimationProperties(node);  ap.setStartColor(node.getColor());  ap.setTargetColor(getBackground());  ap.setStartPoint(sp);  ap.setTargetPoint(new Point(x, y));  node.setLocation(sp);  aniProperties.put(node, ap);  System.out.println("New Node to " + node);         } else {  aniProperties.remove(node);         }     } else {         nodeHeight *= 2;     }     layoutNode(node.getLeft(), x - nodeHeight, y + nodeHeight);     layoutNode(node.getRight(), x + nodeHeight, y + nodeHeight); }        }        @Override        public void doLayout() { System.out.println("DoLayout"); stopAnimation(); FontMetrics fm = getFontMetrics(getFont()); int nodeHeight = fm.getHeight(); int x = getWidth() / 2; int y = nodeHeight; if (root != null) {     root.setLocation(new Point(x, y));     layoutNode(root, x, y);//     Node node = root.getLeft();//     while (node != null) {//         x -= nodeHeight;//         y += nodeHeight;//         layout(node, x, y);//         node = node.getLeft();//     }//     node = root.getRight();//     x = getWidth() / 2;//     y = nodeHeight;//     while (node != null) {//         x += nodeHeight;//         y += nodeHeight;//         layout(node, x, y);//         node = node.getRight();//     } } startTimer.restart();        }        @Override        public Dimension getPreferredSize() { return new Dimension(200, 200);        }        protected Node createNode(Node parent) { DefaultNode child = new DefaultNode(++number, parent); child.setColor(Color.GREEN); System.out.println("Create new node " + child); return child;        }        protected Node addLeftNode(Node parent) { Node node = createNode(parent); if (parent != null) {     System.out.println("Add " + node + " to left of " + parent);     parent.setLeftNode(node); } return node;        }        protected Node addRightNode(Node parent) { Node node = createNode(parent); if (parent != null) {     System.out.println("Add " + node + " to right of " + parent);     parent.setRightNode(node); } return node;        }        @Override        protected void paintComponent(Graphics g) { super.paintComponent(g); if (root != null) {     Graphics2D g2d = (Graphics2D) g.create();     paintConnectors(root, g2d);     paintNode(root, g2d);     g2d.dispose(); }        }        protected void paintNode(Node node, Graphics2D g2d) { if (node != null && node.getLocation() != null) {     node.paint(this, g2d);     paintNode(node.getLeft(), g2d);     paintNode(node.getRight(), g2d); }        }        protected void paintConnectors(Node node, Graphics2D g2d) { if (node != null && node.getLocation() != null) {     Node parent = node.getParent();     if (parent != null) {         g2d.setColor(Color.GRAY);         if (parent.getLocation() != null && node.getLocation() != null) {  g2d.draw(new Line2D.Float(parent.getLocation(), node.getLocation()));         }     }     paintConnectors(node.getLeft(), g2d);     paintConnectors(node.getRight(), g2d); }        }    }    public static Point calculateProgress(Point startPoint, Point targetPoint, double progress) {        Point point = new Point();        if (startPoint != null && targetPoint != null) { point.x = calculateProgress(startPoint.x, targetPoint.x, progress); point.y = calculateProgress(startPoint.y, targetPoint.y, progress);        }        return point;    }    public static int calculateProgress(int startValue, int endValue, double fraction) {        int value = 0;        int distance = endValue - startValue;        value = (int) Math.round((double) distance * fraction);        value += startValue;        return value;    }    public static Color calculateProgress(Color start, Color target, double progress) {        return blend(start, target, progress);    }    public static Color blend(Color color1, Color color2, double ratio) {        float r = (float) ratio;        float ir = (float) 1.0 - r;        float rgb1[] = new float[3];        float rgb2[] = new float[3];        color1.getColorComponents(rgb1);        color2.getColorComponents(rgb2);        float red = rgb1[0] * r + rgb2[0] * ir;        float green = rgb1[1] * r + rgb2[1] * ir;        float blue = rgb1[2] * r + rgb2[2] * ir;        if (red < 0) { red = 0;        } else if (red > 255) { red = 255;        }        if (green < 0) { green = 0;        } else if (green > 255) { green = 255;        }        if (blue < 0) { blue = 0;        } else if (blue > 255) { blue = 255;        }        Color color = null;        try { color = new Color(red, green, blue);        } catch (IllegalArgumentException exp) { NumberFormat nf = NumberFormat.getNumberInstance(); System.err.println(nf.format(red) + "; " + nf.format(green) + "; " + nf.format(blue));        }        return color;    }}

Update with simple example ;)

Okay, this is a simple example. Basically, it just blinks the node…

import java.awt.BorderLayout;import java.awt.Color;import java.awt.Dimension;import java.awt.EventQueue;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.geom.Ellipse2D;import java.text.NumberFormat;import javax.swing.Jframe;import javax.swing.JPanel;import javax.swing.Timer;import javax.swing.UIManager;import javax.swing.UnsupportedLookAndFeelException;public class BlinkNode {    public static void main(String[] args) {        new BlinkNode();    }    public BlinkNode() {        EventQueue.invokeLater(new Runnable() { @Override public void run() {     try {         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());     } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {     }     Jframe frame = new Jframe("Testing");     frame.setDefaultCloseOperation(Jframe.EXIT_ON_CLOSE);     frame.setLayout(new BorderLayout());     frame.add(new TestPane());     frame.pack();     frame.setLocationRelativeTo(null);     frame.setVisible(true); }        });    }    public class TestPane extends JPanel {        // Animation stuff        private Timer aniTimer;        // The amount of time that each animation cycle plays for         // in millis        private int aniRunTime = 1000;        // The time the animation was started        private long startTime = -1;        // Our color ranges, where to start and where        // we want to get to and the current state...        private Color startColor;        private Color targetColor;        private Color color;        public TestPane() { // Initial state startColor = getBackground(); targetColor = Color.GREEN; color = startColor; aniTimer = new Timer(40, new ActionListener() {     @Override     public void actionPerformed(ActionEvent e) {         // Set the start time it hasn't already         if (startTime < 0) {  startTime = System.currentTimeMillis();         }         // We're always finished if we run over time...         float progress = 1f;         // Calculate the duration of play         long duration = System.currentTimeMillis() - startTime;         // Have we reached the end yet??         if (duration >= aniRunTime) {  // Reset the start time, this allows the   // animation to cycle.  Normally you would stop  // the timer, see the previous example  startTime = -1;  // Swap the start and target colors...  Color tmp = startColor;  startColor = targetColor;  targetColor = tmp;  color = startColor;         } else {  // Calculate the progress  progress = (float) duration / (float) aniRunTime;  // Blend the colors  color = blend(startColor, targetColor, 1f - progress);         }         // update the ui         repaint();     } }); aniTimer.setRepeats(true); aniTimer.setCoalesce(true); aniTimer.start();        }        @Override        public Dimension getPreferredSize() { return new Dimension(200, 200);        }        @Override        protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); int x = (getWidth() - 20) / 2; int y = (getHeight() - 20) / 2; g2d.setColor(color); Ellipse2D node = new Ellipse2D.Float(x, y, 20, 20); g2d.fill(node); g2d.setColor(Color.GRAY); g2d.draw(node); g2d.dispose();        }    }    public static Color blend(Color color1, Color color2, double ratio) {        float r = (float) ratio;        float ir = (float) 1.0 - r;        float rgb1[] = new float[3];        float rgb2[] = new float[3];        color1.getColorComponents(rgb1);        color2.getColorComponents(rgb2);        float red = rgb1[0] * r + rgb2[0] * ir;        float green = rgb1[1] * r + rgb2[1] * ir;        float blue = rgb1[2] * r + rgb2[2] * ir;        if (red < 0) { red = 0;        } else if (red > 255) { red = 255;        }        if (green < 0) { green = 0;        } else if (green > 255) { green = 255;        }        if (blue < 0) { blue = 0;        } else if (blue > 255) { blue = 255;        }        Color color = null;        try { color = new Color(red, green, blue);        } catch (IllegalArgumentException exp) { NumberFormat nf = NumberFormat.getNumberInstance(); System.err.println(nf.format(red) + "; " + nf.format(green) + "; " + nf.format(blue));        }        return color;    }}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/410333.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号