简体   繁体   English

启动画面进度条未绘制

[英]Splash Screen Progress bar not drawing

I'm trying to make my own progress bar, on my splash screen. 我正在尝试在我的初始屏幕上制作自己的进度栏。 Creating my splash screen was easy: 创建我的启动画面很容易:

java -splash:EaseMailMain.jpg Main.class (From Eclipse) java -splash:EaseMailMain.jpg Main.class(来自Eclipse)

The first line of my main method calls this: 我的main方法的第一行称为:

new Thread(new Splash()).start();

And this is the splash class: 这是飞溅类:

    public class Splash implements Runnable {
    public volatile static int percent = 0;
    @Override
    public void run() {
        System.out.println("Start");
        final SplashScreen splash = SplashScreen.getSplashScreen();
        if (splash == null) {
            System.out.println("SplashScreen.getSplashScreen() returned null");
            return;
        }
        Graphics2D g = splash.createGraphics();
        if (g == null) {
            System.out.println("g is null");
            return;
        }
        int height = splash.getSize().height;
        int width = splash.getSize().width;
        //g.drawOval(0, 0, 100, 100);
        g.setColor(Color.white);
        g.drawRect(0, height-50, width, 50);
        g.setColor(Color.BLACK);
        while(percent <= 100) {
            System.out.println((width*percent)/100);
            g.drawRect(0, height-50, (int)((width*percent)/100), 50);
            percent += 1;
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

I don't get any errors, but I do get a small box underneath it: 我没有任何错误,但是在它下面确实有一个小盒子:

下方带有矩形的图像。

If I change the drawRects to (0, 0, width, height) it makes no difference. 如果将drawRects更改为(0,0,width,height),则没有区别。

I've tried invoking on the swing EDT with: 我尝试使用以下方法调用Swing EDT:

SwingUtilities.invokeAndWait((new Splash()));

But nothing happens. 但是什么也没发生。

Can anyone see the problem? 谁能看到这个问题? Or know how to fix it? 还是知道如何解决?

You should use SwingUtilities.invokeLater or SwingUtilities.invokeAndWait when updating the GUI from a different thread. 从其他线程更新GUI时,应使用SwingUtilities.invokeLaterSwingUtilities.invokeAndWait

Please see the Chapter Concurrency in Swing which explains the reasons behind this. 请参阅Swing中的并发性章节其中解释了其背后的原因。

The SplashScreen Example from the Tutorial does the Thread.sleep inside the Swing thread. 教程中的SplashScreen示例在Swing线程内执行Thread.sleep This is fine, too if you do not need any other GUI refresh while the SplashScreen is showing. 如果在显示SplashScreen时不需要其他GUI刷新,也可以。 Your loading code however should happen in a different thread. 但是,您的加载代码应在其他线程中发生。

I would recommend adding a setPercent setter to your class which creates a Runnable to update the GUI via SwingUtilities.invokeLater . 我建议将setPercent setter添加到您的类中,该setPercent setter创建一个Runnable以通过SwingUtilities.invokeLater更新GUI。 That way you do not even need to poll the percent variable and the SwingThread is free to render other UI stuff, too. 这样,您甚至不需要轮询percent变量,并且SwingThread也可以自由呈现其他UI内容。

Bikeshedder is right (+1), you're blocking the EDT. Bikeshedder是对的(+1),您正在阻止EDT。

while(percent <= 100) {
    System.out.println((width*percent)/100);
    g.drawRect(0, height-50, (int)((width*percent)/100), 50);
    percent += 1;
    try {
        Thread.sleep(50);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

Using SwingUtilities.invokeAndWait((new Splash())); 使用SwingUtilities.invokeAndWait((new Splash())); is placing the Runnable onto the Event Queue, meaning when you enter your while loop and Thread.sleep , you're preventing the Event Queue from dispatching any new events, including repaint requests Runnable放到事件队列中,这意味着当您输入while循环和Thread.sleep ,您将阻止事件队列调度任何新事件,包括重画请求

You should be using something like a SwingWorker to perform your actually loading (in a background thread), publishing the progress results, which the splash screen can the display.... 您应该使用诸如SwingWorker类的东西来执行您的实际加载(在后台线程中),发布进度结果,并在初始屏幕上显示该结果。

在此处输入图片说明

public class TestSplashScreen {

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

    public TestSplashScreen() {
        SplashScreenWorker worker = new SplashScreenWorker();
        worker.execute();
        try {
            worker.get();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        System.out.println("All Done...");
//        Launch main application...
//        SwingUtilities.invokeLater(...);
    }

    public class SplashScreenWorker extends SwingWorker<Void, Float> {

        private SplashScreen splash;

        public SplashScreenWorker() {
            splash = SplashScreen.getSplashScreen();
            if (splash == null) {
                System.out.println("SplashScreen.getSplashScreen() returned null");
                return;
            }
        }

        @Override
        protected void process(List<Float> chunks) {
            Graphics2D g = splash.createGraphics();
            if (g == null) {
                System.out.println("g is null");
                return;
            }
            float progress = chunks.get(chunks.size() - 1);
            int height = splash.getSize().height;
            int width = splash.getSize().width;
            g.setComposite(AlphaComposite.Clear);
            g.fillRect(0, 0, width, height);
            g.setPaintMode();
            g.setColor(Color.WHITE);
            g.drawRect(0, height - 50, width, 50);
            g.setColor(Color.RED);
            int y = height - 50;
            g.fillRect(0, y, (int) (width * progress), 50);
            FontMetrics fm = g.getFontMetrics();
            String text = "Loading Microsoft Windows..." + NumberFormat.getPercentInstance().format(progress);
            g.setColor(Color.WHITE);
            g.drawString(text, (width - fm.stringWidth(text)) / 2, y + ((50 - fm.getHeight()) / 2) + fm.getAscent());
            g.dispose();
            splash.update();
        }

        @Override
        protected Void doInBackground() throws Exception {
            for (int value = 0; value < 1000; value++) {

                float progress = value / 1000f;
                publish(progress);
                Thread.sleep(25);

            }
            return null;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM