Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 带JComponents的滑动效果菜单_Java_Swing_Animation - Fatal编程技术网

Java 带JComponents的滑动效果菜单

Java 带JComponents的滑动效果菜单,java,swing,animation,Java,Swing,Animation,我正在尝试使用jlabel和计时器来产生一些滑动效果。 我只想使用两个计时器(IN和OUT)来管理多个组件的效果。 问题是,只有在我不快速地从一个JLabel移动到另一个JLabel并且我不知道如何管理它的情况下,一切都可以正常工作 这是我的密码: public class Sliders extends JFrame { private JPanel contentPane; JLabel label,label_1; static RainDrop frame; javax.swing

我正在尝试使用jlabel和计时器来产生一些滑动效果。 我只想使用两个计时器(IN和OUT)来管理多个组件的效果。 问题是,只有在我不快速地从一个JLabel移动到另一个JLabel并且我不知道如何管理它的情况下,一切都可以正常工作

这是我的密码:

public class Sliders extends JFrame {

private JPanel contentPane;
JLabel label,label_1;
static RainDrop frame;
 javax.swing.Timer  in,out;
/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                frame = new RainDrop();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public Sliders() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    label = new JLabel("");
    label.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseEntered(MouseEvent a1) {
            setIN(2,0,label);
                System.out.println("ENTRATO");
                checkloop_out_mag(-270,label);

        }
        @Override
        public void mouseExited(MouseEvent a2) {
            in.stop();
            setOUT(-2,0,label);
            System.out.println("USCITO");                       
        }
    });
    label.setBackground(Color.ORANGE);
    label.setOpaque(true);
    label.setBounds(-270, 0, 337, 44);
    contentPane.add(label);

    label_1 = new JLabel("");
    label_1.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseEntered(MouseEvent b1) {
                setIN(2,44,label_1);
                System.out.println("ENTRATO");
                checkloop_out_mag(-270,label_1);
        }
        @Override
        public void mouseExited(MouseEvent b2) {
            in.stop();
            setOUT(-2,44,label_1);
            System.out.println("USCITO");                   
        }
    });
    label_1.setOpaque(true);
    label_1.setBackground(Color.GREEN);
    label_1.setBounds(-270, 44, 337, 44);
    contentPane.add(label_1);
}



public void setIN(int x,int y,JLabel label) {


    in = new javax.swing.Timer(2, new ActionListener() {


                @Override
                public void actionPerformed(ActionEvent e) {



                     label.setLocation(label.getBounds().x+x,y);

                     System.out.println("SPOSTO");

                     System.out.println("CONTROLLO");
                     checkloop_in_magequals(0,label); 

                }
            });
            in.setRepeats(true);
            in.start();



}

public void setOUT(int x,int y,JLabel label) {


    out = new javax.swing.Timer(2, new ActionListener() {


                @Override
                public void actionPerformed(ActionEvent e) {



                     label.setLocation(label.getBounds().x+x,y);

                     System.out.println("SPOSTO");

                     System.out.println("CONTROLLO");
                       checkloop_out_equals(-270,label);


                }
            });
            out.setRepeats(true);
            out.start();



}

public void checkloop_out_equals(int z,JLabel label) {
     if (label.getBounds().x==z){
            out.stop();
            System.out.println("STOP");
     }
}

public void checkloop_out_mag(int z,JLabel label) {
     if (label.getBounds().x>z){
            out.stop();
            System.out.println("STOP");
     }
}


public void checkloop_in_magequals(int z,JLabel label) {
 if (label.getBounds().x>=z){
        in.stop();
        System.out.println("STOP");
     }
 }
}

有没有办法只用两个定时器来修复代码?或者每个JComponent都需要两个计时器吗?

首先,使用动画框架,比如或,它们提供了大量功能,否则需要大量的编码才能完成

动画是一门复杂的学科,所以我只讲一些基本的知识。动画是随着时间变化的幻觉(告诉你它将是基本的)

