JButton处于紧迫状态

时间:2011-09-23 14:54:22

标签: java swing actionlistener swingworker jprogressbar

在我的Java GUI应用程序中,我有JButton,点击后会调用function来连接到database,然后调用functionclear } table中的DB,然后调用function从一个文件中读取文本并加载variables,该function调用从另一个文件读取文本的data文件,比较两者中的function,然后将update调用到数据库中的insertJButton数据,所有这些都可以正常工作。

但是我的问题与Indeterminate progress bar有关,点击后我想运行一个action listener setIndeterminate to false,以便用户知道正在完成的工作,然后就在它离开{{1}之前并将progress bar的值设置为100(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());
                    }
                }
            }
        }

另一方面,我希望操作栏实际上随着程序的进展而移动,但我不确定如何监控其进度。

谢谢,牛肉。

UPDATE 这是我的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 个答案:

答案 0 :(得分:7)

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

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

答案 1 :(得分:6)

  

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

您可以从按钮的处理程序中启动SwingWorker,如图here所示。实现Runnable的相关示例见here

答案 2 :(得分:5)

处理进度条的一种方法是在类中扩展SwingWorkerSwingWorker负责为您运行后台任务,因此您不必实现自己的线程,最终可能导致未知问题。 首先,负责处理进度条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

答案 3 :(得分: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

触发