将JLabel移动到其他JLabel - GUI

时间:2014-11-12 23:19:35

标签: java swing jlabel

我正在尝试让JLabel移动到其他JLabel,现在只有1个计时器工作。它应该像火车穿过轨道一样运行,一直绕着轨道行进,最后一直向后从它开始。我不知道如何让它一路走来,任何帮助都表示赞赏。

谢谢。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.JTextField;

import java.awt.Color;

import javax.swing.JSlider;
import javax.swing.SwingConstants;
import javax.swing.border.BevelBorder;

public class MoveLabel {
    private JTextField textField;
    private JTextField tf;
    private JTextField textField_1;
    private JTextField textField_2;
    private JTextField textField_3;
    private JTextField textField_5;
    private JTextField textField_6;
    private JTextField textField_7;
    private JTextField textField_8;
    private JTextField textField_9;
    private JTextField textField_10;
    private JTextField textField_11;
    private JTextField textField_12;
    private JTextField textField_13;
    private JTextField textField_14;
    private JTextField textField_15;
    private JTextField textField_16;
    private JTextField textField_17;
    private JTextField textField_18;
    private JTextField textField_19;
    private JTextField textField_20;
    private JTextField textField_21;
    private JTextField textField_22;
    private JTextField textField_23;
    private JTextField textField_24;
    private JTextField textField_25;
    private JTextField textField_26;
    private JSlider slider;
    private JSlider slider_1;
    private JSlider slider_2;

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

    public MoveLabel() {
        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.getContentPane().setLayout(new BorderLayout());
                TestPane testPane = new TestPane();
                testPane.setBackground(Color.WHITE);
                frame.getContentPane().add(testPane);

                textField = new JTextField();
                textField.setBounds(100, 138, 20, 20);
                testPane.add(textField);
                textField.setColumns(10);


                textField_1 = new JTextField();
                textField_1.setColumns(10);
                textField_1.setBounds(80, 44, 20, 20);
                testPane.add(textField_1);

                textField_2 = new JTextField();
                textField_2.setColumns(10);
                textField_2.setBounds(120, 44, 20, 20);
                testPane.add(textField_2);

                textField_3 = new JTextField();
                textField_3.setColumns(10);
                textField_3.setBounds(160, 44, 20, 20);
                testPane.add(textField_3);

                textField_5 = new JTextField();
                textField_5.setColumns(10);
                textField_5.setBounds(140, 138, 20, 20);
                testPane.add(textField_5);

                textField_6 = new JTextField();
                textField_6.setColumns(10);
                textField_6.setBounds(160, 138, 20, 20);
                testPane.add(textField_6);

                textField_7 = new JTextField();
                textField_7.setColumns(10);
                textField_7.setBounds(120, 138, 20, 20);
                testPane.add(textField_7);

                textField_8 = new JTextField();
                textField_8.setColumns(10);
                textField_8.setBounds(80, 59, 20, 20);
                testPane.add(textField_8);

                textField_9 = new JTextField();
                textField_9.setColumns(10);
                textField_9.setBounds(80, 75, 20, 20);
                testPane.add(textField_9);

                textField_10 = new JTextField();
                textField_10.setColumns(10);
                textField_10.setBounds(80, 90, 20, 20);
                testPane.add(textField_10);

                textField_11 = new JTextField();
                textField_11.setColumns(10);
                textField_11.setBounds(80, 106, 20, 20);
                testPane.add(textField_11);

                textField_12 = new JTextField();
                textField_12.setColumns(10);
                textField_12.setBounds(80, 123, 20, 20);
                testPane.add(textField_12);

                textField_13 = new JTextField();
                textField_13.setColumns(10);
                textField_13.setBounds(179, 44, 20, 20);
                testPane.add(textField_13);

                textField_14 = new JTextField();
                textField_14.setColumns(10);
                textField_14.setBounds(199, 44, 20, 20);
                testPane.add(textField_14);

                textField_15 = new JTextField();
                textField_15.setColumns(10);
                textField_15.setBounds(80, 138, 20, 20);
                testPane.add(textField_15);

                textField_16 = new JTextField();
                textField_16.setColumns(10);
                textField_16.setBounds(100, 44, 20, 20);
                testPane.add(textField_16);

                textField_17 = new JTextField();
                textField_17.setColumns(10);
                textField_17.setBounds(140, 44, 20, 20);
                testPane.add(textField_17);

                textField_18 = new JTextField();
                textField_18.setColumns(10);
                textField_18.setBounds(179, 138, 20, 20);
                testPane.add(textField_18);

                textField_19 = new JTextField();
                textField_19.setColumns(10);
                textField_19.setBounds(199, 138, 20, 20);
                testPane.add(textField_19);

                textField_20 = new JTextField();
                textField_20.setColumns(10);
                textField_20.setBounds(219, 63, 20, 20);
                testPane.add(textField_20);

                textField_21 = new JTextField();
                textField_21.setColumns(10);
                textField_21.setBounds(219, 138, 20, 20);
                testPane.add(textField_21);

                textField_22 = new JTextField();
                textField_22.setBackground(Color.WHITE);
                textField_22.setColumns(10);
                textField_22.setBounds(219, 44, 20, 20);
                testPane.add(textField_22);

                textField_23 = new JTextField();
                textField_23.setColumns(10);
                textField_23.setBounds(219, 123, 20, 20);
                testPane.add(textField_23);

                textField_24 = new JTextField();
                textField_24.setColumns(10);
                textField_24.setBounds(219, 99, 20, 27);
                testPane.add(textField_24);

                textField_25 = new JTextField();
                textField_25.setColumns(10);
                textField_25.setBounds(219, 83, 20, 20);
                testPane.add(textField_25);

                textField_26 = new JTextField();
                textField_26.setColumns(10);
                textField_26.setBounds(219, 90, 20, 20);
                testPane.add(textField_26);

                slider_2 = new JSlider();
                slider_2.setMaximum(3);
                slider_2.setPaintTicks(true);
                slider_2.setSnapToTicks(true);
                slider_2.setOrientation(SwingConstants.VERTICAL);
                slider_2.setBounds(533, 260, 57, 229);
                testPane.add(slider_2);




                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class TestPane extends JPanel {

        protected static final int PLAY_TIME = 4000;

        private JLabel label;
        private JTextField tf;
        private int targetX;
        private int targetY;
        private int targetX2;
        private int targetY2;
        private long startTime;
        private long startTime2;
        private final int startX;
        private final int startY;
        private final int startX2;
        private final int startY2;



        public TestPane() {
            setLayout(null);
            tf = new JTextField("");
            tf.setSize(20,20);
            tf.setBackground(Color.red);
            add(tf);



            Dimension size = getPreferredSize();

            startX = 80;
            startY = 44;

          /*  targetX = (size.width - label.getSize().width) / 2;
            targetY = (size.height - label.getSize().height) / 2;
            */
            targetX = 140;
            targetY = 44;



            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    int x = tf.getX();
                    int y = tf.getY();
                    long duration = System.currentTimeMillis() - startTime;
                    float progress = (float)duration / (float)PLAY_TIME;
                    if (progress > 1f) {
                        progress = 1f;
                        ((Timer)(e.getSource())).stop();
                    }

                    x = startX + (int)Math.round((targetX - startX) * progress);
                    y = startY + (int)Math.round((targetY - startY) * progress);

                    tf.setLocation(x, y);

                }
            });
            startTime = System.currentTimeMillis();
            timer.start();
           /* try {
                Thread.sleep(10);
            }
            catch (InterruptedException ie) {
                ie.printStackTrace();
            }
            if (timer.isRunning() != true)
            {
            timer.stop();
            }*/

            startX2 = targetX;
            startY2 = targetY;

            tf.setLocation(startX,startY);

          /*  targetX = (size.width - label.getSize().width) / 2;
            targetY = (size.height - label.getSize().height) / 2;
            */
            targetX2 = 219;
            targetY2 = 44;


            Timer timer2 = new Timer(40, new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    int x2 = tf.getX();
                    int y2 = tf.getY();
                    long duration = System.currentTimeMillis() - startTime2;
                    float progress = (float)duration / (float)PLAY_TIME;
                    if (progress > 1f) 
                    {
                        progress = 1f;
                        ((Timer)(e.getSource())).stop();
                    }

                    x2 = startX2 + (int)Math.round((targetX2 - startX2) * progress);
                    y2 = startY2 + (int)Math.round((targetY2 - startY2) * progress);

                    tf.setLocation(x2, y2);
                    tf.getLocation();


                }
            });
            startTime2 = System.currentTimeMillis();


            if (timer.isRunning() == false)
            {
            //
            timer2.start();
            }
            else 
            {
                timer2.setDelay(10);
            }

        }   

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(600, 500);

    }

  }
}

1 个答案:

答案 0 :(得分:3)

nb:我不喜欢null布局,我不会宽恕null布局,我宁愿使用自定义绘画,但是那个'很多与这个问题无关的工作。此示例旨在关注TimelineKeyFrame动画的实现

因为您必须通过x / y位置移动对象,但是在同一时间段内向不同的方向移动,这将成为一个非常复杂的问题......

你可以尝试设置四个链式Timer,当它们完成时触发下一个Timer,并且它们都会动画的不同部分......但坦率地说,这就变成了一团糟快......

更好的想法是使用时间线和关键帧的概念。这个想法是,在时间线(0-1)上,某些事件在规定的时间(关键帧)发生。然后时间线将在这些关键帧之间进行混合......

