4

I know that I can fade in a panel, by adding the alpha value to the background color & a timer. But how can I fade in a panel with child components (like a JLabel)?

EDIT

_fadeTimer = new Timer(40, new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            if (_alpha == 255) {
                _fadeTimer.stop();
            } else {
                pnl_hint.setBackground(new Color(
                        bgColor.getRed(),
                        bgColor.getGreen(),
                        bgColor.getBlue(),
                        (_alpha += 1)));

                pnl_hint.updateUI();
            }
        }
    });
    _fadeTimer.start();
Christian 'fuzi' Orgler
  • 1,682
  • 8
  • 27
  • 51

4 Answers4

8

Another option would be to capture a screenshot of your panel and then let it paint itself with an increasing alpha composite.

Here is a small demo of that (although I am not sure this is really clean):

import java.awt.AlphaComposite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class TestFading {

    private static class FadingPanel extends JPanel {
        private BufferedImage buffer;
        private boolean isFading = false;
        private long start;
        private float alpha = 1.0f;

        @Override
        public void paint(Graphics g) {
            if (isFading) {// During fading, we prevent child components from being painted
                g.clearRect(0, 0, getWidth(), getHeight());
                ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
                g.drawImage(buffer, 0, 0, this);// We only draw an image of them with an alpha
            } else {
                super.paint(g);
            }
        }

        public void fade(int time) {
            start = System.currentTimeMillis();
            buffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
            this.print(buffer.getGraphics());// Draw the current components on the buffer
            isFading = true;
            final int timeInMillis = time * 1000;
            final Timer t = new Timer(50, null);
            t.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    long elapsed = System.currentTimeMillis() - start;
                    if (elapsed > timeInMillis) {
                        start = 0;
                        isFading = false;
                        buffer = null;
                        repaint();
                        t.stop();
                    } else {
                        alpha = 1.0f - (float) elapsed / timeInMillis;
                        repaint();
                    }
                }
            });
            t.start();
        }
    }

    protected void initUI() throws MalformedURLException {
        JFrame frame = new JFrame(TestFading.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final FadingPanel panel = new FadingPanel();
        JTextField textfield = new JTextField(60);
        JLabel image = new JLabel(new ImageIcon(new URL("http://helios.gsfc.nasa.gov/image_mag_stamp.jpg")));
        JButton button = new JButton("Fade");
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // I use an invoke later to allow the button to release itself
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        panel.fade(5);// Fade the panel in 5s.
                    }
                });
            }
        });
        panel.add(textfield);
        panel.add(image);
        panel.add(button);
        frame.add(panel);
        frame.setSize(400, 300);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    new TestFading().initUI();
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                }
            }
        });
    }

}
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • My JPanel was no opaque and had a cyan background color, but when I invoked `fade` it became opaque again and lost it's background color. Finally, when `face` finished the panel restored itself. – Cardinal System Nov 24 '17 at 22:16
3

Untested pseudo-code.

public void fade(Container c) {
    Component[] children = c.getComponents();
    for (Component component : components)  {
        // do fade thing with component
        if (component instanceOf Container) {
            fade( (Container)component );
        }
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • yea it's logic to use a recursive method... but i have a jlabel in my panel with an ImageIcon... and I cannot make them transparent like panel.setBackground(new Color(red, green, blue, alpha); – Christian 'fuzi' Orgler Sep 21 '12 at 08:41
  • 1
    Good call on the dribbling out of data. Is this a '10 part' question where we get the clues in installments? For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Sep 21 '12 at 08:58
  • I did not suggest a snippet or 'example code' but an SSCCE, like posted by Guillaume. An SSCCE is compilable and runs. – Andrew Thompson Sep 21 '12 at 10:18
  • 1
    @Christian'fuzi'Orgler: Please post a _complete_ example, such as this [one](http://stackoverflow.com/a/2234020/230513). – trashgod Sep 21 '12 at 10:19
3

Instead of setting background override paintChildren method. Call super.paintChildren() and then fill component's rect with semi transparent color.

StanislavL
  • 56,971
  • 9
  • 68
  • 98
0

I added a JLabel with an image and set the JPanel opaque to false!

In the overriden paintComponent method i set the AlphaComposite with my alpha before the super.paintComponent() call.

How do I fade an image in swing?

Community
  • 1
  • 1
Christian 'fuzi' Orgler
  • 1,682
  • 8
  • 27
  • 51