Java 新线程JDialog中的JProgressBar
我想在新的JDialog中创建JProgressBar,它将与主逻辑在单独的线程中。因此,我可以从创建新的JDialog开始不确定的过程,并通过处理JDialog完成该过程。但是我很难做到这一点,因为在JDialog出现之后,在主线程(SwingUtilities)中的逻辑完成之前,它不会显示任何组件(包括JProgressBar) 线程包括JDialog:Java 新线程JDialog中的JProgressBar,java,multithreading,swing,concurrency,jprogressbar,Java,Multithreading,Swing,Concurrency,Jprogressbar,我想在新的JDialog中创建JProgressBar,它将与主逻辑在单独的线程中。因此,我可以从创建新的JDialog开始不确定的过程,并通过处理JDialog完成该过程。但是我很难做到这一点,因为在JDialog出现之后,在主线程(SwingUtilities)中的逻辑完成之前,它不会显示任何组件(包括JProgressBar) 线程包括JDialog: package gui.progress; public class ProgressThread extends Thread {
package gui.progress;
public class ProgressThread extends Thread {
private ProgressBar progressBar = null;
public ProgressThread() {
super();
}
@Override
public void run() {
progressBar = new ProgressBar(null);
progressBar.setVisible(true);
}
public void stopThread() {
progressBar.dispose();
}
}
JProgressBar切换方法:
private static ProgressThread progressThread = null;
...
public static void toggleProcessBar() {
if(progressThread == null) {
progressThread = new ProgressThread();
progressThread.start();
} else {
progressThread.stopThread();
progressThread = null;
}
}
在主线程中显示进度条(所有swing工作都在这里进行),并在单独的线程上进行密集的后台工作
UI将始终响应(因为您不阻止主线程),并且您可以在长时间运行的任务完成时通知它。在主线程中显示进度条(所有swing工作都在这里进行),并在单独的线程上执行密集的后台工作 UI将一直响应(因为您不阻止主线程),并且您可以在长时间运行的任务完成时通知它 但是我很难做到这一点,因为在JDialog出现之后,在主线程(SwingUtilities)中的逻辑完成之前,它不会显示任何组件(包括JProgressBar) 您有问题,Swing是单线程的,所有更新都必须在上完成,有两种方法
- 易于使用
,但到Swing GUI的输出必须打包到Runnable#Thread
invokeLater
- 例如,关于
的示例在Oracles和教程中SwingWorker
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
public class TestProgressBar {
private static void createAndShowUI() {
JFrame frame = new JFrame("TestProgressBar");
frame.getContentPane().add(new TestPBGui().getMainPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowUI();
}
});
}
private TestProgressBar() {
}
}
class TestPBGui {
private JPanel mainPanel = new JPanel();
public TestPBGui() {
JButton yourAttempt = new JButton("Your attempt to show Progress Bar");
JButton myAttempt = new JButton("My attempt to show Progress Bar");
yourAttempt.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
yourAttemptActionPerformed();
}
});
myAttempt.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myAttemptActionPerformed();
}
});
mainPanel.add(yourAttempt);
mainPanel.add(myAttempt);
}
private void yourAttemptActionPerformed() {
Window thisWin = SwingUtilities.getWindowAncestor(mainPanel);
JDialog progressDialog = new JDialog(thisWin, "Uploading...");
JPanel contentPane = new JPanel();
contentPane.setPreferredSize(new Dimension(300, 100));
JProgressBar bar = new JProgressBar(0, 100);
bar.setIndeterminate(true);
contentPane.add(bar);
progressDialog.setContentPane(contentPane);
progressDialog.pack();
progressDialog.setLocationRelativeTo(null);
Task task = new Task("Your attempt");
task.execute();
progressDialog.setVisible(true);
while (!task.isDone()) {
}
progressDialog.dispose();
}
private void myAttemptActionPerformed() {
Window thisWin = SwingUtilities.getWindowAncestor(mainPanel);
final JDialog progressDialog = new JDialog(thisWin, "Uploading...");
JPanel contentPane = new JPanel();
contentPane.setPreferredSize(new Dimension(300, 100));
final JProgressBar bar = new JProgressBar(0, 100);
bar.setIndeterminate(true);
contentPane.add(bar);
progressDialog.setContentPane(contentPane);
progressDialog.pack();
progressDialog.setLocationRelativeTo(null);
final Task task = new Task("My attempt");
task.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equalsIgnoreCase("progress")) {
int progress = task.getProgress();
if (progress == 0) {
bar.setIndeterminate(true);
} else {
bar.setIndeterminate(false);
bar.setValue(progress);
progressDialog.dispose();
}
}
}
});
task.execute();
progressDialog.setVisible(true);
}
public JPanel getMainPanel() {
return mainPanel;
}
}
class Task extends SwingWorker<Void, Void> {
private static final long SLEEP_TIME = 4000;
private String text;
public Task(String text) {
this.text = text;
}
@Override
public Void doInBackground() {
setProgress(0);
try {
Thread.sleep(SLEEP_TIME);// imitate a long-running task
} catch (InterruptedException e) {
}
setProgress(100);
return null;
}
@Override
public void done() {
System.out.println(text + " is done");
Toolkit.getDefaultToolkit().beep();
}
}
导入java.awt.Dimension;
导入java.awt.Toolkit;
导入java.awt.Window;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.beans.PropertyChangeEvent;
导入java.beans.PropertyChangeListener;
导入javax.swing.*;
公共类TestProgressBar{
私有静态void createAndShowUI(){
JFrame frame=新JFrame(“TestProgressBar”);
frame.getContentPane().add(新的TestPBGui().getMainPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
公共静态void main(字符串[]args){
invokeLater(new Runnable()){
@凌驾
公开募捐{
createAndShowUI();
}
});
}
私有TestProgressBar(){
}
}
类TestPBGui{
private JPanel mainPanel=new JPanel();
公共TestPBGui(){
JButton yourtiment=新JButton(“您显示进度条的尝试”);
JButton mytrunt=新JButton(“我尝试显示进度条”);
addActionListener(新建ActionListener()){
@凌驾
已执行的公共无效操作(操作事件e){
yourAttemptActionPerformed();
}
});
mytrunt.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
myAttemptActionPerformed();
}
});
添加(您的尝试);
mainPanel.add(我的尝试);
}
private void yourAttemptActionPerformed(){
windowthiswin=SwingUtilities.getWindowSenator(主面板);
JDialog progressDialog=新建JDialog(thisWin,“上载…”);
JPanel contentPane=新的JPanel();
setPreferredSize(新维度(300100));
JProgressBar=新的JProgressBar(0100);
bar.setUndeterminate(真);
contentPane.add(条);
progressDialog.setContentPane(contentPane);
progressDialog.pack();
progressDialog.setLocationRelativeTo(空);
任务=新任务(“您的尝试”);
task.execute();
progressDialog.setVisible(true);
而(!task.isDone()){
}
progressDialog.dispose();
}
私有void myAttemptActionPerformed(){
windowthiswin=SwingUtilities.getWindowSenator(主面板);
final JDialog progressDialog=新建JDialog(thisWin,“上载…”);
JPanel contentPane=新的JPanel();
setPreferredSize(新维度(300100));
最终JProgressBar=新的JProgressBar(0,100);
bar.setUndeterminate(真);
contentPane.add(条);
progressDialog.setContentPane(contentPane);
progressDialog.pack();
progressDialog.setLocationRelativeTo(空);
最终任务=新任务(“我的尝试”);
task.addPropertyChangeListener(新的PropertyChangeListener(){
@凌驾
公共作废属性更改(属性更改事件evt){
if(evt.getPropertyName().equalsIgnoreCase(“进度”)){
int progress=task.getProgress();
如果(进度==0){
bar.setUndeterminate(真);
}否则{
bar.setUndeterminate(假);
设置值(进度);
progressDialog.dispose();
}
}
}
});
task.execute();
progressDialog.setVisible(true);
}
公共JPanel getMainPanel(){
返回主面板;
}
}
类任务扩展SwingWorker{
私人静态最终长睡眠时间=4000;
私有字符串文本;
公共任务(字符串文本){
this.text=文本;
}
@凌驾
公共无效doInBackground(){
setProgress(0);
试一试{
Thread.sleep(sleep_TIME);//模拟长时间运行的任务
}捕捉(中断异常e){
}
进度(100);
返回null;
}
@凌驾
公众假期结束(){
System.out.println(text+“已完成”);