Q:

How to animate JLabel and not push other components

I'm trying to animate the JLabel, when i'm setting it visible true. And when my JLbael is showing up, other components are pushed down. Is there any way to keep jlabel in one position when visible and not visible? I'm using gridbaglayout.

A:

The visible state of a component will affect how most layout managers will treat the component, typically, they ignore them when they aren't visible.
You could write your own layout manager, but that's kind of annoying and time consuming.  You could use a "fake" component (adding the label inside it), but that's kind of messy and hard to keep the two components in sync or you could "fake" the visibility state...
Start by creating a custom component which extends from JLabel, override it's paintComponent and using a AlphaComposite change the transparency level of the content which is painted.  This way, you could animate the "alpha" level instead of the visibility level...

import java.awt.AlphaComposite;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private FadeLabel fadeLabel;
        private Timer timer;

        public TestPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            fadeLabel = new FadeLabel("Rabbit");
            fadeLabel.setAlpha(0f);

            add(new JLabel("Watch me pull a..."), gbc);
            add(fadeLabel, gbc);

            JButton btn = new JButton("out of my hat");
            add(btn, gbc);

            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (!timer.isRunning()) {
                        fadeLabel.setAlpha(0);
                        timer.start();
                    }
                }
            });

            timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    float alpha = fadeLabel.getAlpha();
                    alpha += 0.01;
                    if (alpha >= 1.0f) {
                        alpha = 1.0f;
                        timer.stop();
                    }
                    fadeLabel.setAlpha(alpha);
                }
            });

        }

    }

    public class FadeLabel extends JLabel {

        private float alpha = 1f;

        public FadeLabel(String text, Icon icon, int horizontalAlignment) {
            super(text, icon, horizontalAlignment);
        }

        public FadeLabel(String text, int horizontalAlignment) {
            super(text, horizontalAlignment);
        }

        public FadeLabel(String text) {
            super(text);
        }

        public FadeLabel(Icon image, int horizontalAlignment) {
            super(image, horizontalAlignment);
        }

        public FadeLabel(Icon image) {
            super(image);
        }

        public FadeLabel() {
        }

        public float getAlpha() {
            return alpha;
        }

        public void setAlpha(float value) {
            if (value != alpha) {
                float old = alpha;
                this.alpha = value;
                firePropertyChange("alpha", old, alpha);
                repaint();
            }
        }

        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setComposite(AlphaComposite.SrcOver.derive(alpha));
            super.paintComponent(g2d);
            g2d.dispose();
        }

    }
}

Now, you can just as easily set the alpha level from 0 to 1 and you will get the same instance change as you would if you changed the visibility state, but without the bumping of surrounding components

