【问题标题】:java Jframe refuses to render when called from outsidejava Jframe从外部调用时拒绝渲染
【发布时间】: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


【解决方案1】:

**** 我明白了!!!! ****

我一遍又一遍地使用我的代码,直到最终找到解决方案......

在检查我调用报告器进程的菜单类时,我意识到当报告器运行时,菜单类被锁定并且没有响应。我无法移动、调整大小或关闭它...

所以我开始使用 Google 教授,并了解如何将我的记者课程包含在自己的线程中。为此,我必须让记者实现 java.lang.Runnable,然后从菜单类中像这样调用记者

Reporter r = new Reporter();
r.setWhere(" year='" + cyear +"'");
r.setReport("T");
Thread t1 = new Thread(r);
t1.start();

我必须创建 setWhere 和 setReport 函数来将参数转储到类中,因此我可以从报告器类的 run() 函数中进行导致负载过重的实际函数调用。

然后,这将 Swing GUI 与大量迭代的报告器类分离,这样我的所有框架都会按我希望的方式显示。

这对我来说是一个新概念。尽管他们在我的 java 类中向我们展示了线程的概念(18 年前),但我从来没有使用过它。我从来没有一个应用程序会在其中类相互锁定或因为它需要大量的 CPU 负载。

有趣的是(对于我作为业余爱好者而言),尽管记者进程很忙,但我实际上可以从记者类内部调用和更新进度条框架,而无需将其包装到另一个线程中。所要做的就是解耦菜单类。 非 GUI 报告器类和进度条 GUI 似乎仍然可以协同工作而不会相互阻塞。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2011-10-17
    • 2015-03-10
    • 1970-01-01
    相关资源
    最近更新 更多