1

私は3つのクラスを持っています:ローダー、MyDialog、およびTEST(メインメソッド付き)。(コードについては以下を参照)

私が達成したいのは、JLabel と JProgressBar を使用して簡単なダイアログを作成することです。これにより、MyDialog を表示する残り時間をユーザーに通知します。MyDialog は、コンストラクターでの時間のかかる操作 (データベースからのデータのロードなど) を伴う Jdialog です。

以下のコードはモデルの状況です。「MyDialog」がメインによって作成されると(定数BY_USERがfalse)、すべてが正確に機能します。しかし、ボタンでダイアログを作成し、ボタンを押した後に MyDialog のインスタンスが作成されると (定数 BY_USER が true)、ローダーは空白の白いフォームになります。未完成のようです。

Loader は Thread を拡張しているので、問題はスレッド化 (イベント ディスパッチ スレッド) にあるのでしょうか? 何が間違っていて、どのように修正するのかわかりません。助けてください。

私の英語に感謝し、申し訳ありません。

クラステスト:

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

1 に答える 1

0

SwingWorker とその使い方に注目してください。問題を解決するのに役立つと思います。

于 2013-07-24T11:01:59.110 に答える