制作类似Eclipse的带有进度条的启动画面

9

我的主类从文件中加载配置,然后显示一个框架。我想制作一个带有进度条的启动画面,就像Eclipse一样,当文件正在加载时进度会增加,加载完成后启动画面消失。然后我的主框架被加载。

MainClass代码:

public static void main(String[] args) {
  ApplicationContext context = new ClassPathXmlApplicationContext(
    "classpath:/META-INF/spring/applicationContext.xml");
  // splash with progress load till this file is loaded
  UserDao userDao = context.getBean(UserDao.class);
  isRegistered = userDao.isRegistered();
  System.out.println("registered: " + isRegistered);
  if (isRegistered) {
    // progress finish and hide splash
    log.debug("user is registered"); // show frame1
  } else {
    // progress finish and hide splash
    log.debug("user is not registered"); // show frame2
  }
}

我对Swing没有太多经验,请指导如何完成。

更新:我找到了下面的例子,但它有一些小问题:

  • when the counter gets to the specified number it should stop at (300) it keeps counting for ever without stopping the timer and hiding the splash screen.

  • i want to bind the counter to the file loading, so while the file is loaded the progress gets loaded until the file gets loaded then the progress completes and the splash screen disappears.

    @SuppressWarnings("serial")
    @Component
    public class SplashScreen extends JWindow {
    
        static boolean isRegistered;
    
        static Log log = LogFactory.getLog(SplashScreen.class);
    
        private static JProgressBar progressBar = new JProgressBar();
        private static SplashScreen execute;
        private static int count;
        private static Timer timer1;
    
        public SplashScreen() {
    
            Container container = getContentPane();
            container.setLayout(null);
    
            JPanel panel = new JPanel();
            panel.setBorder(new javax.swing.border.EtchedBorder());
            panel.setBackground(new Color(255, 255, 255));
            panel.setBounds(10, 10, 348, 150);
            panel.setLayout(null);
            container.add(panel);
    
            JLabel label = new JLabel("Hello World!");
            label.setFont(new Font("Verdana", Font.BOLD, 14));
            label.setBounds(85, 25, 280, 30);
            panel.add(label);
    
            progressBar.setMaximum(50);
            progressBar.setBounds(55, 180, 250, 15);
            container.add(progressBar);
            loadProgressBar();
            setSize(370, 215);
            setLocationRelativeTo(null);
            setVisible(true);
        }
    
        public void loadProgressBar() {
            ActionListener al = new ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    count++;
                    progressBar.setValue(count);
                    if (count == 300) {
                        timer1.stop();
                        execute.setVisible(false);
                        return;
                    }
                }
            };
            timer1 = new Timer(50, al);
            timer1.start();
        }
    
        public static void main(String[] args) {
    
            execute = new SplashScreen();
    
            ApplicationContext context = new ClassPathXmlApplicationContext(
                    "classpath:/META-INF/spring/applicationContext.xml");
    
            UserDao userDao = context.getBean(UserDao.class);
    
            isRegistered = userDao.isRegistered();
    
    
            if (isRegistered) {
                 // show frame 1
            } else {
                                                        // show frame 2
    
            }
    
        }
    
    }
    

1
你看过这个问题了吗?它有一些不错的链接。 - Rob I
2个回答

10

Java内置了SplashScreen类,专门用于此目的。有一个关于如何使用它的教程,在这里


谢谢你的提醒。在你提到它之前,我还没有注意到API中的SplashScreen类。 - Bobulous

9
当计数器达到指定的数字(300)时,它应该停止计数,并保持计时器运行,同时隐藏启动屏幕。以下代码似乎表现良好(致命缺陷是计数器可能需要比文件加载长,反之亦然):
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.HeadlessException;
import java.awt.event.ActionListener;
import javax.swing.*;

public class SplashScreen extends JWindow {

    static boolean isRegistered;
    private static JProgressBar progressBar = new JProgressBar();
    private static SplashScreen execute;
    private static int count;
    private static Timer timer1;

    public SplashScreen() {

        Container container = getContentPane();
        container.setLayout(null);

        JPanel panel = new JPanel();
        panel.setBorder(new javax.swing.border.EtchedBorder());
        panel.setBackground(new Color(255, 255, 255));
        panel.setBounds(10, 10, 348, 150);
        panel.setLayout(null);
        container.add(panel);

        JLabel label = new JLabel("Hello World!");
        label.setFont(new Font("Verdana", Font.BOLD, 14));
        label.setBounds(85, 25, 280, 30);
        panel.add(label);

        progressBar.setMaximum(50);
        progressBar.setBounds(55, 180, 250, 15);
        container.add(progressBar);
        loadProgressBar();
        setSize(370, 215);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private void loadProgressBar() {
        ActionListener al = new ActionListener() {

            public void actionPerformed(java.awt.event.ActionEvent evt) {
                count++;

                progressBar.setValue(count);

                System.out.println(count);

                if (count == 300) {

                    createFrame();

                    execute.setVisible(false);//swapped this around with timer1.stop()

                    timer1.stop();
                }

            }

            private void createFrame() throws HeadlessException {
                JFrame frame = new JFrame();
                frame.setSize(500, 500);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        };
        timer1 = new Timer(50, al);
        timer1.start();
    }

    public static void main(String[] args) {
        execute = new SplashScreen();
    }
};

我想将计数器绑定到文件加载上,因此在加载文件时进度条会随之加载,直到文件完全加载完成,进度条才会完成并消失闪屏。您应该查看使用TaskProgressMonitorProgressMonitorInputStream,然后检查文件何时被完全读取并结束SplashScreen的显示。在这里可以找到一些很好的教程和解释。

我该如何使进度条缓慢加载,因为它加载得非常快?我尝试增加计数,但它仍然加载得很快。 - Mahmoud Saleh
@Msaleh 如果您正在使用我提供的代码,请将 timer1 = new Timer(400, al); 的值更改为更大的值。在此示例中,计时器现在将每0.5秒调用一次。 - David Kroukamp
请问您能否解释一下 if (count == 300)timer1 = new Timer(50, al); 之间的区别以及它们各自的作用。 - Mahmoud Saleh
@Msaleh计时器调用方法来增加计数器,if语句检查计数器何时达到特定值,然后停止。 - David Kroukamp

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