Java 如何使用动态消息显示忙/工作/加载对话框
我想显示模态对话框,它将阻止我的主窗口,我想通过showLoadingDialog()、hideLoadingDialog()和setLoadingMessage(字符串消息)方法从外部控制它-我尝试了这段代码,但它不起作用-加载对话框可见,但没有消息Java 如何使用动态消息显示忙/工作/加载对话框,java,multithreading,swing,jdialog,Java,Multithreading,Swing,Jdialog,我想显示模态对话框,它将阻止我的主窗口,我想通过showLoadingDialog()、hideLoadingDialog()和setLoadingMessage(字符串消息)方法从外部控制它-我尝试了这段代码,但它不起作用-加载对话框可见,但没有消息 import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.J
import java.awt.GridLayout;
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;
public class LoadingExample {
private static class LoadingDialog extends JDialog {
private JLabel label = new JLabel("working");
public LoadingDialog(JFrame owner) {
super(owner, ModalityType.APPLICATION_MODAL);
setUndecorated(true);
add(label);
pack();
// move window to center of owner
int x = owner.getX()
+ (owner.getWidth() - getPreferredSize().width) / 2;
int y = owner.getY()
+ (owner.getHeight() - getPreferredSize().height) / 2;
setLocation(x, y);
repaint();
}
public void setMessage(String message) {
label.setText(message);
}
}
private static LoadingDialog loadingDialog;
public static void main(String[] args) {
final JFrame mainWindow = new JFrame("Main frame");
mainWindow.setLayout(new GridLayout(3, 3));
for (int i = 1; i <= 9; i++) {
final int workTime = i;
JButton workButton = new JButton("work for " + i + " second");
//action listener, which had to show loading dialog and countdown seconds before finish
workButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showLoadingDialog(mainWindow);
for (int j = 0; j < workTime; j++)
try {
// ... do some work here
setLoadingMessage("remain " + (workTime - j)
+ " second(s)");
loadingDialog.repaint();
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
hideLoadingDialog();
}
});
mainWindow.add(workButton);
}
mainWindow.pack();
mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWindow.setLocationRelativeTo(null);
mainWindow.setVisible(true);
}
public static void showLoadingDialog(JFrame owner) {
if (loadingDialog != null)
loadingDialog.dispose();
loadingDialog = new LoadingDialog(owner);
new Thread() {
@Override
public void run() {
loadingDialog.setVisible(true);
};
}.start();
}
public static void setLoadingMessage(String message) {
loadingDialog.setMessage(message);
}
public static void hideLoadingDialog() {
if (loadingDialog != null) {
loadingDialog.setVisible(false);
loadingDialog.dispose();
loadingDialog = null;
}
}
}
导入java.awt.GridLayout;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入javax.swing.JButton;
导入javax.swing.JDialog;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
公共类加载示例{
私有静态类加载对话框扩展JDialog{
专用JLabel标签=新JLabel(“工作”);
公共加载对话框(JFrame所有者){
super(所有者,ModalityType.APPLICATION\u model);
未装饰的设置(真实);
添加(标签);
包装();
//将窗口移到所有者的中心
intx=owner.getX()
+(owner.getWidth()-getPreferredSize().width)/2;
int y=owner.getY()
+(owner.getHeight()-getPreferredSize().height)/2;
设定位置(x,y);
重新油漆();
}
公共无效设置消息(字符串消息){
label.setText(消息);
}
}
私有静态加载对话框加载对话框;
公共静态void main(字符串[]args){
最终JFrame主窗口=新JFrame(“主框架”);
setLayout(新的GridLayout(3,3));
对于(int i=1;i您不能从与要更改的控件关联的调度程序线程不同的线程更改GUI。要正确执行此操作,您可以使用SwingUtilities.InvokeLater
:
new Thread() {
@Override
public void run() {
SwingUtilities.InvokeLater(new Runnable() {
public void run() {
loadingDialog.setVisible(true);
}
});
};
}.start();
您不能从与要更改的控件关联的调度程序线程之外的其他线程对GUI进行更改。要正确执行此操作,您可以使用SwingUtilities.InvokeLater
:
new Thread() {
@Override
public void run() {
SwingUtilities.InvokeLater(new Runnable() {
public void run() {
loadingDialog.setVisible(true);
}
});
};
}.start();
我想写一些示例代码,但在启动IDE之前,我在“优秀”中做了一个小搜索,它正好包含了您要查找的示例代码。您拥有的是一个。因此,当您有中间结果时,您可以调用SwingWorker#publish
方法。在SwingWorker#流程
方法中,更新t使用您刚刚发布的新消息创建模态对话框。SwingWorker#done
方法允许您在之后删除模态对话框
但我建议您从头到尾阅读整个并发教程,因为您的示例代码表明您缺乏一些基本的Swing线程知识。我想编写一些示例代码,但在启动IDE之前,我在“优秀”中进行了一次小搜索,结果发现,它正好包含您要查找的示例代码。您拥有的是。因此,当您得到中间结果时,您可以调用SwingWorker#publish
方法。在SwingWorker#process
方法中,您可以使用刚刚发布的新消息更新模式对话框。SwingWorker#done
方法允许您在之后删除模式对话框
但是我建议您从头到尾阅读整个并发教程,因为您的示例代码显示您缺乏一些基本的Swing线程知识。“我尝试了这段代码,但它不起作用”-什么不起作用?您可以使用SwingWorker
在后台执行任务,然后更新GUI(即消息和可能的进度条)以反映其进度。如果我理解正确,SwingWorker可以帮助我在后台执行任务,但我想在工作期间阻止ui,因为应用程序的某些其他部分。或者您建议使用SwingWorker显示LoadingDialog?那么这些方法如何显示LoadingDialog(),hideLoadingDialog()和setLoadingMessage(String message)?谢谢:)模态对话框会阻塞UI,那么问题出在哪里?建议使用SwingWorker在后台执行计算,并在EDT上更新模态对话框的状态“我尝试了此代码,但不起作用”-什么不起作用?您可以使用SwingWorker
在后台执行任务,然后更新GUI(即消息和可能的进度条)为了反映它的进度。如果我做对了,请阅读,SwingWorker可以帮助我在后台执行任务,但我想在工作期间阻止ui,因为应用程序的其他部分。或者您建议使用SwingWorker显示LoadingDialog?那么这些方法如何显示showLoadingDialog()、hideLoadingDialog()和setLoadingMessage(字符串消息)?谢谢:)模式对话框会阻塞UI,那么问题出在哪里?建议使用SwingWorker在后台执行计算,并在EDT上更新模式对话框的状态