Java JButton保持按下状态

Java JButton保持按下状态,java,swing,actionlistener,swingworker,jprogressbar,Java,Swing,Actionlistener,Swingworker,Jprogressbar,在我的Java GUI应用程序中,我有一个jb按钮,单击它会调用函数连接到数据库,然后调用函数清除数据库中的表,然后调用从一个文件读取文本并加载变量的函数,调用从另一个文件读取文本的函数,比较两个文件的数据,然后调用函数,将更新或插入数据库中的数据,所有这些都可以正常工作 然而,我的问题与JButton有关,当它被单击时,我想运行一个不确定进度条,这样用户就知道工作正在完成,然后就在它离开操作侦听器setUndeterminate之前,将进度条的值设置为false,并将进度条的值设置为100(完

在我的Java GUI应用程序中,我有一个
jb按钮
,单击它会调用
函数
连接到
数据库
,然后调用
函数
清除
数据库中的
,然后调用从一个文件读取文本并加载
变量的
函数
,调用从另一个文件读取文本的
函数,比较两个文件的
数据
,然后调用
函数
,将
更新
插入数据库中的数据,所有这些都可以正常工作

然而,我的问题与
JButton
有关,当它被单击时,我想运行一个
不确定进度条
,这样用户就知道工作正在完成,然后就在它离开
操作侦听器setUndeterminate之前,将
进度条的值设置为false
,并将
进度条的值设置为
100(完成)
,但在我的例子中,当您单击
按钮时,它将保持单击状态,
进度条将冻结

我应该采取什么措施来防止这种情况?可能吗?但是我对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());
                }
            }

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


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

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

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

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

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

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

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

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);
    };
};

接头C1(e);应该执行控制器类或SwingWorker,而不是通过昂贵的操作从GUI启动

您是指必须超出java程序本身的操作,例如文本文件和db?是的。CPU时间方面很昂贵。因此,我是否可以在执行操作时创建新线程并调用新函数线程,或者我应该在实际函数本身中执行线程?您应该在侦听器方法中创建新线程。这实际上不是一个昂贵的操作。有一些方法可以改进这一点(例如,使用外部创建的执行器),但这并不重要。好吧,我没有用java做过很多线程,对我做过的事情也没有很好的理解,但我会再试一次,谢谢你的帮助谢谢,我会看看我能从这些示例中得到什么,并试着实现它们。仔细看你的旁注,这是一个显示
Swin中增量进度的示例gWorker
。再次感谢,我将检查线程部分完成后,仍然尝试分解示例。我是否会创建一个
SwingWorker
,就像
私有类functionWorker扩展SwingWorker{}
但是在
SwingWorker
中调用我的4个方法,然后创建
SwingWorker
的任务,并在我的
actionlistener
中执行该任务,第一个示例中似乎有很多事情,我的头脑很难集中,看起来更容易,但是
SwingWorker
提供了更多的杠杆作用e、 [
RandomDataDemo
]()显示一个DB连接。它声明了
SwingWorker
,但您必须选择所需的粒度。可能是
SwingWorker
,其中
记录
表示一个文件的内容和元数据?我不确定我是否明白,我的程序不喜欢
@Override
方法或
属性ChangeListener的实现e> 或者
Void,Void
argumentsOoops..你在使用什么JDK?所有这些都是J2 SE 5+功能:)我使用的是最新版本,但我最近使用了一个新的用户帐户,所以我不能完全确定请学习java
                    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);
    };
};