java – 将JLabel移动到其他JLabel – GUI
发布时间:2020-12-15 07:36:30 所属栏目:Java 来源:网络整理
导读:我正试图让JLabel移动到其他JLabel,现在只有1个计时器工作.它应该像火车穿过轨道一样运行,一直绕着轨道行进,最后一直向后从它开始.我不知道如何让它一路走来,任何帮助都表示赞赏. 谢谢. import java.awt.BorderLayout;import java.awt.Dimension;import java
我正试图让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); testPane.add(textField_1); textField_2 = new JTextField(); textField_2.setColumns(10); textField_2.setBounds(120,20); testPane.add(textField_2); textField_3 = new JTextField(); textField_3.setColumns(10); textField_3.setBounds(160,20); testPane.add(textField_3); textField_5 = new JTextField(); textField_5.setColumns(10); textField_5.setBounds(140,20); testPane.add(textField_5); textField_6 = new JTextField(); textField_6.setColumns(10); textField_6.setBounds(160,20); testPane.add(textField_6); textField_7 = new JTextField(); textField_7.setColumns(10); textField_7.setBounds(120,20); testPane.add(textField_7); textField_8 = new JTextField(); textField_8.setColumns(10); textField_8.setBounds(80,59,20); testPane.add(textField_8); textField_9 = new JTextField(); textField_9.setColumns(10); textField_9.setBounds(80,75,20); testPane.add(textField_9); textField_10 = new JTextField(); textField_10.setColumns(10); textField_10.setBounds(80,90,20); testPane.add(textField_10); textField_11 = new JTextField(); textField_11.setColumns(10); textField_11.setBounds(80,106,20); testPane.add(textField_11); textField_12 = new JTextField(); textField_12.setColumns(10); textField_12.setBounds(80,123,20); testPane.add(textField_12); textField_13 = new JTextField(); textField_13.setColumns(10); textField_13.setBounds(179,20); testPane.add(textField_13); textField_14 = new JTextField(); textField_14.setColumns(10); textField_14.setBounds(199,20); testPane.add(textField_14); textField_15 = new JTextField(); textField_15.setColumns(10); textField_15.setBounds(80,20); testPane.add(textField_15); textField_16 = new JTextField(); textField_16.setColumns(10); textField_16.setBounds(100,20); testPane.add(textField_16); textField_17 = new JTextField(); textField_17.setColumns(10); textField_17.setBounds(140,20); testPane.add(textField_17); textField_18 = new JTextField(); textField_18.setColumns(10); textField_18.setBounds(179,20); testPane.add(textField_18); textField_19 = new JTextField(); textField_19.setColumns(10); textField_19.setBounds(199,20); testPane.add(textField_19); textField_20 = new JTextField(); textField_20.setColumns(10); textField_20.setBounds(219,63,20); testPane.add(textField_20); textField_21 = new JTextField(); textField_21.setColumns(10); textField_21.setBounds(219,20); testPane.add(textField_21); textField_22 = new JTextField(); textField_22.setBackground(Color.WHITE); textField_22.setColumns(10); textField_22.setBounds(219,20); testPane.add(textField_22); textField_23 = new JTextField(); textField_23.setColumns(10); textField_23.setBounds(219,20); testPane.add(textField_23); textField_24 = new JTextField(); textField_24.setColumns(10); textField_24.setBounds(219,99,27); testPane.add(textField_24); textField_25 = new JTextField(); textField_25.setColumns(10); textField_25.setBounds(219,83,20); testPane.add(textField_25); textField_26 = new JTextField(); textField_26.setColumns(10); textField_26.setBounds(219,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动画的实现
因为你必须通过x / y位置移动对象,但是在同一时间段内向不同方向移动,这将成为一个非常复杂的问题…… 您可以尝试设置四个链接的计时器,它们在完成后触发下一个计时器,并且所有计时器都执行动画的不同部分…但坦率地说,这真的很快变得一团糟…… 更好的想法是使用时间线和关键帧的概念.这个想法是,在时间线(0-1)上,某些事件在规定的时间(关键帧)发生.然后时间线将在这些关键帧之间进行混合…… 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)); } for (int index = 0; index < 6; index++) { y += 20; tracks.add(createTrack(x,20)); } for (int index = 0; index < 6; index++) { x -= 20; tracks.add(createTrack(x,20)); } for (int index = 0; index < 6; index++) { y -= 20; tracks.add(createTrack(x,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,20 * 7)); timeline.add(0.75f,20 * 7)); timeline.add(1f,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,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,20)); timeline.add(0.1f,20)); timeline.add(0.5f,20 * 7)); timeline.add(0.6f,20 * 7)); timeline.add(1f,20)); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |