JButton 保持按下状态

发布于 2024-12-06 07:39:00 字数 2707 浏览 2 评论 0原文

在我的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

∝单色的世界 2024-12-13 07:39:00

该问题可能与连接到在 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.

幻想少年梦 2024-12-13 07:39:00

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

您可以启动 SwingWorker 来自按钮的处理程序,如图所示 这里。实现Runnable的相关示例可见这里

Could I create the new thread when the action is performed and call the new functions in the thread, or should I do the threading within the actual function itself?

You can start a SwingWorker from your button's handler, as shown here. A related example implementing Runnable is seen here.

顾挽 2024-12-13 07:39:00

处理进度条的一种方法是在类中扩展 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

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) :

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

on your button's event listener :

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

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

情愿 2024-12-13 07:39:00
                    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 触发

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

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.

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

You will also need to make sure that your specific button is firing the action performed.

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

The connEtoC1(e); should execute a controller class or SwingWorker rather than firing from the GUI

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文