JProgressBar 未更新

2024-03-22

我制作了一个非常简单的代码来在此处显示它,我有一个按钮应该显示 JDialog 来检查进度状态,我正在使用延迟调用来完成 EDT 并且我的循环不在 run 方法中,那么为什么我的酒吧没有更新吗? 这是代码

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class JBarEx extends JFrame {
private JTextField progStatus = new JTextField("Undefined");
private JButton dialogBtn = new JButton("Show Progression dialog");
final JDialog dlg = new JDialog((JFrame) null, "prog Title", false);
final JProgressBar dpb = new JProgressBar(0, 100);

public JBarEx() {
    JPanel pan = new JPanel();
    dialogBtn.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            showProgress();
        }
    });
    progStatus.setEditable(false);
    pan.add(progStatus);
    pan.add(dialogBtn);
    setContentPane(pan);
    this.setSize(200, 100);
    setVisible(true);
}

public void showProgress() {
    dlg.add(BorderLayout.CENTER, dpb);
    dlg.add(BorderLayout.NORTH, new JLabel("prog message"));
    dlg.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
    dlg.setSize(300, 75);
    dlg.setLocationRelativeTo(null);
    dlg.setVisible(true);

    for (int i = 0; i < 100; i++) {
        final int ii = i;
        try {
            Thread.sleep(25);
            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    updateBar(ii);

                }
            });
        }
        catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

public void updateBar(int newValue) {
    dpb.setValue(newValue);
}

public static void main(String[] args) {
    JBarEx jbx = new JBarEx();
}

}


Your showProgress方法正在事件调度线程的上下文中执行。 EDT 负责处理油漆请求等。这意味着只要您的for-loop正在执行时,EDT 无法处理任何新的绘制请求(或处理invokeLater事件),因为它阻塞了 EDT。

虽然有很多可能的方法来解决问题,但根据您的代码示例,最简单的方法是使用SwingWorker http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html.

它能够让您在后台线程中执行长时间运行的任务(释放 EDT),而且还允许您publishing更新(如果需要),以便可以在 EDT 中处理它们,并提供方便的progress通知。