你的问题归结为两个基本问题:

  • 你需要一个中央“时钟”,它可以提供“滴答声”和(相对)有规律的间隔
  • 一个足够不可知、足够解耦的API,它不关心动画的“内容”,只关心给定的持续时间和范围,它可以计算每个“勾号”上所需的属性
  • 一个重要的概念是,动画应该在一段时间内播放,而不是在值之间播放。其主要原因是灵活性。为了改变速度而改变动画的持续时间要容易得多,它允许系统相对简单地“删除”帧。还记得我说过“动画是随时间变化的幻觉”——这就是我所说的

    简单的

    让我们从一些基础开始

    public class Range<T> {
        private T from;
        private T to;
    
        public Range(T from, T to) {
            this.from = from;
            this.to = to;
        }
    
        public T getFrom() {
            return from;
        }
    
        public T getTo() {
            return to;
        }
    
        @Override
        public String toString() {
            return "From " + getFrom() + " to " + getTo();
        }
        
    }
    
    “动画特性”是我们努力实现的潜在力量。它负责计算动画想要运行的时间量、动画已经运行的时间量,并提供一种方法来计算指定动画的结果值
    范围
    值。(注意,
    calculateValue
    可能是
    范围的属性,但我只是把它放在原处)

    好的,这很好,但是我们实际上需要一个中央时钟来提供所有的信号并通知属性

    public enum Animator {
    
        INSTANCE;
    
        private Timer timer;
    
        private List<AnimationProperties> properies;
    
        private Animator() {
            properies = new ArrayList<>(5);
            timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    Iterator<AnimationProperties> it = properies.iterator();
                    while (it.hasNext()) {
                        AnimationProperties ap = it.next();
                        if (ap.tick()) {
                            it.remove();
                        }
                    }
                    if (properies.isEmpty()) {
                        timer.stop();
                    }
                }
            });
        }
    
        public void add(AnimationProperties ap) {
            properies.add(ap);
            timer.start();
        }
    
        public void remove(AnimationProperties ap) {
            properies.remove(ap);
            if (properies.isEmpty()) {
                timer.stop();
            }
        }
    
    }
    
    这里真正需要注意的是,
    IntAnimationProperties
    还需要一个“最大范围”值。这是动画预期运行的总可用范围。这用于计算“动画范围”所在的当前“进度”值

    考虑一下当用户退出时,如果一个面板半展开会发生什么情况?通常情况下,它必须使用整个持续时间来设置该半范围的动画

    相反,此实现计算移动到所需点所需的“剩余”持续时间,在上面的示例中,这是正常持续时间的一半

    例子。。。 因此,基于以上,我们可以得到类似于

    导入java.awt.Color;
    导入java.awt.Dimension;
    导入java.awt.EventQueue;
    导入java.awt.event.ActionEvent;
    导入java.awt.event.ActionListener;
    导入java.awt.event.MouseAdapter;
    导入java.awt.event.MouseEvent;
    导入java.time.Duration;
    导入java.time.LocalDateTime;
    导入java.util.ArrayList;
    导入java.util.Iterator;
    导入java.util.List;
    导入javax.swing.JFrame;
    导入javax.swing.JPanel;
    导入javax.swing.Timer;
    导入javax.swing.UIManager;
    导入javax.swing.UnsupportedLookAndFeelException;
    公开课考试{
    公共静态void main(字符串[]args){
    新测试();
    }
    公开考试(){
    invokeLater(新的Runnable(){
    @凌驾
    公开募捐{
    试一试{
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    }catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
    例如printStackTrace();
    }
    JFrame=新JFrame(“测试”);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(newtestpane());
    frame.pack();
    frame.setLocationRelativeTo(空);
    frame.setVisible(true);
    }
    });
    }
    公共类TestPane扩展了JPanel{
    公共测试窗格(){
    setLayout(空);
    滑块滑块1=新滑块();
    幻灯片1.背景(颜色:蓝色);
    滑块1.设置位置(0,44);
    添加(滑块1);
    滑块滑块2=新滑块();
    幻灯片2.背景(颜色为洋红色);
    滑块2.设置位置(0,88);
    添加(滑块2);
    }
    @凌驾
    公共维度getPreferredSize(){
    返回新维度(200200);
    }
    }
    公共类滑块扩展了JPanel{
    私有动画属性ap;
    私有内部网maxRange=新内部网(44150);
    专用持续时间=秒的持续时间(5);
    公共滑块(){
    设置大小(44,44);
    addMouseListener(新的MouseAdapter(){
    @凌驾
    公共无效鼠标事件(鼠标事件e){
    animateTo(150);
    }
    @凌驾
    公共无效mouseExited(MouseEvent e){
    animateTo(44);
    }
    公共无效动画到(int到){
    如果(ap!=null){
    Animator.INSTANCE.remove(ap);
    }
    IntRange animationRange=新的IntRange(getWidth(),to);
    ap=新的IntAnimationProperties(animationRange、maxRange、duration、new AnimationPropertiesListener(){
    @凌驾
    公共无效状态已更改(AnimationProperties animator){
    s
    
    public enum Animator {
    
        INSTANCE;
    
        private Timer timer;
    
        private List<AnimationProperties> properies;
    
        private Animator() {
            properies = new ArrayList<>(5);
            timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    Iterator<AnimationProperties> it = properies.iterator();
                    while (it.hasNext()) {
                        AnimationProperties ap = it.next();
                        if (ap.tick()) {
                            it.remove();
                        }
                    }
                    if (properies.isEmpty()) {
                        timer.stop();
                    }
                }
            });
        }
    
        public void add(AnimationProperties ap) {
            properies.add(ap);
            timer.start();
        }
    
        public void remove(AnimationProperties ap) {
            properies.remove(ap);
            if (properies.isEmpty()) {
                timer.stop();
            }
        }
    
    }
    
    public class IntRange extends Range<Integer> {
        
        public IntRange(Integer from, Integer to) {
            super(from, to);
        }
        
        public Integer getDistance() {
            return getTo() - getFrom();
        }
    }
    
    public class IntAnimationProperties extends AbstractAnimationProperties<Integer> {
    
        public IntAnimationProperties(IntRange animationRange, IntRange maxRange, Duration duration, AnimationPropertiesListener<Integer> listener) {
            super(animationRange, listener);
            
            int maxDistance = maxRange.getDistance();
            int aniDistance = animationRange.getDistance();
    
            double progress = Math.min(100, Math.max(0, Math.abs(aniDistance/ (double)maxDistance)));
            Duration remainingDuration = Duration.ofMillis((long)(duration.toMillis() * progress));
            setDuration(remainingDuration);
        }
    
        @Override
        public Integer calculateValue(double progress) {
            IntRange range = (IntRange)getRange();
            int distance = range.getDistance();
            int value = (int) Math.round((double) distance * progress);
            value += range.getFrom();
            return value;
        }
    
    }
    
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.time.Duration;
    import java.time.LocalDateTime;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            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 TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() {
                setLayout(null);
                Slider slider1 = new Slider();
                slider1.setBackground(Color.BLUE);
                slider1.setLocation(0, 44);         
                add(slider1);
    
                Slider slider2 = new Slider();
                slider2.setBackground(Color.MAGENTA);
                slider2.setLocation(0, 88);
                add(slider2);
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
        }
    
        public class Slider extends JPanel {
    
            private AnimationProperties<Integer> ap;
    
            private IntRange maxRange = new IntRange(44, 150);
            private Duration duration = Duration.ofSeconds(5);
    
            public Slider() {
                setSize(44, 44);
    
                addMouseListener(new MouseAdapter() {
                    @Override
                    public void mouseEntered(MouseEvent e) {
                        animateTo(150);
                    }
    
                    @Override
                    public void mouseExited(MouseEvent e) {
                        animateTo(44);
                    }
    
                    public void animateTo(int to) {
                        if (ap != null) {
                            Animator.INSTANCE.remove(ap);
                        }
                        IntRange animationRange = new IntRange(getWidth(), to);
                        ap = new IntAnimationProperties(animationRange, maxRange, duration, new AnimationPropertiesListener<Integer>() {
                            @Override
                            public void stateChanged(AnimationProperties<Integer> animator) {
                                setSize(animator.getValue(), 44);
                                repaint();
                            }
                        });
                        Animator.INSTANCE.add(ap);
                    }
    
                });
            }
    
        }
    
        public enum Animator {
    
            INSTANCE;
    
            private Timer timer;
    
            private List<AnimationProperties> properies;
    
            private Animator() {
                properies = new ArrayList<>(5);
                timer = new Timer(5, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        Iterator<AnimationProperties> it = properies.iterator();
                        while (it.hasNext()) {
                            AnimationProperties ap = it.next();
                            if (ap.tick()) {
                                it.remove();
                            }
                        }
                        if (properies.isEmpty()) {
                            timer.stop();
                        }
                    }
                });
            }
    
            public void add(AnimationProperties ap) {
                properies.add(ap);
                timer.start();
            }
    
            public void remove(AnimationProperties ap) {
                properies.remove(ap);
                if (properies.isEmpty()) {
                    timer.stop();
                }
            }
    
        }
    
        public interface AnimationProperties<T> {
            public Range<T> getRange();
            public T getValue();
            public boolean tick();
    
            public void setDuration(Duration duration);
            public Duration getDuration();
        }
    
        public interface AnimationPropertiesListener<T> {
            public void stateChanged(AnimationProperties<T> animator);
        }
    
        public class Range<T> {
            private T from;
            private T to;
    
            public Range(T from, T to) {
                this.from = from;
                this.to = to;
            }
    
            public T getFrom() {
                return from;
            }
    
            public T getTo() {
                return to;
            }
    
            @Override
            public String toString() {
                return "From " + getFrom() + " to " + getTo();
            }
    
        }
    
        public abstract class AbstractAnimationProperties<T> implements AnimationProperties<T> {
    
            private Range<T> range;
    
            private LocalDateTime startTime;
    
            private Duration duration = Duration.ofSeconds(5);
    
            private T value;
    
            private AnimationPropertiesListener<T> listener;
    
            public AbstractAnimationProperties(Range<T> range, AnimationPropertiesListener<T> listener) {
                this.range = range;
                this.value = range.getFrom();
    
                this.listener = listener;
            }
    
            public void setDuration(Duration duration) {
                this.duration = duration;
            }
    
            public Duration getDuration() {
                return duration;
            }
    
            public Range<T> getRange() {
                return range;
            }
    
            @Override
            public T getValue() {
                return value;
            }
    
            @Override
            public boolean tick() {
                if (startTime == null) {
                    startTime = LocalDateTime.now();
                }
                Duration duration = getDuration();
                Duration runningTime = Duration.between(startTime, LocalDateTime.now());
                Duration timeRemaining = duration.minus(runningTime);
                if (timeRemaining.isNegative()) {
                    runningTime = duration;
                }
                double progress = (runningTime.toMillis() / (double) duration.toMillis());
                value = calculateValue(progress);
    
                listener.stateChanged(this);
    
                return progress >= 1.0;
            }
    
            public abstract T calculateValue(double progress);
    
        }
    
        public class IntRange extends Range<Integer> {
    
            public IntRange(Integer from, Integer to) {
                super(from, to);
            }
    
            public Integer getDistance() {
                return getTo() - getFrom();
            }
        }
    
        public class IntAnimationProperties extends AbstractAnimationProperties<Integer> {
    
            public IntAnimationProperties(IntRange animationRange, IntRange maxRange, Duration duration, AnimationPropertiesListener<Integer> listener) {
                super(animationRange, listener);
    
                int maxDistance = maxRange.getDistance();
                int aniDistance = animationRange.getDistance();
    
                double progress = Math.min(100, Math.max(0, Math.abs(aniDistance/ (double)maxDistance)));
                Duration remainingDuration = Duration.ofMillis((long)(duration.toMillis() * progress));
                setDuration(remainingDuration);
            }
    
            @Override
            public Integer calculateValue(double progress) {
                IntRange range = (IntRange)getRange();
                int distance = range.getDistance();
                int value = (int) Math.round((double) distance * progress);
                value += range.getFrom();
                return value;
            }
    
        }
    
    }