JDialog在程序和用户操作时创建的不同行为

时间:2013-07-24 10:45:52

标签: java multithreading swing jdialog jprogressbar

我有3个clasess:Loader,MyDialog和TEST(使用main方法)。 (代码见下文)

我想要实现的一切都是使用JLabel和JProgressBar创建简单的对话框,它将通知用户显示MyDialog需要多长时间。 MyDialog是Jdialog,在构造函数中运行耗时(从数据库加载数据等)。

下面的代码是模型情况。当“MyDialog”由main创建时(常量BY_USER为false),一切正常工作我想要的。但是当我使用按钮进行对话时,按下按钮后创建MyDialog实例(常量BY_USER为真),Loader为空白表格。看起来似乎没有完成。

Loader正在扩展Thread,所以我想问题将出现在线程中(事件调度线程)?我不知道,有什么问题以及如何解决它。请帮忙。

谢谢,对不起我的英语。

CLASS TEST:

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);
}
}

CLASS Loader:

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;
}

1 个答案:

答案 0 :(得分:0)

了解SwingWorker及其用途;我认为它可以帮助您解决问题。