我只是想在完成长时间下载时在框架的左下角设置一个不确定的 JProgressBar 动画。
我浏览了很多教程,但对我来说没有一个是清楚的。我只是想让它在后台下载文件时设置动画。在我尝试过的每一种方式中,它都不会在下载完成之后之前为进度条设置动画。
我需要帮助知道在哪里放置我的 download() 调用。
class MyFunClass extends JFrame {
JProgressBar progressBar = new JProgressBar();
public void buttonClicked() {
progressBar.setVisible(true);
progressBar.setIndeterminate(true);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
progressBar.setIndeterminate(true);
progressBar.setVisible(true);
// Do I do my download() in here??
}});
// Do download() here???
progressBar.setVisible(false);
}
}
提前致谢!
解决方案
编辑:对于以后和我有类似问题的人来说,这是一个基本问题的基本解决方案。这不是我的逐字代码,而是一般草图。在 buttonClicked()
中:
public void buttonClicked() {
class MyWorker extends SwingWorker(String, Object) {
protected String doInBackground() {
progressBar.setVisible(true);
progressBar.setIndeterminate(true);
// Do my downloading code
return "Done."
}
protected void done() {
progressBar.setVisible(false)
}
}
new MyWorker().execute();
}
最佳答案
您当前的代码显示没有创建后台线程,而是显示您试图在 Swing 线程上对代码进行排队从 Swing 线程中没有对这个问题很有意义(虽然有时你可能想这样做,但再次强调,不在这里)。成功的唯一方法是使用后台线程。标准甲骨文JProgressBar tutorial和 Concurrency in Swing经历了这一切。
基本的事情是您必须从 Swing Thread 更新 JProgressBar 将在后台线程中执行长时间运行的进程,例如 SwingWorker 对象提供的进程。我们无法在此处查看所有详细信息,因此我所能做的就是提供一个链接,但我们很乐意在您查看教程后帮助您了解详细信息。只需查看教程,如果仍然卡住,再回来提出您的具体问题。
编辑 1
你声明:
can I just create a new thread object within the buttonClicked() function?
是的,您可以在 buttonClicked()
方法 中创建一个 SwingWorker 对象并在那里执行它。
The thing is I have my API and library of all the functionality that I'm developing the GUI to, and it seems like a longwinded workaround to wrap that function call in a thread.
抱歉,我不知道您在这里说的是什么,也不知道您认为线程会导致什么问题。 buttonClicked()
方法可能必须 在 EDT 而不是后台线程中运行。
另请注意,在我的大多数更复杂的 Swing GUI 中,我经常在不同的(模型)对象中下载文件,并在与 GUI 对象( View )不同的对象(控件)中创建我的 SwingWorker。这样做可能看起来更复杂,但是当我这样做时,调试、维护和增强我的程序会很多,尤其是当我大量使用时允许我单独测试所有程序组件的接口(interface)。
编辑2
对您的解决方案发布的一些更正。您发布了:
public void buttonClicked() {
class MyWorker extends SwingWorker(String, Object) {
protected String runInBackground() {
progressBar.setVisible(true);
progressBar.setIndeterminate(true);
// ...
有问题
- 是
doInBackground()
,不是runInBackground()
- 但更重要的是,您是从后台线程中进行 Swing 调用,这是永远不应该做的事情(除非调用是线程安全的,即使那样...)。
所以改变它:
public void buttonClicked() {
progressBar.setVisible(true);
progressBar.setIndeterminate(true);
class MyWorker extends SwingWorker<String, Void> {
protected String doInBackground() {
// ...
关于java - 基本不确定进度条用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10442406/