我正在创建一个简单的用户界面,用户可以单击按钮来运行特定的Java类。单击后,应该向用户显示任务的进度,并为任务运行时的任何时间点提供用户终止任务的“取消”按钮。
在这种情况下,当用户在UI中单击JButton时,我将使用ProgressMonitor显示,其中将调用包含可运行线程的runEngineerBuild()来执行另一个Java类的方法(称为EngineerBuild.java) )。但是,不显示ProgressMonitor对话框。如何显示ProgressDialog?我想知道是否是因为多个运行线程的性质或者我错过了某些东西。真的很感谢你的帮助!
在SecondPanel.java中:
package mainApplication;
import java.awt.Font;
public class SecondPanel extends JPanel {
private MainApplication ma = null; // main JFrame
private JPanel pnlBtn;
private JPanel pnlProgress;
private JButton btnRunAll;
private JButton btnEngBuild;
private JButton btnWholeDoc;
private JButton btnCancelProgress;
private JLabel lblTitleSteps;
private JLabel lblAlt;
private JLabel lbl_1a;
private JLabel lbl_1b_c;
private JLabel lblTitleStatus;
private JProgressBar progressRunAll;
private JProgressBar progressEngBuild;
private JProgressBar progressWholeDoc;
private Property property = Property.getInstance();
// private Task task;
private boolean cancelFlag;
/**
* Create the panel for Step 1 TabbedPane.
*/
public SecondPanel(MainApplication mainApp) {
// TODO Auto-generated constructor stub
super();
ma = mainApp;
}
public SecondPanel() {
this.setBackground(new Color(224, 255, 255));
this.setBounds(0, 0, 745, 1350);
this.setPreferredSize(new Dimension(745, 600));
this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
pnlBtn = new JPanel();
pnlBtn.setLayout(new BoxLayout(pnlBtn, BoxLayout.PAGE_AXIS));
pnlBtn.setAlignmentY(Component.TOP_ALIGNMENT);
pnlProgress = new JPanel();
pnlProgress.setLayout(new BoxLayout(pnlProgress, BoxLayout.PAGE_AXIS));
pnlProgress.setAlignmentY(TOP_ALIGNMENT);
pnlBtn.add(Box.createRigidArea(new Dimension(0, 15)));
btnEngBuild = new JButton("Run EngineerBuild.java");
btnEngBuild.setToolTipText("Build search engineer");
btnEngBuild.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
// start activity
activity = new SimulatedActivity(1000);
activity.start();
// launch progress dialog
progressDialog = new ProgressMonitor(ma,
"Waiting for Simulated Activity", null, 0, activity
.getTarget());
progressDialog.setMillisToPopup(1000);
// start timer
activityMonitor = new Timer(500, null);
activityMonitor.start();
btnEngBuild.setEnabled(false);
}
});
activityMonitor = new Timer(500, new ActionListener() {
private PrintStream textArea;
public void actionPerformed(ActionEvent event) {
int current = activity.getCurrent();
// show progress
runEngineerBuild();
textArea.append(current + "\n");
progressDialog.setProgress(current);
// check if task is completed or canceled
if (current == activity.getTarget() || progressDialog.isCanceled()) {
activityMonitor.stop();
progressDialog.close();
activity.interrupt();
btnEngBuild.setEnabled(true);
}
}
});
btnEngBuild.setMinimumSize(new Dimension(200, 30));
btnEngBuild.setPreferredSize(new Dimension(200, 30));
btnEngBuild.setMaximumSize(new Dimension(200, 30));
pnlBtn.add(btnEngBuild);
pnlBtn.add(Box.createRigidArea(new Dimension(0, 15)));
// components in panel progress
lblTitleStatus = new JLabel();
lblTitleStatus.setText("<html><u>Task Status</u></html>");
progressEngBuild = new JProgressBar();
Border border2 = BorderFactory.createTitledBorder("Run EngineerBuild");
progressEngBuild.setBorder(border2);
// title
pnlProgress.add(lblTitleStatus);
pnlProgress.add(Box.createRigidArea(new Dimension(0, 15)));
pnlProgress.add(progressEngBuild);
pnlProgress.add(Box.createRigidArea(new Dimension(0, 15)));
this.add(Box.createRigidArea(new Dimension(15, 10)));
this.add(pnlBtn);
this.add(Box.createRigidArea(new Dimension(50, 10)));
this.add(pnlProgress);
}
public void runEngineerBuild()
{
EngineerBuildRunnable ebr = new EngineerBuildRunnable();
ebr.run();
}
private class EngineerBuildRunnable implements Runnable {
EngineerBuild eb;
public EngineerBuildRunnable() {
eb = new EngineerBuild();
}
public void run() {
eb.initial();
eb.storeIntoFile();
}
}
private Timer activityMonitor;
private ProgressMonitor progressDialog;
private SimulatedActivity activity;
public static final int WIDTH = 300;
public static final int HEIGHT = 200;
}
/**
* A simulated activity thread.
*/
class SimulatedActivity extends Thread {
/**
* Constructs the simulated activity thread object. The thread increments a
* counter from 0 to a given target.
*
* @param t
* the target value of the counter.
*/
public SimulatedActivity(int t) {
current = 0;
target = t;
}
public int getTarget() {
return target;
}
public int getCurrent() {
return current;
}
public void run() {
try {
while (current < target && !interrupted()) {
sleep(100);
current++;
}
} catch (InterruptedException e) {
}
}
private int current;
private int target;
}
以下是您感兴趣的原始ProgressMonitor代码的链接:
User Interface Programming - Example 1-11 ProgressMonitorTest.java
答案 0 :(得分:2)
很有可能,调用runEngineerBuild()
将调用长时间运行的代码,这是您在Swing事件线程中执行的操作,这将占用线程,使您的GUI无用并冻结,直到那么久 - 运行代码已完成运行。解决方案与所有类似问题相同 - 在后台线程(如SwingWorker)中调用runEngineerBuild()
。
快速解决方法是在一个简单的线程中显式调用runEngineerBuild()
:
EngineerBuildRunnable ebr = new EngineerBuildRunnable();
new Thread(ebr).start();
// ebr.run(); // !!! don't call a Runnable's run method directly !!!!
有关如何使用SwingWorker的详细信息,请查看:Lesson: Concurrency in Swing。