使用Java的GUI应用程序的进度栏

时间:2018-08-06 04:02:01

标签: java user-interface progress-bar

我正在尝试为正在运行GUI之前下载信息的应用程序编写进度条。由于下载和整理信息的过程非常漫长,因此我想将进度告知用户。我决定在游戏后期使用进度条,因此,大部分代码都已编写,并且我试图将进度条合并到代码中,而无需进行大量的代码修改。以下是进度条的代码。当前,一切正常运行并弹出GUI后,进度条会出现。

static class PopulatingCardsWorker extends SwingWorker<Void, Integer> {

    JProgressBar jpb;
    int max;
    JLabel label;

    public PopulatingCardsWorker(JProgressBar jpb, int maximum, JLabel label) {
        this.jpb = jpb;
        this.max = maximum;
        this.label = label;
    }

    @Override
    protected void process(List<Integer> chunks) {
        int i = chunks.get(chunks.size()-1);
        jpb.setValue(i); // The last value in this array is all we care about.
        System.out.println(i);
        label.setText("Loading " + i + " of " + max);
    }

    @Override
    protected Void doInBackground() throws Exception {
        for(int i = 0; i < max; i++) {
            Thread.sleep(10); // Illustrating long-running code.
            publish(i);
        }
        return null;
    }

    @Override
    protected void done() {
        try {
            get();
            JOptionPane.showMessageDialog(jpb.getParent(), "Success", "Success", JOptionPane.INFORMATION_MESSAGE);
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

private static void go(int max) {
    JFrame frame = new JFrame();
    JPanel panel = new JPanel();
    JLabel label = new JLabel("Loading...");
    JProgressBar jpb = new JProgressBar();
    jpb.setIndeterminate(false);
    jpb.setMaximum(max);
    panel.add(label);
    panel.add(jpb);
    frame.add(panel);
    frame.pack();
    frame.setSize(200,90);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    new PopulatingCardsWorker(jpb, max, label).execute();
}

程序首先调用GUI应用程序,然后运行数据库获取代码,如下所示。

public static void main(String args[]) {
    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new MagicTheGatheringUI().setVisible(true);
        }
    });
}

public MagicTheGatheringUI() {
    int i, size;

    colorRefinementFilter = "selected";
    try {
        my_list=new CardDatabase();
        my_list.sortByName(my_list.all_cards);
        my_list.populateSubArrays();
        size = my_list.all_cards.size();

        for(i = 0; i < size; i++)
        {
            namesList.addElement(my_list.all_cards.get(i).name);
        }
    } catch(Exception e) {
        System.out.println(e);
        System.exit(0);
    }
    initComponents();
}

在创建“ my_list = new CardDatabase();”的过程中创建了swing worker。在那堂课中,我有摇摆工人和摇摆工人应该监视的过程。

我目前使用名为“ populate_cards()”的方法调用摆动工作程序,并使用以下代码创建摆动工作程序。 Swing Worker应该监视populate_cards()方法中发生的事情。在我更好地了解如何使其以期望的方式工作之前,swing worker方法中的所有数据都是临时的。

SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            go(1000);
        }
    });

我相信问题是我在实际的GUI的“ invokeLater”方法内部调用进度条。

我查看了以下问题以尝试解决我的问题。

How to add a progress bar?

Can a progress bar be used in a class outside main?

我也看过教程。

1 个答案:

答案 0 :(得分:0)

您的代码正常。代码结束后会弹出progressBar(和gui本身)的原因是,在Java中,默认情况下,代码和gui在同一线程上运行。由于代码的优先级高于gui,因此所有代码都将首先执行,然后gui更新。

您应该使用“ go”方法进行操作:

new Thread(){
    public void run(){
       new PopulatingCardsWorker(jpb, max, label).execute();
    }
} start();

see that article for more information about threads

我正在通过电话接听电话,非常抱歉写得不好。

Code and GUi threads

and from Wikipedia

last one