设计一个闪屏(Java)

8

我想设计一个启动屏幕,可以显示当前的加载进度,并带有进度条,类似于NetBeans启动屏幕。

loading... modules, done!.... loading modules and so on 

在加载完成后,主应用程序会出现。
我已经阅读了许多关于创建启动画面的文章,但其中没有一篇提到如何在启动画面上显示不同后台任务的进度。
我该怎么做才能实现这个功能?
我可以在Java中编写其余部分的应用程序,使用JavaFX 2来制作启动画面吗?
解决了!
我终于成功了。 我的错误是我在任务线程中更新GUI内容,所以我的任务线程被阻塞并且无法执行GUI更新指令之后的下一个指令。现在我将更新GUI指令移到任务完成之后执行,它正在工作...... 感谢Jewelsea为我指明正确的方向。

我可以插一句话吗?不要这样做。我不知道有谁真的喜欢启动画面 - 当软件把它推到我的面前时,我很讨厌它,只需在后台加载并在准备好时显示窗口即可。可能只是我这样想。 - Gareth Latty
5
在我看来,启动画面在软件/应用程序需要一些时间进行加载时非常有用,例如建立数据库连接、获取数据等,这样用户就可以看到某些处理正在进行。 - Deepak
这肯定是桌面环境的问题吧?例如,KDE会在光标旁边显示弹跳的应用程序图标,以向用户反馈应用程序正在启动。当然,最好的选择是将其作为用户首选项 - 这样可以让每个人都满意。 - Gareth Latty
是的,我的应用程序(javafx+java)大约需要10秒钟才能加载... - Deepak
NetBeans是如何做到这一点的? - Deepak
6个回答

9

我之前为一个独立的JavaFX 2.0应用程序创建了一个启动页示例

我更新了示例,以演示通过进度条和启动页上的进度文本监视加载进度。

要使代码适应于监视应用程序的初始化进度,而不是将ProgressBar绑定到WebEngine的loadWorker.workDone属性,需要创建一个执行昂贵的初始化工作的JavaFX Task,并通过Task的progressPropertymessageProperty监视Task的进度。

这里有一个基于Task方法的启动页示例链接,该方法在前面的段落中进行了概述。

对于WebStart或嵌入浏览器的JavaFX应用程序,可以使用预加载器,正如assylias所建议的那样。


那么您的意思是说我必须为每个后台进程创建不同的任务,并在启动屏幕上显示这些任务的进度属性? - Deepak
嗨,jewelsea。你的启动画面示例非常好用。在商业应用中采用这段代码有什么限制吗?谢谢。 - ytw
使用闪屏示例没有任何限制。 - jewelsea
jewelsea - 使用您的示例,它运行良好,但我有一个工厂类,当从AnnotationConfigApplicationContext构造函数调用时,会加载一堆bean(数据库、消息等)。我希望能够从中获得一些反馈,因为大部分启动时间都在这个构造函数中。有什么想法吗? - kpenrose
@kpenrose 我不使用Spring,所以无法就该特定集成点提供建议。一般来说,如果您有一个长时间运行的启动任务,并且需要在闪屏页面上提供间歇性进度反馈,则可以使用我在答案中链接的任务篮闪屏页面。如果您有更多问题,请将其作为新问题而不是评论提出。 - jewelsea
显示剩余3条评论

4
如果您使用 进行部署,icon 元素 可以引用各种图片。下载期间,jnlp 客户端处理进度指示。优点是可以在用户体验的早期介入。
稍后,一个 SwingWorker 可以在后台加载图像,如 此处 所示。该工作者的 progress() 方法可以通过 PropertyChangeListener 驱动 JProgressBar,如 此处 所示。

3
使用预加载器来显示应用程序初始化的进度似乎是您要寻找的。

预加载器适用于WebStart和嵌入式浏览器应用程序,但是(截至JavaFX 2.0),不适用于独立应用程序。 - jewelsea
似乎对于JavaFX 2.1+,预加载程序也可以在独立应用程序的初始化中使用 - 但我还没有尝试过。 - jewelsea

3
请查看Swing闪屏教程,其中包含一个示例,在闪屏上更新进度条。您可以轻松地调整示例以更新一些文本。

1
除非你不能使用Swing/AWT组件,例如JProgressBar,因为它会使启动画面消失。您必须在SplashScreen.createGraphics()上绘制它... - Matthieu

0

你也可以使用Java创建启动画面,

但如果你想少写代码,做更多的事情,那就使用JavaFx启动画面组件吧。


我已经尝试过了,但我想要显示后台进程的进度。 - Deepak

0

为了完整性,如果您想显示进度条。引用SplashScreen javadoc

当 Swing/AWT 显示第一个窗口时,启动画面窗口会自动关闭。

这意味着它不能使用标准的 AWT/Swing 组件(例如 JProgressBar),但只能通过 Graphics2D 方法进行绘制(例如 drawText()fillRect() 等)。

因此,您需要在一个单独的类中模拟进度条(代码仅作为非常粗略的演示给出。您应该检查 SplashScreen.isVisible()):

public class SplashProgressBar {

    SplashScreen splash;
    Graphics2D g;
    int x, y, w, h; // Drawing position in splash screen

    int val, max; // Progress bar value
    String text; // Text to display

    public SplashProgressBar(SplashScreen splash, int x, int y, int w, int h) {
        this.splash = splash;
        g = splash.createGraphics();
        this.x = x;
        // this.y = y; etc
        this.val = 0;
        this.max = 100;
    }

    public void setMaximum(int n) {
        max = n;
        update();
    }

    public void setValue(int n) {
        val = n;
        update();
    }

    public void setString(String text) {
        this.text = text;
        update();
    }

    public void update() {
        g.setColor(Color.WHITE);
        g.fillRect(x, y, w, h);
        g.setColor(Color.DARK_GRAY);
        g.drawRect(x, y, w, h);
        g.setColor(Color.ORANGE);
        g.fill3DRect(x, y, w * val / max, h, true);
        if (text != null) {
            g.setColor(Color.BLACK);
            g.drawString(text, x + (w - g.getFontMetrics().stringWidth(text)) / 2.0f, y + 8 - 2); // Use TextLayout to get precise text dimensions...
        }
        splash.update();
    }
}

然后:

// Drawn a scroll bar at (10;100) x (300x15) on the splash screen image (we know its size and where it would fit)
SplashProgressBar spb = new SplashProgressBar(SplashScreen.getSplashScreen(), 10, 100, 300, 15);
spb.setMaximum(processing.size());
for (int i = 0; i < processing.size(); i++) {
    spb.setValue(i);
    spb.setString("Processing #"+(i+1));
    // Do the processing...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接