使用Gridbag布局时的动画。

我最近开始使用Java,并想知道在使用GridBag Layout时是否可以制作动画。

这些可能吗?如何? 任何教程,帮助等都将非常感谢:)

为了执行这种性质的任何类型的动画,你将需要某种代理布局管理器。

它需要确定所有组件的当前位置,布局管理器希望它们具有的位置,然后将它们移动到位。

以下示例演示了基本概念。 动画引擎的使用是非常基本的,不包括慢进和慢进等基本function,但使用线性方法。

 public class TestAnimatedLayout { public static void main(String[] args) { new TestAnimatedLayout(); } public TestAnimatedLayout() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException ex) { } catch (InstantiationException ex) { } catch (IllegalAccessException ex) { } catch (UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new TestAnimatedLayoutPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestAnimatedLayoutPane extends JPanel { public TestAnimatedLayoutPane() { setLayout(new AnimatedLayout(new GridBagLayout())); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; add(new JLabel("Value:"), gbc); gbc.gridx++; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 1; add(new JComboBox(), gbc); gbc.gridx = 0; gbc.gridy++; gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 1; gbc.weighty = 1; gbc.gridwidth = 2; add(new JScrollPane(new JTextArea()), gbc); gbc.gridwidth = 0; gbc.gridy++; gbc.gridx++; gbc.weightx = 0; gbc.weighty = 0; gbc.fill = GridBagConstraints.NONE; gbc.anchor = GridBagConstraints.EAST; add(new JButton("Click"), gbc); } @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } } public class AnimatedLayout implements LayoutManager2 { private LayoutManager2 proxy; private Map mapStart; private Map mapTarget; private Map mapTrips; private Map mapAnimators; public AnimatedLayout(LayoutManager2 proxy) { this.proxy = proxy; mapTrips = new WeakHashMap<>(5); mapAnimators = new WeakHashMap<>(5); } @Override public void addLayoutComponent(String name, Component comp) { proxy.addLayoutComponent(name, comp); } @Override public void removeLayoutComponent(Component comp) { proxy.removeLayoutComponent(comp); } @Override public Dimension preferredLayoutSize(Container parent) { return proxy.preferredLayoutSize(parent); } @Override public Dimension minimumLayoutSize(Container parent) { return proxy.minimumLayoutSize(parent); } @Override public void layoutContainer(Container parent) { Timer timer = mapTrips.get(parent); if (timer == null) { System.out.println("...create new trip"); timer = new Timer(125, new TripAction(parent)); timer.setRepeats(false); timer.setCoalesce(false); mapTrips.put(parent, timer); } System.out.println("trip..."); timer.restart(); } protected void doLayout(Container parent) { System.out.println("doLayout..."); mapStart = new HashMap<>(parent.getComponentCount()); for (Component comp : parent.getComponents()) { mapStart.put(comp, (Rectangle) comp.getBounds().clone()); } proxy.layoutContainer(parent); LayoutConstraints constraints = new LayoutConstraints(); for (Component comp : parent.getComponents()) { Rectangle bounds = comp.getBounds(); Rectangle startBounds = mapStart.get(comp); if (!mapStart.get(comp).equals(bounds)) { comp.setBounds(startBounds); constraints.add(comp, startBounds, bounds); } } System.out.println("Items to layout " + constraints.size()); if (constraints.size() > 0) { Animator animator = mapAnimators.get(parent); if (animator == null) { animator = new Animator(parent, constraints); mapAnimators.put(parent, animator); } else { animator.setConstraints(constraints); } animator.restart(); } else { if (mapAnimators.containsKey(parent)) { Animator animator = mapAnimators.get(parent); animator.stop(); mapAnimators.remove(parent); } } } @Override public void addLayoutComponent(Component comp, Object constraints) { proxy.addLayoutComponent(comp, constraints); } @Override public Dimension maximumLayoutSize(Container target) { return proxy.maximumLayoutSize(target); } @Override public float getLayoutAlignmentX(Container target) { return proxy.getLayoutAlignmentX(target); } @Override public float getLayoutAlignmentY(Container target) { return proxy.getLayoutAlignmentY(target); } @Override public void invalidateLayout(Container target) { proxy.invalidateLayout(target); } protected class TripAction implements ActionListener { private Container container; public TripAction(Container container) { this.container = container; } @Override public void actionPerformed(ActionEvent e) { System.out.println("...trip"); mapTrips.remove(container); doLayout(container); } } } public class LayoutConstraints { private List animationBounds; public LayoutConstraints() { animationBounds = new ArrayList(25); } public void add(Component comp, Rectangle startBounds, Rectangle targetBounds) { add(new AnimationBounds(comp, startBounds, targetBounds)); } public void add(AnimationBounds bounds) { animationBounds.add(bounds); } public int size() { return animationBounds.size(); } public AnimationBounds[] getAnimationBounds() { return animationBounds.toArray(new AnimationBounds[animationBounds.size()]); } } public class AnimationBounds { private Component component; private Rectangle startBounds; private Rectangle targetBounds; public AnimationBounds(Component component, Rectangle startBounds, Rectangle targetBounds) { this.component = component; this.startBounds = startBounds; this.targetBounds = targetBounds; } public Rectangle getStartBounds() { return startBounds; } public Rectangle getTargetBounds() { return targetBounds; } public Component getComponent() { return component; } public Rectangle getBounds(float progress) { return calculateProgress(getStartBounds(), getTargetBounds(), progress); } } public static Rectangle calculateProgress(Rectangle startBounds, Rectangle targetBounds, float progress) { Rectangle bounds = new Rectangle(); if (startBounds != null && targetBounds != null) { bounds.setLocation(calculateProgress(startBounds.getLocation(), targetBounds.getLocation(), progress)); bounds.setSize(calculateProgress(startBounds.getSize(), targetBounds.getSize(), progress)); } return bounds; } public static Point calculateProgress(Point startPoint, Point targetPoint, float progress) { Point point = new Point(); if (startPoint != null && targetPoint != null) { point.x = calculateProgress(startPoint.x, targetPoint.x, progress); point.y = calculateProgress(startPoint.y, targetPoint.y, progress); } return point; } public static Dimension calculateProgress(Dimension startSize, Dimension targetSize, float progress) { Dimension size = new Dimension(); if (startSize != null && targetSize != null) { size.width = calculateProgress(startSize.width, targetSize.width, progress); size.height = calculateProgress(startSize.height, targetSize.height, progress); } return size; } public static int calculateProgress(int startValue, int endValue, float fraction) { int value = 0; int distance = endValue - startValue; value = (int) ((float) distance * fraction); value += startValue; return value; } public class Animator implements ActionListener { private Timer timer; private LayoutConstraints constraints; private int tick; private Container parent; public Animator(Container parent, LayoutConstraints constraints) { setConstraints(constraints); timer = new Timer(16, this); timer.setRepeats(true); timer.setCoalesce(true); this.parent = parent; } private void setConstraints(LayoutConstraints constraints) { this.constraints = constraints; } public void restart() { tick = 0; timer.restart(); } protected void stop() { timer.stop(); tick = 0; } @Override public void actionPerformed(ActionEvent e) { tick += 16; float progress = (float)tick / (float)1000; if (progress >= 1f) { progress = 1f; timer.stop(); } for (AnimationBounds ab : constraints.getAnimationBounds()) { Rectangle bounds = ab.getBounds(progress); Component comp = ab.getComponent(); comp.setBounds(bounds); comp.invalidate(); comp.repaint(); } parent.repaint(); } } } 

更新

你也可以看看AurelianRibbon / Sliding-Layout

这是我刚开始学习Java课程的时间很长的程序。我在JTabbedPane上的不同选项卡上做了简单的动画(根据需要更改图像/声音文件的路径),希望这会有所帮助:

更新:

很抱歉没有关注Swing中的并发性。

这是更新的答案:

  import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JApplet; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.SwingUtilities; import javax.swing.Timer; public class ClassTestHello extends JApplet { private static JPanel j1; private JLabel jl; private JPanel j2; private Timer timer; private int i=0; private int[] a=new int[10]; @Override public void init() { SwingUtilities.invokeLater(new Runnable() { public void run() { start(); paint(); } }); } public void paint() { jl=new JLabel("hiii"); j1.add(jl); a[0]=1000; a[1]=800; a[2]=900; a[3]=2000; a[4]=500; ActionListener actionListener = new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { if(i%2==0) jl.setText("hiii"); else jl.setText("byee"); i++; if(i>4) i=0; timer.setDelay(a[i]); } }; timer = new Timer(a[i], actionListener); timer.setInitialDelay(0); timer.start(); } @Override public void start() { j1=new JPanel(); j2=new JPanel(); JTabbedPane jt1=new JTabbedPane(); ImageIcon ic=new ImageIcon("e:/guitar.gif"); JLabel jLabel3=new JLabel(ic); j2.add(jLabel3); jt1.add("one",j1); jt1.addTab("hii",j2); getContentPane().add(jt1); } }