将JLabel移动到其他JLabel - GUI [英] Moving JLabel to other JLabels - GUI

查看:111
本文介绍了将JLabel移动到其他JLabel - GUI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to make a JLabel move across other JLabels, only 1 timer works right now. It is supposed to operate like a train moving across a track, going all the way around the track and ending up right back where it started from. I'm not sure how to make it go all the way around, any help is appreciated.

谢谢。

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);

    }

  }
}


推荐答案

nb:我不喜欢 null 布局,我不宽恕 null 布局,我更喜欢使用自定义绘画,但这是很多与问题无关的工作。此示例旨在专注于时间轴 KeyFrame 动画

nb: I don't like null layouts, I don't condone null layouts, I would prefer to have used custom painting, but that's a lot of work not related to the question. This example is intended to focus on the implementation of a Timeline and KeyFrame animation

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

Because you have to move the object through both the x/y positions, but in different directions over the same time period, this becomes a very complex problem...

您可以尝试设置四个链式计时器,这会触发下一个计时器当他们完成时,所有人都在做动画的不同部分......但坦率地说,这真的很快变得一团糟......

You could try and set up four, chained Timers, which trigger the next Timer when they complete, and which all do a different part of the animation...but frankly, that becomes a mess real quick...

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

A better idea is to use a concept of a time line and key frames. The idea is, that over the time line (0-1), certain events occur at prescribed times (key frames). The time line will then blend between these key frames...

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;
            }

        }

    }
}

然后,您可以做一些愚蠢的事情,例如改变各部门之间的速度......

You could then do silly things like vary the speed between sections...

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));

这篇关于将JLabel移动到其他JLabel - GUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