Grey splash screen due to no repainting

graphics2d, image, java, splash-screen, swing

Solution

Use a `JLabel` instead. Painting on the frame directly is a bad idea.

See this, it works everytime:

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

/**
 * Simple splash screen, contains only the image.
 * 
 * @author m4tx3
 */
public class SplashScreen extends JFrame {

    /**
     * Constructor. Creates a window with splash screen, loads an image at the URL specified in imageURL, and finally displays this image.
     * 
     * @param imageURL
     *            URL to the image that you want to put on the splash screen.
     */
    public SplashScreen() {
        super("Splash screen");
    }

    public void createSplashScreen(final URL imageURL) {

        JLabel splashLabel = new JLabel(new ImageIcon(imageURL));
        add(splashLabel);
            setSize(splashLabel.getPreferredSize());
        setUndecorated(true);
        setLocationRelativeTo(null);
        setVisible(true);

        repaint();
    }

    /**
     * Closes the splash screen and frees the memory taken by the image.
     * 
     * Call this function when the loading is complete.
     */
    public void close() {
        setVisible(false);
        dispose();
    }

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

            @Override
            public void run() {
                try {
                    new SplashScreen().createSplashScreen(new URL(
                            "http://art.gnome.org/download/themes/splash_screens/1334/Splash-GnomeDarkSplashScreen.png"));
                } catch (MalformedURLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
    }
}

Problem

I'm making a splash screen for my application. It's just static BufferedImage drawn by Graphics2D, inside JFrame with no decorations. My problem is: the window sometimes isn't drawn properly, it means it doesn't always contain my image, it's sometimes just grey. I tried already creating splash screen in second thread, but it didn't help. I could call `splashScreen.repaint()` every line, but it's nonsense... Here's my code: ``` package SeriousSteve.MapEditor; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URL; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.JFrame; /** * Simple splash screen, contains only the image. * * @author m4tx3 */ public class SplashScreen extends JFrame { private BufferedImage image; /** * Constructor. Creates a window with splash screen, loads an image at the * URL specified in imageURL, and finally displays this image. * * @param imageURL URL to the image that you want to put on the splash * screen. */ public SplashScreen() { super("Splash screen"); } public void createSplashScreen(final URL imageURL) { try { image = ImageIO.read(imageURL); } catch (IOException ex) { Logger.getLogger(SplashScreen.class.getName()). log(Level.SEVERE, null, ex); } setUndecorated(true); setSize(image.getWidth(), image.getHeight()); setLocationRelativeTo(null); setVisible(true); createGraphics(); repaint(); } /** * Creates a graphics context and draws a splash screen. */ private void createGraphics() { Graphics2D g = (Graphics2D) getGraphics(); g.drawImage(image, 0, 0, null); } /** * Closes the splash screen and frees the memory taken by the image. * * Call this function when the loading is complete. */ public void close() { setVisible(false); image = null; dispose(); } } ``` And: ``` SplashScreen splashScreen = new SplashScreen(); splashScreen.createSplashScreen(getClass().getResource( "Img/splash.png")); ``` Btw., - I'm creating my own splash screen class, because I've got 2 apps (the game and map editor for it) in 1 jar... I want to show splash screen only in map editor, so I can't modify manifest file. Regards

Original source