enter image description here

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class MoveLabel {

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

    public MoveLabel() {
        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.getContentPane().setLayout(new BorderLayout());
                TestPane testPane = new TestPane();
                testPane.setBackground(Color.WHITE);
                frame.getContentPane().add(testPane);

                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class TestPane extends JPanel {

        private JTextField tf;
        private List<JTextField> tracks;

        protected static final int PLAY_TIME = 4000;

        private Timeline timeline;
        private long startTime;

        public TestPane() {
            setLayout(null);

            tracks = new ArrayList<JTextField>(20);

            int x = 20;
            int y = 20;

            for (int index = 0; index < 6; index++) {
                x += 20;
                tracks.add(createTrack(x, y, 20, 20));
            }
            for (int index = 0; index < 6; index++) {
                y += 20;
                tracks.add(createTrack(x, y, 20, 20));
            }
            for (int index = 0; index < 6; index++) {
                x -= 20;
                tracks.add(createTrack(x, y, 20, 20));
            }
            for (int index = 0; index < 6; index++) {
                y -= 20;
                tracks.add(createTrack(x, y, 20, 20));
            }

            for (JTextField track : tracks) {
                add(track);
            }

            tf = new JTextField("");
            tf.setSize(20, 20);
            tf.setBackground(Color.red);
            add(tf);
            setComponentZOrder(tf, 0);

            timeline = new Timeline();
            timeline.add(0, new Point(20, 20));
            timeline.add(0.25f, new Point(20 * 7, 20));
            timeline.add(0.5f, new Point(20 * 7, 20 * 7));
            timeline.add(0.75f, new Point(20, 20 * 7));
            timeline.add(1f, new Point(20, 20));

            Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    long duration = System.currentTimeMillis() - startTime;
                    float progress = (float) duration / (float) PLAY_TIME;
                    if (progress > 1f) {
                        startTime = System.currentTimeMillis();
                        progress = 0;
//                      ((Timer) (e.getSource())).stop();
                    }

                    Point p = timeline.getPointAt(progress);
                    tf.setLocation(p);

                }
            });
            startTime = System.currentTimeMillis();
            timer.start();

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(600, 500);

        }

        protected JTextField createTrack(int x, int y, int width, int height) {
            JTextField field = new JTextField();
            field.setBounds(x, y, width, height);
            field.setEditable(false);
            field.setFocusable(false);
            return field;
        }

    }

    public static class Timeline {

        private Map<Float, KeyFrame> mapEvents;

        public Timeline() {
            mapEvents = new TreeMap<>();
        }

        public void add(float progress, Point p) {
            mapEvents.put(progress, new KeyFrame(progress, p));
        }

        public Point getPointAt(float progress) {

            if (progress < 0) {
                progress = 0;
            } else if (progress > 1) {
                progress = 1;
            }

            KeyFrame[] keyFrames = getKeyFramesBetween(progress);

            float max = keyFrames[1].progress - keyFrames[0].progress;
            float value = progress - keyFrames[0].progress;
            float weight = value / max;

            return blend(keyFrames[0].getPoint(), keyFrames[1].getPoint(), 1f - weight);

        }

        public KeyFrame[] getKeyFramesBetween(float progress) {

            KeyFrame[] frames = new KeyFrame[2];
            int startAt = 0;
            Float[] keyFrames = mapEvents.keySet().toArray(new Float[mapEvents.size()]);
            while (startAt < keyFrames.length && keyFrames[startAt] <= progress) {
                startAt++;
            }

            if (startAt >= keyFrames.length) {
                startAt = keyFrames.length - 1;
            }

            frames[0] = mapEvents.get(keyFrames[startAt - 1]);
            frames[1] = mapEvents.get(keyFrames[startAt]);

            return frames;

        }

        protected  Point blend(Point start, Point end, float ratio) {
            Point blend = new Point();

            float ir = (float) 1.0 - ratio;

            blend.x = (int)(start.x * ratio + end.x * ir);
            blend.y = (int)(start.y * ratio + end.y * ir);

            return blend;
        }

        public class KeyFrame {

            private float progress;
            private Point point;

            public KeyFrame(float progress, Point point) {
                this.progress = progress;
                this.point = point;
            }

            public float getProgress() {
                return progress;
            }

            public Point getPoint() {
                return point;
            }

        }

    }
}

然后你可以做一些愚蠢的事情,比如改变部分之间的速度......

timeline = new Timeline();
timeline.add(0, new Point(20, 20));
timeline.add(0.1f, new Point(20 * 7, 20));
timeline.add(0.5f, new Point(20 * 7, 20 * 7));
timeline.add(0.6f, new Point(20, 20 * 7));
timeline.add(1f, new Point(20, 20));

enter image description here