Progress Monitor不会出现在Java Swing中

时间:2015-03-13 21:49:06

标签: java multithreading swing jpanel progressmonitor

我正在创建一个简单的用户界面,用户可以单击按钮来运行特定的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

1 个答案:

答案 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