java - Spring 行为模拟

标签 java swing timer paintcomponent imageicon

基本上,我想在绘制的图像上模拟 Spring 行为。我想让它通过一些迭代来放大和缩小(就像它固定在 Spring 上一样)。

我在网上找到的所有示例都指向此类 - FloatSpring.java

它应该提供所需的计算,以应用取决于各种 FloatSpring 类设置的类似 Spring 的效果将点 A 移动到点 B。问题是我没有找到一个清楚的例子来说明如何正确使用它。

我做了这个小例子来测试 FloatSpring:

public static void main ( String[] args )
{
    // Some image to bounce
    final ImageIcon icon =
            new ImageIcon ( WebProgressOverlayExample.class.getResource ( "icons/ava1.jpg" ) );

    // Component to paint image on
    JComponent spring = new JComponent ()
    {
        // Zoom value (1f = 100% = normal size)
        float zoom = 1f;

        {
            // Basic spring settings
            final FloatSpring fs = new FloatSpring ( 100 );
            fs.setPosition ( zoom );

            // Animation delay
            final int delay = 1000 / 24;

            // Animator
            new Timer ( delay, new ActionListener ()
            {
                private float elapsed = 0f;

                public void actionPerformed ( ActionEvent e )
                {
                    // Increasing elapsed time and updating spring
                    elapsed += delay;
                    fs.update ( 3f, elapsed );

                    // Updating zoom value and component
                    zoom = fs.getPosition ();
                    repaint ();
                }
            } ).start ();
        }

        protected void paintComponent ( Graphics g )
        {
            super.paintComponent ( g );

            // Scaled image
            int width = Math.round ( icon.getIconWidth () * zoom );
            int height = Math.round ( icon.getIconHeight () * zoom );
            g.drawImage ( icon.getImage (), getWidth () / 2 - width / 2,
                    getHeight () / 2 - height / 2, this );
        }

        public Dimension getPreferredSize ()
        {
            return new Dimension ( 500, 500 );
        }
    };

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

在此示例中,zoom 属性应在计时器周期内从 1f 反弹到 3f,并最终将显示在组件图像上的图像放大到 3 倍.类似于简单的动画过渡。

FloatSpring 类应该没问题 - 我只是不明白如何正确使用它。确切地说 - 我应该将什么指定为 springKdampingK 值以及 time 属性目的尚不清楚...

我真的很感激那里的任何帮助。

最佳答案

这是一个有效的 sscce使用 FloatSpring .

bungee

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.UIManager;

/**
* @see http://stackoverflow.com/a/11233735/230513
*/
public class Test {

    private static Spring spring = new Spring();

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(spring);
                frame.add(new JButton(new AbstractAction("Start") {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        spring.start();
                    }
                }), BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                spring.start();
            }
        });
    }

    private static class Spring extends JComponent {

        private static final int SIZE = 500;
        private static final int DELAY = 1000 / 20; // ~20Hz
        private final Icon icon = UIManager.getIcon("OptionPane.informationIcon");
        private final FloatSpring fs = new FloatSpring(42);
        private final int target = 0;
        private final float delta = 1f / SIZE;
        private float elapsed = 0f;
        private Timer timer = new Timer(DELAY, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if ((int) fs.getPosition() < (target + 1)) {
                    timer.stop();
                    return;
                }
                elapsed += delta;
                fs.update(target, elapsed);
                repaint();
            }
        });

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            int x = (getWidth() - icon.getIconWidth()) / 2;
            int y = (int) fs.getPosition();
            icon.paintIcon(this, g, x, y);
            int xc = x + icon.getIconWidth() / 2;
            g.drawLine(xc, 0, xc, y);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(SIZE / 2, SIZE);
        }

        public void start() {
            timer.stop();
            elapsed = 0;
            fs.setPosition(SIZE - icon.getIconHeight());
            fs.setVelocity(0);
            timer.start();
        }
    }
}

关于java - Spring 行为模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11228554/

相关文章:

java - 模型更新时更新 JTree 中的选择路径

java - 在 Java 中显示 UTF-8 表情符号

java - 在 JFrame 中添加同一类的两个组件

c++ - C/C++ 经过的进程周期,不包括在断点处

python - 改变QLabel大小时PyQt5 "Timers cannot be started from another thread"错误

java - '需要身份验证。测试 IAB 时,您必须登录您的 Google 帐户

java - 多线程锁定 Java Swing GUI

Java - 显示 JPopupMenu 时触发执行代码?

c++ - 用定时器停止程序

java - Reactor Core - Mono - onError Flatmap