JButton 保持按下状态
在我的 Java GUI 应用程序中,我有一个 JButton,单击时它会调用一个函数来连接到数据库,然后调用一个函数 来清除
DB
中的表
,然后调用从一个文件读取文本的函数
并加载变量
,它调用从另一个文件读取文本的函数
,比较两个文件中的数据
,然后调用函数
来更新
或在数据库中插入
数据,所有这些都工作正常。
然而,我的问题与JButton
有关,当单击它时,我想运行一个不确定进度条
,以便用户知道工作正在完成,然后在它离开之前将操作侦听器设置不确定为 false
并将进度条
的值设置为100(完整)
,但在我的情况下,当您单击 < code>button 它停留在单击状态并且进度条
冻结。
我应该采取什么措施来防止这种情况发生?线程可能吗?但我对 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());
}
}
In my Java GUI app I have a JButton
and when clicked it calls a function
to connect to a database
, then calls a function
to clear
a table
in the DB
, then calls a function
that reads text from one file and loads variables
, which calls a function
that reads text from another file, compares the data
from both and then calls a function
to either update
or insert
data in the DB, all of that works fine.
However my question is related to the JButton
, when its clicked I want to run a Indeterminate progress bar
just so the user knows work is being done and then right before it leaves the the action listener setIndeterminate to false
and set the value of the progress bar
to 100(complete)
, but in my case when you click the button
it stays in the clicked state and the progress bar
freezes.
What should I implement to prevent this? threading possibly? but Im quite new to threading in java. here is my action listener:
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());
}
}
}
}
On a side note, I would like to have the action bar actually move as the the program progresses but I wasnt sure how to monitor its progress.
Thanks, Beef.
UPDATE here is my example of SwingWorker and how I used it:
Declared globally
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();
}
}
Inside my actionPerformed method
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());
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
该问题可能与连接到在 UI 线程中执行昂贵的操作(连接到数据库、读取文件、调用其他函数)有关。在任何情况下,您都不应该从 UI 线程调用使用过多 CPU 时间的代码,因为整个界面在执行您的代码时无法继续,并且会导致应用程序看起来“死”,组件仍保持在以下状态:昂贵的操作完成之前的时间。您应该执行另一个线程,在其中执行昂贵的工作,然后使用
SwingUtilities.invokeLater(Runnable doRun)
以及传递的可运行对象来更新进度。可能存在与组件状态相关的同步问题,但您可以稍后修复这些问题。
The problem is probably related to connecting to doing expensive operations in the UI thread (connecting to a database, reading from a file, calling other functions). Under no circumstances should you call code that uses excessive CPU time from the UI thread, as the entire interface can't proceed while it is executing your code, and it results in a 'dead' looking application, with components remaining in their state at the time before an expensive operation until completion. You should execute another thread, do the expensive work in that, and then use a
SwingUtilities.invokeLater(Runnable doRun)
with a passed runnable where you'd update the progress.There may be synchronisation issues relating to the states of components, but you can fix these later.
您可以启动
SwingWorker
来自按钮的处理程序,如图所示 这里。实现Runnable
的相关示例可见这里。You can start a
SwingWorker
from your button's handler, as shown here. A related example implementingRunnable
is seen here.处理进度条的一种方法是在类中扩展
SwingWorker
。SwingWorker
负责为您运行后台任务,因此您不必实现自己的线程,这可能会导致未知问题。首先,处理进度条 UI 的类应该实现
PropertyChangeListener
并实现 public void propertyChange(PropertyChangeEvent evt) { - 根据全局变量更新进度条状态。
后台任务类应如下所示(这可能是内部类):
在按钮的事件侦听器上:
我尝试淡化代码示例,您必须阅读一些教程才能了解所有这些部分如何组合在一起。但是,要点是不要对线程进行编码,而是使用
SwingWorker
One method to handle progressbars are to extend
SwingWorker
in a class.SwingWorker
takes care of running background tasks for you and so you do not have to implement your own threading that can end up in unknown issues.To begin with, your class that takes care of progress bar UI should implement
PropertyChangeListener
And implement
public void propertyChange(PropertyChangeEvent evt) {
- to update the progressbar status based on a global variable.The background task class should look like the following(this could be an inner class) :
on your button's event listener :
I have tried to water down code example, you would have to read some tutorial to understand how all these pieces fit together. However, the main point is do not code your Threads, instead use
SwingWorker
您需要告诉进度条已经取得了多少进展,因为它不知道完成的百分比。更好的是,编写一个更新和重新绘制进度条的方法,而不是在此处重复方法调用。
您还需要确保您的特定按钮正在触发所执行的操作。
connEtoC1(e);应该执行控制器类或 SwingWorker 而不是从 GUI 触发
You will need to tell the progress bar how much progress has been made because it does not know the percentage completed. Better yet, write a method that updates and repaints the progress bar rather than repeating the method calls here.
You will also need to make sure that your specific button is firing the action performed.
The connEtoC1(e); should execute a controller class or SwingWorker rather than firing from the GUI