Animaciones al usar Gridbag Layout.

Recientemente inicié Java y me pregunté si era posible hacer animaciones mientras usaba GridBag Layout.

¿Son estos posibles y cómo? Cualquier tutorial, ayuda y tal sería muy apreciado 🙂

Para realizar cualquier tipo de animación de esta naturaleza, necesitarás algún tipo de administrador de diseño proxy.

Necesita determinar la posición actual de todos los componentes, la posición que el administrador de disposición desea que tengan y luego moverlos a su posición.

El siguiente ejemplo demuestra la idea básica. El uso del motor de animación es MUY básico y no incluye características como los fundamentos de entrada y salida lentas, pero utiliza un enfoque lineal.

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

Actualizar

También puedes echar un vistazo a AurelianRibbon / Sliding-Layout

Este es el progtwig que hice hace mucho tiempo cuando recién comencé mis clases de Java Hice animaciones simples en diferentes tabs en JTabbedPane (cambie la ruta de las imágenes / archivo de sonido según sea necesario), espero que esto ayude:

ACTUALIZAR:

Perdón por no seguir la concurrencia en Swing.

Aquí hay una respuesta actualizada:

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