我正在尝试创建一个弹出对话框进度条,最好是不确定的,但这并不是太重要。我一直在浏览“Oracle's ProgressBar Tutorials”和谷歌搜索,但没有那么幸运让它工作。我将代码粘贴到操作侦听器下方,并且不会弹出对话框。有什么建议吗?
抱歉,这是我在该网站上的第一篇文章。但它的工作原理是,当我按下创建按钮时,它会从不同的服务器和目录中获取一些信息,并为我创建一个文件。这就是新项目。 Features 是我制作的一个枚举,在创建按钮时使用
JTextBox
中的文本进行设置。问题是这个过程需要时间来处理,所以我想要一个进度条来显示它的处理
private class CreateButton implements ActionListener
{
@Override
public void actionPerformed(ActionEvent arg0) {
class Task extends SwingWorker<Void, Void>
{
@Override
protected Void doInBackground()
{
//Set Variables
for(Feature f : Feature.values())
{
if(f.getComp() != null)
{
f.getVariable().setVariable(((JTextField) f.getComp()).getText());
}
}
new Project(jobs.getSelectedValue().split("-")[0].trim(),
jobs.getSelectedValue().split("-")[1].trim(),
features);
return null;
}
}
ProgressMonitor pm = new ProgressMonitor(display, "Testing...", "", 0, 100);
pm.setProgress(0);
Task task = new Task();
task.execute();
}
}
我不确定您的SSCCE,所以我只是发布
JProgressBar
通常如何工作。
了解 SwingWorker 和 JProgressBar
在后台进程中显示进度条。显示了其工作原理的简单示例。
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
public class MyProgressBarTest {
private static final long serialVersionUID = 1L;
private static JProgressBar progressBar;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MyProgressBarTest obj = new MyProgressBarTest();
obj.createGUI();
}
});
}
public void createGUI() {
final JFrame frame = new JFrame();
JPanel panel = new JPanel();
final JButton button = new JButton("Progress");
progressBar = new JProgressBar();
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
MyCustomProgressBarDialog progressBarObj = new MyCustomProgressBarDialog(progressBar, frame);
progressBarObj.createProgressUI();
MyActionPerformer actionObj = new MyActionPerformer(progressBar, progressBarObj, button);
actionObj.execute();
}
});
panel.add(button);
frame.add(panel);
frame.setTitle("JProgressBar Example");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setLocationRelativeTo(null);
frame.setSize(200, 300);
frame.setVisible(true);
}
}
class MyActionPerformer extends SwingWorker<String, Object> {
JProgressBar fProgressBar;
MyCustomProgressBarDialog progressDialog;
JButton button;
public MyActionPerformer(JProgressBar progressBar, MyCustomProgressBarDialog progressDialog, JButton button) {
this.fProgressBar = progressBar;
this.fProgressBar.setVisible(true);
this.fProgressBar.setIndeterminate(true);
this.button = button;
this.progressDialog = progressDialog;
this.button.setEnabled(false);
}
protected String doInBackground() throws Exception {
calculateResult();
return "Finished";
}
protected void done() {
fProgressBar.setVisible(false);
this.progressDialog.setVisible(false);
this.button.setEnabled(true);
}
public void calculateResult() {
for (int i = 0; i < 500000; i++) {
System.out.println("Progress Bar: " + i);
}
}
}
class MyCustomProgressBarDialog extends JDialog {
private static final long serialVersionUID = 1L;
private static JProgressBar progressBar;
private JFrame motherFrame;
private JLabel label = new JLabel("loading.. ");
private JButton button;
public MyCustomProgressBarDialog(JProgressBar progressBar, JFrame frame) {
this.progressBar = progressBar;
this.motherFrame = frame;
this.button = button;
}
public void createProgressUI() {
add(label, BorderLayout.NORTH);
add(progressBar, BorderLayout.CENTER);
setSize(50, 40);
setAlwaysOnTop(true);
setLocationRelativeTo(motherFrame);
setUndecorated(true);
setVisible(true);
}
}
这来自 Oracle javadoc for ProgressMonitor:
最初,没有 ProgressDialog。第一个之后 millisToDecideToPopup 毫秒(默认 500)进度监视器 将预测操作需要多长时间。如果它长于 millisToPopup(默认 2000,2 秒)ProgressDialog 将是 弹出来了。
请注意,创建后至少 1/2 秒才会弹出。即使这样,它也只会在预计该过程需要 2 秒以上的时间时才会弹出。
这一切都基于您对
setProgress(int)
的重复调用以及您给出的范围内值的进展之间的时间。
我怀疑导致对话框弹出的条件不满足。或者,也许您的程序会在该时间过去之前退出。
您需要定义属性
ProgressMonitor pm;
然后应该创建总进度大小
int totalProgress = Feature.values().size();
然后在循环中只需增加计数
int counter = 0;
for(Feature f : Feature.values())
{
if (pm.isCanceled()) {
pm.close();
return null;
}
pm.setProgress(counter);
pm.setNote("Task is " + counter*100/totalProgress + "% completed");
counter++;
调用进度监视器
pm = new ProgressMonitor(display, "Testing...", "", 0, totalProgress);
假设大部分工作是在循环中完成的,如果其他部分(例如项目创建)需要时间,那么您可以向
totalProgress
添加额外的百分比计数或在功能完成后重置监视器。