5

在我的 Java GUI 应用程序中,我有一个JButton,单击时它调用 afunction连接到 a database,然后调用 afunction中的cleara ,然后调用从一个文件读取文本并加载的 a,它调用从另一个文件读取文本的 a,比较来自两者,然后调用数据库中的一个或数据,所有这些都可以正常工作。tableDBfunctionvariablesfunctiondatafunctionupdateinsert

但是我的问题与 相关JButton,当它被点击时,我想运行一个Indeterminate progress bar,这样用户就知道工作正在完成,然后在它离开之前并将action listener setIndeterminate to false值设置progress bar100(complete),但在我的情况下,当你点击button它时停留在单击状态并progress bar冻结。

我应该采取什么措施来防止这种情况?线程可能?但我对java中的线程很陌生。这是我的动作监听器:

    private class buttonListener implements ActionListener
        {
            public void actionPerformed(ActionEvent e)
            {
                if( e.getSource() == genButton )
                {
                    progressBar.setIndeterminate(true);
                    progressBar.setString(null);
                    try 
                    {
                        dbConnect(); //connects to DB
                        clearSchedules(); // deletes data in tables
                        readFile(); // reads first file and calls the other functions
                        dbClose();// closes the DB
                        progressBar.setIndeterminate(false);
                        progressBar.setValue(100);
                    } 
                    catch (Exception e1){
                        System.err.println("Error: " + e1.getMessage());
                    }
                }
            }
        }

附带说明一下,我想让操作栏随着程序的进行而实际移动,但我不确定如何监控它的进度。

谢谢,牛肉。

这里的更新 是我的 SwingWorker 示例以及我如何使用它:

在全球范围内宣布

 private functionWorker task;


    private abstract class functionWorker extends SwingWorker { 

        public void execute() {
            try {
                dbConnect();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            clearSchedules();
            try {
                readFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
            dbClose();
        }
    }

在我的 actionPerformed 方法中

if( e.getSource() == genButton )
            {

                progressBar.setIndeterminate(true);
                progressBar.setString(null);
                try 
                {
                    task.execute();

                    progressBar.setIndeterminate(false);
                    progressBar.setValue(100);
                } 
                catch (Exception e1){
                    System.err.println("Error: " + e1.getMessage());
                }
            }
4

4 回答 4

7

问题可能与连接到在 UI 线程中执行昂贵的操作(连接到数据库、从文件读取、调用其他函数)有关。在任何情况下,您都不应从 UI 线程调用占用过多 CPU 时间的代码,因为整个界面在执行代码时无法继续,这会导致应用程序看起来“死”,组件仍处于其状态昂贵的操作之前直到完成的时间。您应该执行另一个线程,在其中完成昂贵的工作,然后将 aSwingUtilities.invokeLater(Runnable doRun)与传递的可运行文件一起使用,您将在其中更新进度。

可能存在与组件状态相关的同步问题,但您可以稍后修复这些问题。

于 2011-09-23T14:58:40.500 回答
6

我可以在执行操作时创建新线程并调用线程中的新函数,还是应该在实际函数本身中执行线程?

您可以从按钮的处理程序启动 a ,如此SwingWorker所示。在这里可以看到一个相关的实现示例。Runnable

于 2011-09-23T15:12:58.050 回答
5

处理进度条的一种方法是SwingWorker在类中扩展。 SwingWorker负责为您运行后台任务,因此您不必实现自己的线程,这可能会导致未知问题。首先,处理进度条 UI 的类应该实现PropertyChangeListener 并实现public void propertyChange(PropertyChangeEvent evt) {- 根据全局变量更新进度条状态。

后台任务类应如下所示(这可能是一个内部类):

class ProgressTask extends SwingWorker<Void, Void> {
        @Override
        public Void doInBackground() {
             //handle your tasks here
             //update global variable to indicate task status.
        }
        @Override
        public void done() {
             //re-enabled your button
        }
}

在按钮的事件监听器上:

 public void actionPerformed(ActionEvent evt) {
    //disable your button
    //Create new instance of "ProgressTask"
    //make the task listen to progress changes by task.addPropertyChangeListener(this);
    //calll task.execute();
 }

我试图淡化代码示例,您必须阅读一些教程才能了解所有这些部分如何组合在一起。但是,要点是不要对线程进行编码,而是使用SwingWorker

于 2011-09-23T15:11:37.287 回答
0
                    progressBar.setIndeterminate(true);
                    progressBar.setValue(0);                        
dbConnect(); //connects to DB
                    progressBar.setIndeterminate(true);
                    progressBar.setValue(10);
                    clearSchedules(); // deletes data in tables
                    progressBar.setIndeterminate(true);
                    progressBar.setValue(50);
                    readFile(); // reads first file and calls the other functions
                    progressBar.setIndeterminate(true);
                    progressBar.setValue(75);
                    dbClose();// closes the DB
                    progressBar.setIndeterminate(false);
                    progressBar.setValue(100);

您需要告诉进度条已经取得了多少进展,因为它不知道完成的百分比。更好的是,编写一个更新和重新绘制进度条的方法,而不是在这里重复方法调用。

updateProgressBar(int progress, boolean isDeterminate, String msg){};

您还需要确保您的特定按钮正在触发执行的操作。

class IvjEventHandler implements java.awt.event.ActionListener {
        public void actionPerformed(java.awt.event.ActionEvent e) {
            if (e.getSource() == JMyPanel.this.getJButtonUpdate()) 
                connEtoC1(e);
    };
};

connEtoC1(e);应该执行控制器类或 SwingWorker 而不是从 GUI 触发

于 2011-09-23T15:12:59.433 回答