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