我有 3 个类:Loader、MyDialog 和 TEST(使用 main 方法)。(代码见下文)
我想要实现的一切都是使用 JLabel 和 JProgressBar 创建简单的对话框,它会通知用户还有多少时间来显示 MyDialog。MyDialog 是 Jdialog,在构造函数中具有耗时的操作(从数据库加载数据等)。
在下面的代码中是模型情况。当 main 创建“MyDialog”(常量 BY_USER 为 false)时,一切都在我想要的状态下正常工作。但是当我用 button 进行对话框,并且在按下按钮后创建 MyDialog 的实例(常量 BY_USER 为真)时,Loader 是空白的白色形式。好像没有完成。
加载器正在扩展线程,所以我想问题出在线程(事件调度线程)中?我不知道,出了什么问题以及如何解决。请帮忙。
谢谢和对不起我的英语。
类测试:
package test;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class TEST {
public static final boolean BY_USER = false;
public static void main(String[] args) {
if (BY_USER) {
JFrame mainDialog = new JFrame("Main");
JButton show = new JButton("Show MyDialog");
show.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
MyDialog dialog = new MyDialog();
}
});
mainDialog.add(show);
mainDialog.setLocationRelativeTo(null);
mainDialog.setMinimumSize(new Dimension(160, 80));
mainDialog.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
mainDialog.setVisible(true);
} else {
MyDialog dialog = new MyDialog();
}
}
}
CLASS MyDialog : 封装测试;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class MyDialog extends JFrame{
public MyDialog() {
super();
// making loader with title, first message and count of steps of operation
Loader loader = new Loader("Loader", "First showed message", 100);
loader.ShowLoader();
// time-consuming operation (loading data from database etc.).
// for clarity replaced with for statement
int j=0;
for(int i=0; i<Integer.MAX_VALUE; i++)
{
j++;
if(j==Integer.MAX_VALUE/100){
// updating loader message and progress bar value
loader.NewAction(Integer.MAX_VALUE - i+"");
j=0;
}
}
// closing loader
loader.DestroyLoader();
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setSize(300, 300);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
}
类加载器:
package test;
import java.awt.BorderLayout;
import java.awt.Dialog;
import java.awt.Dimension;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingConstants;
public class Loader extends Thread{
private JDialog dialog;
private JLabel message = new JLabel("", SwingConstants.CENTER);
private JProgressBar progressBar = new JProgressBar(0, 100);
private String newMessage;
private double percentForStep;
private int remainingSteps;
public Loader(String taskName, String firstMessage, int steps) {
this.remainingSteps = steps-1;
dialog = new JDialog((Dialog) null, taskName);
dialog.setLayout(new BorderLayout(15, 15));
dialog.add(message, BorderLayout.CENTER);
dialog.add(progressBar, BorderLayout.SOUTH);
message.setText(firstMessage);
percentForStep = 100 / steps;
}
public void ShowLoader()
{
dialog.setMinimumSize(new Dimension(400,120));
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
this.start();
}
public void DestroyLoader(){
dialog.dispose();
this.interrupt();
}
public void NewAction(String newMessage){
this.newMessage = newMessage;
this.remainingSteps--;
Lock.changed = true;
}
public int RemainingStepsCount()
{
return remainingSteps;
}
@Override
@SuppressWarnings({"CallToThreadYield", "SleepWhileInLoop"})
public void run() {
do{
synchronized (Lock.class) {
if (Lock.changed) {
Lock.changed = false;
this.message.setText(newMessage);
this.progressBar.setValue((int)(100-(remainingSteps*percentForStep)));
dialog.repaint();
}
dialog.repaint();
}
}while(true);
}
}
class Lock{
static boolean changed = false;
}