使用java swing滑动抽屉动画

时间:2014-01-14 03:40:55

标签: java swing animation user-interface

我是使用java swing摆动和设计界面的新手。我希望抽屉在按钮点击时拉出滑动动画。首先,是否可以这样做,如果是,我该怎么做。谢谢。我将非常感谢您对某些具体方法信息的回应。

2 个答案:

答案 0 :(得分:2)

根据您想要达到的目标,您可以通过多种方式实现这些目标。

基本方法只需绘制graphics和Swing Timer

这将允许您简单地更新一个变量,该变量将作为绘制大小的基础,例如......

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.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class DrawerPaneTest {

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

    public DrawerPaneTest() {
        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 DrawerPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class DrawerPane extends JPanel {

        private boolean drawIn = false;
        private Timer timer;
        private int drawWidth = 0;
        private int drawDelta = 4;

        public DrawerPane() {
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    timer.stop();
                    drawIn = !drawIn;
                    drawDelta = drawIn ? 4 : -4;
                    timer.start();
                }
            });

            timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    drawWidth += drawDelta;
                    if (drawWidth >= getWidth() / 2) {
                        drawWidth = getWidth() / 2;
                        timer.stop();
                    } else if (drawWidth < 0) {
                        drawWidth = 0;
                        timer.stop();
                    }
                    repaint();
                }
            });
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(Color.RED);
            g2d.drawRect(0, 0, drawWidth, getHeight());
            g2d.dispose();
        }
    }

}

这是非常基本的,并没有考虑概念中的慢/慢等问题。对于那些,你最好看一个专门的动画框架,比如

你可能会使用它取决于你想要实现的目标,我个人喜欢时间框架,主要是因为它给了我很大的自由,因为像Trident这样的东西(大多数)被设计为能够提供例如,更改对象上的属性,例如大小或位置。虽然时间框架可以做到这一点,但需要更多的工作来实现这一点。

我没有使用过通用补间引擎,但是看到了一些很好的例子,例如Sliding-Layout,它们可能实际上满足了你的需求......

答案 1 :(得分:1)

首先,我认为你不应该使用Canvas,因为,IMO,如果没有必要,你不应该将Swing的组件与AWT混合(我说的是实际的组件你放置在GUI中 - 我知道Swing是建立在AWT之上的)。

您可能希望使用JPanel并使用其paintComponent方法执行自定义绘画。有很多关于此的教程(例如Lesson: Performing Custom Painting)。

一旦你弄清楚如何在JPanel(简单地使用Graphics2D绘图)中绘制抽屉,你就会想要为它制作动画:基本上,你只需要更新一些属性,很可能是某个位置......
你想要一些很好的缓和效果,一切都很容易处理和打包,我建议你看看Universal Tween Engine。我已经习惯了,也可以帮助你。

通用补间引擎库链接到项目后,只需使用以下呼叫:

Tween
    .to(drawerProperties, Type.POSITION, 10.0f)  // animate the POSITION property of your drawerProperties on 10.0 units of time
    .target(100)  // set the number of frames of that animation to 
    .ease(Quad.OUT)  // set a nice quadratic effect on the animation
    .start(tweenManager);  // launch the animation

然后,在其他地方,您只需运行Thread即可使用TweenManager不断更新TweenManager#update

再一次,它看起来很多工作,但它实际上非常容易使用,通用Tween引擎入门部分非常好。此外,如果你想真正为你的项目添加动画,这肯定是一个很好的工具:)

最后一点:您可能需要在Swing的事件调度线程中更新您的属性,具体取决于您的解决方案的实施方式。如果您对此不太了解,可以阅读Lesson: Concurrency in Swing - 或者如果您有具体问题,只需搜索 StackOverflow :)