java - 创建螺旋动画(延迟帮助)

标签 java animation delay sleep spiral

注意:我对 Java 还很陌生,所以如果答案非常简单,请记住这一点:)

我想做的就是制作一个漂亮的螺旋动画,就像播放音乐时在 Windows Media Player 中显示的动画一样,或者类似于 Windows XP 中的屏幕保护程序之一的动画。

我一直在试图弄清楚如何在创建一条线和创建另一条线之间创建延迟。

我希望程序以黑屏开始,每隔半秒左右,在与制作炫酷螺旋动画之前稍有不同的位置添加一行

我确信有一种方法可以使用 Thread.Sleep() 来做我想做的事情,但我只是不知道该怎么做。

任何帮助或建议将不胜感激! :D

我当前代码的图片:/image/fnD32.jpg

最佳答案

Swing 是单线程环境。当您想要定期更改 UI 的状态时需要小心。您需要确保不会以任何方式阻止事件调度线程,这样做会阻止处理任何新的绘制事件(以及其他事件),使您的 UI 看起来像是挂起的,并且还确保您正在同步您的使用事件调度线程进行更新,以确保您不会面临任何竞争条件或其他线程问题的风险

仔细看看Concurrency in Swing更多细节。一个简单的方法是使用 Swing Timer ,例如...

enter image description here

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Spinner {

    public static void main(String[] args) {
        new Spinner();
    }

    public Spinner() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new SpinnerPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class SpinnerPane extends JPanel {

        private float angle;

        public SpinnerPane() {
            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    angle -= 5;
                    repaint();
                }
            });
            timer.start();
        }

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

        protected Point calculateOutterPoint(float angel) {

            int radius = Math.min(getWidth(), getHeight());

            int x = Math.round(radius / 2);
            int y = Math.round(radius / 2);

            double rads = Math.toRadians((angel + 90));

            // This determins the length of tick as calculate from the center of
            // the circle.  The original code from which this derived allowed
            // for a varible length line from the center of the cirlce, we
            // actually want the opposite, so we calculate the outter limit first
            int fullLength = Math.round((radius / 2f)) - 4;

            // Calculate the outter point of the line
            int xPosy = Math.round((float) (x + Math.cos(rads) * fullLength));
            int yPosy = Math.round((float) (y - Math.sin(rads) * fullLength));

            return new Point(xPosy, yPosy);

        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
            g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

            int diameter = Math.min(getWidth(), getHeight());

            int x = (getWidth() - diameter) / 2;
            int y = (getHeight() - diameter) / 2;
            Point to = calculateOutterPoint(angle);
            g2d.drawLine(x + (diameter / 2), y + (diameter / 2), x + to.x, y + to.y);
            g2d.dispose();
        }

    }

}

使用类似的机制,我已经能够创建等待动画,例如......

enter image description here enter image description here

关于java - 创建螺旋动画(延迟帮助),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22877129/

相关文章:

flutter - 为两个文本小部件依次创建幻灯片动画的最佳方法是什么? flutter ?

javascript速度

用户输入后的 C# 时间延迟

notifications - Android Ble 延迟通知

java - 请正确初始化log4j系统警告

java - 启动简单的非基于 Web 的 Java 应用程序的官方 Spring Boot 方式是什么?

高精度的Java图形drawArc

java - java中根据文件名模式获取最新文件

wpf - 如何在 Wpf 中为按钮 FontSize 设置动画?

javascript - 如何将数据添加到 D3 堆叠面积图而不出现奇怪的动画故障?