View Splashscreen with progress while Jframe is loaded

Asked

Viewed 504 times

2

I have an app made on , and I’m trying to add a SplashScreen in it. I managed to make the class SplashScreen work normally, but I’m not able to synchronize the loading of Jframe in invokeLater with the loading of splashScreen.

Follows the code of splashScreen that I’m wearing:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.SplashScreen;
import java.awt.geom.Rectangle2D;

public class GerOficioSplashScreen {

    private static SplashScreen mySplash;
    private static Graphics2D splashGraphics;
    private static Rectangle2D.Double splashProgressArea;

    public static void splashInit() {

        mySplash = SplashScreen.getSplashScreen();

        if (mySplash != null) {

            Dimension ssDim = mySplash.getSize();
            int height = ssDim.height;
            int width = ssDim.width;

            splashProgressArea = new Rectangle2D.Double(1., height * .87, width, height * 0.08);

            splashGraphics = mySplash.createGraphics();
            splashProgress(0);
        }
    }

    public static void splashProgress(int pct) {
        if (mySplash != null && mySplash.isVisible()) {

            splashGraphics.setPaint(Color.LIGHT_GRAY);
            splashGraphics.fill(splashProgressArea);

            splashGraphics.setPaint(Color.BLUE);
            splashGraphics.draw(splashProgressArea);

            int x = (int) splashProgressArea.getMinX();
            int y = (int) splashProgressArea.getMinY();
            int wid = (int) splashProgressArea.getWidth();
            int hgt = (int) splashProgressArea.getHeight();

            int doneWidth = Math.round(pct * wid / 100.f);
            doneWidth = Math.max(0, Math.min(doneWidth, wid - 1));

            splashGraphics.setPaint(Color.GREEN);
            splashGraphics.fillRect(x, y + 1, doneWidth, hgt - 1);

            mySplash.update();
        }
    }
}

His call on the main of my screen in JFrame is like this:

   public static void main(String args[]) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                GerOficioSplashScreen.splashInit();

                for (int i = 0; i < 10; i++) {
                    GerOficioSplashScreen.splashProgress(i * 20);
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        }).start();

        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {

                    Propriedade p = new Propriedade();
                    for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                        if ((p.getLookAndFeel()).equalsIgnoreCase(info.getName())) {
                            javax.swing.UIManager.put("control", new Color(230, 230, 230));
                            javax.swing.UIManager.put("background", new Color(0, 230, 230));
                            javax.swing.UIManager.put("Table.showGrid", true);
                            javax.swing.UIManager.put("Table.alternateRowColor", new Color(232, 232, 232));
                            javax.swing.UIManager.setLookAndFeel(info.getClassName());
                            break;
                        }
                    }

                    ListaDeOficiosUI_unificada a = new ListaDeOficiosUI_unificada();
                    a.setLocationRelativeTo(null);
                    a.setVisible(true);
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException | IOException ex) {
                    PrintMessageUI.exibirError(null, "Erro ao abrir o programa.\n" + ex.getMessage());
                    System.exit(0);
                }
            }
        });
    }

The problem is getting SplashScreen click as you render the screen on invokeLater, it closes before it finishes uploading the progress, and the screen of the JFrame opens.

How do I sync the rendering JFrame initiated in the invokeLater with the progress bar of splashScreen?

1 answer

0


As I did not find a way to properly synchronize the progress bar according to my loading JFrame within the (EDT), I ended up loading the SplashScreen in a Threadparallel to the EDT. I ran some tests to get the average time it takes for the application to load and adapted this time in the progress bar SplashScreen and the rest I based on documentation:

The splash screen window is closed Automatically as soon as the first window is displayed by Swing/AWT (may be also closed Manually using the Java API, see Below).

That is, so the JFrame is rendered and is visible, java itself closes the SplashScreen and then finalizes your Thread.

It was not the best solution, because the JFrame may appear even if the bar is not complete, but has met my problem punctually.

Question code not changed.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.