当前位置: 首页 > 知识库问答 >
问题:

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

邹时铭
2023-03-14

我试图为在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();
}

swing worker是在创建“my_list=new CardDatabase();”的过程中创建的。在那门课上,我有swing worker和swing worker应该监控的流程

我目前在一个名为“populate_cards()”的方法中调用swing worker,并使用以下代码创建swing worker。swing worker应该监视populate_cards()方法中发生的事情。swing worker方法中的所有数据都只是暂时的,直到我更好地理解如何使其按我希望的方式工作。

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

我认为问题在于,我正在为实际的GUI调用“invokeLater”方法内部的进度条。

为了解决我的问题,我研究了以下问题。

如何添加进度条?

进度条可以在main之外的类中使用吗?

我也看过教程。

共有1个答案

范浩荡
2023-03-14

你的代码没问题。progressBar(以及gui本身)在代码结束后弹出的原因是,在java中,默认情况下,代码和gui在同一线程上运行。因为代码的优先级高于gui,所以所有代码都会先执行,然后gui会更新。

你应该用“go”的方法:

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

有关线程的更多信息,请参阅那篇文章

我在接电话,很抱歉写得不好。

代码和GUi线程

来自维基百科

最后一个

 类似资料:
  • 在上一章中,我们创建了一个示例RMI应用程序。 在本章中,我们将解释如何创建RMI应用程序,其中客户端调用显示GUI窗口(JavaFX)的方法。 定义远程接口 在这里,我们使用名为animation()的方法定义一个名为Hello的远程接口。 import java.rmi.Remote; import java.rmi.RemoteException; // Creating Remote

  • 问题内容: 如何为手机创建J2ME应用程序,其GUI与您在Java游戏中看到的菜单类似?我已经尝试过使用Netbeans的MIDlet,但是它们一次只显示一个GUI元素。 (文本框,选择项,登录名等) 您通常在哪个Java IDE中设计这些GUI?Netbeans还是Eclipse?IntelliJ IDEA也可用于此吗? 我是否必须编写/获取一个库,该库通过位图函数将GUI控件绘制到屏幕上,并保

  • 问题内容: 我需要从Docker容器中在后台运行的Java应用程序中启动Selenium。启动失败,因为在运行时无法访问X11环境。请参阅下面的内容。 我该怎么办? 问题 我从安装Java 8和Jetty 9.3.x 的简单程序开始运行一个简单的服务(实际上是selenium的东西)。该服务实际上是为了启动一些需要UI才能执行的事情而设置的。我遇到的问题是其中的任何内容执行失败,因为UI在我运行的

  • 我对Java没有太多的经验,并且很难得到一个进度条来工作。我正在使用NetBeans的内置GUI Maker。目前,我的程序从一个目录读取图像到一个图像数组。显然,这需要一点时间,因此我希望一个简单的进度条来更新用户,以了解加载的程度。我已经使用了其中一个拖放进度条组件。 我目前可以获取目录中的文件数,并可以计算加载文件的百分比 文件成功加载到数组中,但进度条只有在加载所有文件后才会更新。我尝试在

  • 我有一个PySide GUI应用程序(用Python 3编写,运行在Windows 7 Pro上),其中IM设置应用程序图标如下: 我从这个答案中得到了 内容。如果删除这些行,那么当我执行 时,任务栏中将显示Python图标。 有了这些行,所有东西看起来都很棒,窗口和任务栏上都有正确的图标。但是,当我使用cxfreeze打包gui时,窗口和任务栏图标都更改为一般的windows.exe图标。 IM