【发布时间】:2020-02-06 18:32:33
【问题描述】:
我有一个完全荒谬的问题。
情况: 我有一个reporter.java 类,我从中调用一个带有StatusBar 的小型JFrame 类(status.java)。我的reporter.java 有一个主要功能,我可以从中测试其正确性。如果我这样做,一切都会很好。
现在奇怪的事情来了。
我有一个带有菜单栏的 JFrame 类 (menu.java),我从中创建了记者类的一个实例。当我从那里而不是从其主函数调用记者类时,进度类会按要求打开,但它拒绝呈现。我得到的只是一个空框架,我什至无法关闭它,因为它似乎被冻结了。记者中的流程一模一样……
我必须补充一点,记者类中的任务将数百个表格创建到一个 pdf 文件中。这会占用我win10的整个cpu容量几分钟。
啊,还有一个信息:我在 NetBeans 11 中创建了所有这些类。
这里是我的代码 sn-ps:
public class Progress extends javax.swing.JFrame {
JProgressBar progressBar = null;
public Progress (int maxvalue) {
initComponents();
progressBar = new JProgressBar(0, maxvalue);
jPanel1.add(progressBar, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 20, 340, 30));
progressBar.setVisible(true);
setVisible(true);
this.repaint();
}
private void initComponents() {
jPanel1 = new javax.swing.JPanel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setMaximumSize(new java.awt.Dimension(400, 100));
setMinimumSize(new java.awt.Dimension(400, 100));
setPreferredSize(new java.awt.Dimension(400, 100));
getContentPane().setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());
jPanel1.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());
getContentPane().add(jPanel1, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, 400, 100));
pack();
}
public void updProgress(int wert) {
progressBar.setValue(wert);
progressBar.setVisible(true);
this.setVisible(true);
repaint();
}
public void kill() {
this.setVisible(false);
this.dispose();
}
}
...
这里是我的记者班的电话(覆盖我的代码)
Progress bw = null;
bw = new Progress(table.getRowCount());
bw.updProgress(x);
bw.kill();
然后我从我的菜单中调用 Reporter 类
Reporter r = new Reporter();
在 main 函数中也可以找到完全相同的行。 如前所述,当我从其主要功能调用记者类时,它工作正常。当我从菜单类调用完全相同的记者类时,进度条似乎冻结了。我用一个简单的 JLabel 而不是进度条进行了尝试。这也不会渲染。一定是 JFrame 有问题。也许记者班已经到了极限,也冻结了。它没有 GUI 并且在后台运行,所以我无法检查。
有人知道为什么会这样吗???
【问题讨论】:
-
听起来您可能正在使用长时间运行的逻辑阻碍 AWT 事件调度线程。
new Progress是否在 EDT 线程中调用(例如从事件侦听器)?在那之后你是否调用了任何长时间运行的调用? -
嗨。不,我没有事件监听器。我在记者例程开始时调用我的进度类的构造函数,每次完成新的迭代(表)时在我的循环中调用 updProgress 函数,并在循环结束时调用 kill 命令。我不明白的是,当我从主要和外部启动报告器时,系统的行为不同。记者事后做的一模一样……
-
长时间运行的循环也会阻碍事件分派线程中的事件处理。考虑提供 Reporter 类的缩写形式,我们可以编译它并演示问题(即 minimal reproducible example)。
-
感谢 VGR。我想这很难。我的记者班有大约 600 行代码,其中有无数对数据库的 SQL 调用。这些数据库调用使它们长期运行。但是记者班本身就很好。只有当我从另一个摇摆 JFrame 内部启动记者时,进度条框架不再呈现。也许正如建议的那样,这两个 JFrame 是否会相互阻塞?我知道所有的摇摆类都在同一个线程中运行。我可以强制两个 JFrame 在两个线程中运行以避免锁定吗?也许建议。我是一个java爱好者:-)
-
所有 Swing 和 AWT 调用必须在事件调度线程中进行。但是,其他事情,尤其是数据库调用等长时间运行的任务,应该在不同的线程中进行。有关如何完成此操作的示例,请参阅 docs.oracle.com/javase/tutorial/uiswing/concurrency。
标签: java swing jframe progress-bar