我有一个.csv文件,它是来自60000个手绘数字(手写数字的mnist数据集)的完整像素数据。 按下按钮时将调用一个名为train()的函数。 我希望从train()函数中的每一个60000位数字显示在屏幕上。 代码工作得非常好,我只是无法从train()方法中更新JFrame。

我测试了代码,它100%可以正常工作。 我只是无法在train()函数中更新JFrame。

    public void trainMenu() {
        JButton trainBtn = new JButton("Train");
        JLabel otp = new JLabel();
        JPanel bottomBar = new JPanel();
        trainImage = new ImageIcon();
        JLabel imageLabel = new JLabel(this.trainImage);

        bottomBar.setLayout(new GridLayout(1,2,5,5));
        bottomBar.add(trainBtn);
        bottomBar.add(otp);
        this.frame.getContentPane().add(BorderLayout.CENTER,imageLabel);
        this.frame.getContentPane().add(BorderLayout.SOUTH, bottomBar);
        SwingUtilities.updateComponentTreeUI(this.frame);

        ActionListener trainListener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() == trainBtn) {
                    train();
                }
            }
        };

        trainBtn.addActionListener(trainListener);
    }

    void train() {
        BufferedImage bImage;
        //all 60000 numbers are extracted from a .csv file
        //i omitted everything from this function because it's not important for this question
                ...

                //this line is run 60000 times. it displays the converted pixel data (very fast) the code definitely works, it simply won't update.
                this.trainImage.setImage(bImage);
                SwingUtilities.updateComponentTreeUI(frame);
            }
        }


    }

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

当我按下“火车”按钮时,GUI冻结,并且在train()方法完成之前一直没有响应。

#1楼 票数:0

而不是更新trainImage ,为JLabel设置一个新的ImageIcon

imageLabel.setIcon(new ImageIcon(bImage));

您可能还需要在标签上调用revalidate和/或repaint以触​​发新的布局/绘制过程。

就个人而言,我会从train方法返回BufferedImage ,因为train方法确实不应该更新UI,这不是工作。

当我按下“火车”按钮时,GUI冻结,并且在train()方法完成之前一直没有响应。

是的,这是因为Swing与大多数UI工具包一样都是单线程的。 这意味着,如果您在事件调度线程的上下文中执行任何阻止或长时间运行的操作,则将阻止它更新UI或响应任何用户输入。

有关更多详细信息,请参见Swing中的并发

可能的解决方案是使用SwingWorker 这使您可以在其他线程上执行阻止/长时间运行的操作,但是提供了多种将更新安全地同步回UI的方法(Swing也不是线程安全的;)

有关更多详细信息,请参见工作线程和SwingWorker

#2楼 票数:0

您的GUI挂起是因为您在Swing事件线程上进行了大量图像操作。 您可以使用诸如SwingWorker之类的东西吗? 这样,您可以在单独的线程上构建映像,并且仅在必要时更新GUI。

private void train() {
    SwingWorker<BufferedImage, Object> worker = new SwingWorker<BufferedImage, Void>() {
        @Override
        protected BufferedImage doInBackground() throws Exception {
            // load the CSV file
            BufferedImage bImage = new BufferedImage();
            // ... fill up the bImage
            return bImage;
        }

        @Override
        protected void done() {
            try {
                BufferedImage img = get();
                // ... set the trainImage
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
    };

    worker.execute();
}

  ask by Mezex translate from so

未解决问题?本站智能推荐:

1回复

如何从Java中的另一个JFrame更新JFrame

我想从另一个JFrame更新一个JFrame。 我有一个基本程序,该程序具有两个具有相同组名的相似接口,我想知道如何编写该程序,因此,如果一个人更改了组名,它将自动在另一个上更改。 提前致谢 第一个界面 第二介面 这是我的尝试,但是没有用。
1回复

从另一个JFrame调用JFrame方法

我也正在寻找解决方案。 目前,我的netbeans项目中有2个JFrames和1个实用程序类。 我不是Java方面的专家,所以请多多包涵。 我尝试浏览Java文档以及在此站点上,但是似乎找不到解决我问题的方法。 这是场景: 我的启动器类启动名为MainForm.java的JFr
2回复

如何使用来自另一个JFrame的数据更新JFrame?

是否可以使用来自另一个JFrame的数据更新JFrame? 就像,我更改右侧JFrame上的数据,然后左侧JFrame上的数据会自动更新?
1回复

java JFrame更新修改了另一个JFrame

我有一个屏幕( JFrame )从文件中获取一些初始填充。 但是,如果文件由于某种原因缺席或填充不正确,则许多字段被阻止为不可编辑,并且用户被迫单击设置按钮,这将生成另一个JFrame屏幕。 如果用户然后正确更新文件我希望用新文件数据重新填充原始屏幕,这可以完成吗? 所以我有一个设置按
1回复

如何在另一个类中更新JFrame?

我想在构造函数外部或从另一个类更新创建的Control的JLabel。 在这里,我创建了一个控件,并在构造函数中添加了一些组件。 UI是在main中创建的,但是我想在此类之外更新一些标签。 所以我创建setResult(final String text,final String path
1回复

在单击按钮时从另一个JFrame调用JFrame方法

我在堆栈溢出中搜索了类似的问题答案,但没有一个对我有帮助。 所以我的问题是以下几点: 我有一个名为Main_Window的主JFrame,在其上有一个JTable和JButton。 单击按钮后,将打开另一个JFrame( Update_Window ),可以从中更新表。 Upda
2回复

从另一个 jframe 关闭 jframe

我有 2 个jframes (jframeA,jframeB) 。 单击jframeA和jframeB的按钮必须关闭。 jframeA在项目启动时创建,下面是创建框架并将其设置为可见的代码部分。 (以上代码由netbeans自动创建) 我想从jframeB关闭这个框架。 正如我们在上面的
1回复

如何通过另一个JFrame修改JFrame?

我有两个JFrames A和B。B有一个textArea。 我想通过单击A中的按钮向B中的TextArea添加一些文本。这是我的代码: b是B类的对象 textArea是类B中的JTextArea变量名