例如...

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class SwingWorkerProgress {

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

    public SwingWorkerProgress() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JProgressBar pbProgress;
        private JButton start;

        public TestPane() {

            setBorder(new EmptyBorder(10, 10, 10, 10));
            pbProgress = new JProgressBar();
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.insets = new Insets(4, 4, 4, 4);
            gbc.gridx = 0;
            gbc.gridy = 0;
            add(pbProgress, gbc);

            start = new JButton("Start");
            gbc.gridy++;
            add(start, gbc);

            start.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    start.setEnabled(false);
                    ProgressWorker pw = new ProgressWorker();
                    pw.addPropertyChangeListener(new PropertyChangeListener() {

                        @Override
                        public void propertyChange(PropertyChangeEvent evt) {
                            String name = evt.getPropertyName();
                            if (name.equals("progress")) {
                                int progress = (int) evt.getNewValue();
                                pbProgress.setValue(progress);
                                repaint();
                            } else if (name.equals("state")) {
                                SwingWorker.StateValue state = (SwingWorker.StateValue) evt.getNewValue();
                                switch (state) {
                                    case DONE:
                                        start.setEnabled(true);
                                        break;
                                }
                            }
                        }

                    });
                    pw.execute();
                }
            });

        }
    }

    public class ProgressWorker extends SwingWorker<Object, Object> {

        @Override
        protected Object doInBackground() throws Exception {

            for (int i = 0; i < 100; i++) {        
                setProgress(i);
                try {
                    Thread.sleep(25);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            return null;
        }
    }
}

查看Swing 中的并发 http://docs.oracle.com/javase/tutorial/uiswing/concurrency/更多细节

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JProgressBar 未更新 的相关文章

随机推荐

  • Nexus 工件上传

    如何使用 jenkins shell 将工件上传到 Nexus 并自动生成版本 我正在使用这个脚本 我想在上传工件时自动生成版本 mvn deploy deploy file DgroupId DartifactId Dversion Dg
  • 如何使用 Inno Setup 检查互联网连接

    我正在学习 Inno Setup 来制作一个简单的安装程序 在安装过程中我需要从网站下载文件 因此检查是否有互联网连接很重要 在安装过程中如何检查或采取一些警报以连接互联网 Thanks 最好的检查是尝试实际下载该文件 互联网 几乎不是一个
  • Makefile 排列

    Bash 可以产生排列 笛卡尔积 http wikipedia org wiki Cartesian product echo 1 2 a b 1a 1b 2a 2b 我想用 makefile 做类似的事情 这是一个例子 生成文件 all
  • 无效异常展开导致崩溃?

    我正在调试我们的一项测试中发生的崩溃 我们有一个用 C 编写的 ODBC 驱动程序 so 正在使用我们的测试工具 称为 Touchstone 通过 iODBC 对其进行测试 该工具也是用 C 编写的 我已使用 Oracle Solaris
  • jQuery 的 .data() 缓存是否在 jQuery mobile 中的页面转换中持续存在?

    我刚刚在读 jQuery data API参考 http api jquery com data 之前 我推测它可能通过分配来工作 data 页面元素的属性 有效地捷径 foo attr data foobar bar 1 想象一下 它确实
  • 具有自定义默认值的 EclipseLink JPA 主键

    我的 SQL Server 数据库中有一个表 其中主键字段定义为NEWID 作为默认值 期望客户端不需要传递主键字段值 SQL Server 将处理它 在 JPA 定义模型类时 我必须使用生成类型定义此 ID 字段 我试过IDENTITY
  • 如何通过RPC监听firestore

    我想听firestore中的实时变化 而且我也只允许使用Go 由于 Firestore SDK for Go 没有任何选项来监听实时更改 因此我决定使用 firestore v1beta1 sdk 我编写了以下代码来做到这一点 func T
  • jq:打印对象中每个条目的键和值

    如何得到jq像这样获取 json host1 ip 10 1 2 3 host2 ip 10 1 2 2 host3 ip 10 1 18 1 并生成此输出 host1 10 1 2 3 host2 10 1 2 2 host3 10 1
  • Django 查询中的列比较

    我有以下模型 class Car models Model make models CharField max length 40 mileage limit models IntegerField mileage models Integ
  • 滥用设计模式

    在规范的 四人帮 列表中 是否有任何您经常发现误用 误解或过度使用的设计模式 除了备受争议的单例模式之外 换句话说 是否有一种设计模式您建议在使用之前三思而后行 为什么 工厂模式 我之前被空投到一个项目中 每个人都MyObject系统中有一
  • 从日期中分割日期和时间以单独键入

    我想这样做 Date meetingDateAndTime
  • 非负整数和小数值的验证

    我的字段是 tax rate and tax amount我想在其中验证积极的价值观 我写了这个验证 format gt with gt A d Z 但它并不是像这样取带小数点的数字4 67 它给我带来了一个错误 什么类型的验证适用于整数和
  • 某些曲目上的 SoundCloud API 403

    我已经有一个使用 soundcloud API 将 soundcloud 链接嵌入为有效播放器的应用程序有一段时间了 我最近注意到中等数量的403 Unauthorized从曲目查找返回的错误 api soundcloud com trac
  • UTF-8 和 TinyXML

    由于某种原因 我无法正确从 xml 文件读取数据 例如 我得到的不是 Schr der 而是类似 Schr der 的内容 My code tinyxml2 XMLDocument doc bool open string path if
  • InternalsVisibleTo 不适用于 wpf 应用程序

    我在另一个程序集中设置了 程序集 InternalsVisibleTo GuiAssembly 但是当 wpf 绑定发生在另一个程序集中的类上时 它会抛出异常 因为该类中的属性是内部的 我知道这适用于其他应用程序 但不确定为什么它不适用于这
  • SQL Server 递归 CTE 是否被视为循环?

    我的印象是递归 CTE 是基于集合的 但是在一个最近的SO帖子 https stackoverflow com questions 7824831 generate dates between date ranges 7824919 com
  • Python-Docx 缺少默认模板

    我最近安装了 python docx 包 但在使用默认模板时遇到了一些问题 我只是设置一个文档并具有以下代码 在名为 maintitle py 的文件中 from docx import Document from docx shared
  • K 表示使用 PySpark 进行聚类

    我有一个非常大的数据框 我必须使用数据框中的特定 8 列 其中值要么是 强烈同意 同意 或 不同意 根据这 8 列 我需要创建一个新列来告诉该行属于哪个簇 1 8 最好使用 K 均值聚类 这在 PySpark 中可能吗 PS 我是 PySp
  • CodeIgniter 动态语言功能

    我是 Codeigniter 我需要为用户提供动态语言 我在标题处添加了下拉菜单 我希望允许用户在前端更改网站的语言 我尝试在一个控制器中使用以下代码更改语言 this gt config gt set item language span
  • JProgressBar 未更新

    我制作了一个非常简单的代码来在此处显示它 我有一个按钮应该显示 JDialog 来检查进度状态 我正在使用延迟调用来完成 EDT 并且我的循环不在 run 方法中 那么为什么我的酒吧没有更新吗 这是代码 import javax swing