4

(Java SE 6) プログラムが時間のかかる作業を行っている間、「しばらくお待ちください」というメッセージを表示するポップアップ ダイアログを作成しようとしています。これを行うために、モードレス JDialog を使用することを選択しました。これにより、JDialog が表示されている間もプログラムが実行され続け、機能します (モーダル ダイアローグを使用すると、ユーザーがダイアログを閉じるまでプログラムは停止します)。 .

問題は、この方法でモードレス ダイアログを使用すると、タイトル付きの JDialog が表示されますが、内容が表示されないことです (何らかの理由で描画されないと思います)。repaint などを呼び出してみましたが、何も機能していないようです。

さて、インターウェブ上の多くの人々によると、これは Swing の本物のバグであり、私が見つけた唯一の答えは、この方法で物事を行わず、ユーザーに待機するように通知する別の方法を見つけることです。ここにいる誰かが以前にこの問題を抱えていて、回避策を見つけたことがあるかどうか興味があります.

ありがとう!

4

4 に答える 4

5

これはバグではありません。重いジョブと軽いスイング ジョブを、メイン スレッドの隣のセプレッド スレッドで実行する必要があります。これは、ダイアログ GUI スレッドとその ActionListenerEvents の間のバックラウンドでの重いジョブとの関係の論理的な影響のために必要です。メインスレッドを分離しないと、いくつかの通知イベントのために Swing ドローが決定されます。私は同じ問題を抱えていました.JFrameから開始したFTP Upload Progressの進行状況を監視して、JDialogに表示しようとしました。

最初に試しました:

//Activated by Upload Button
public void actionPerformed(ActionEvent e) {

    if("Upload".equals(e.getActionCommand())){

    // some Declarations

    new Thread(){

        public void run() {
            /*Run JDialog with the Upload - ProgressBar*/
            FileUploadProgressBar fileUploadProgressBar = new FileUploadProgressBar(localFile, remoteFile, ftpPersistence);
        }
    }.start();

/*Run the heavy weigth Job - the Upload*/
ftpPersistence.uploadFile(localFile, remoteFile);

// ...
    }

//...

}

しかし、この方法で JDialog FrameBorder と balck コンテンツ ペインを取得できますが ...

次の試行:

//Activated by Upload Button
public void actionPerformed(ActionEvent e) {

    if("Upload".equals(e.getActionCommand())){

    // some Declarations

    new Thread(){

        public void run() {
        /*Run JDialog with the Upload - ProgressBar*/
        FileUploadProgressBar fileUploadProgressBar = new FileUploadProgressBar(localFile, remoteFile, ftpPersistence);
    }
}.start();


new Thread(){

    public void run() 
            /*Run the heavy weigth Job - the Upload*/
            ftpPersistence.uploadFile(localFile, remoteFile);
        }
    }.start();
    // ... 
    }
//...
}

そしてついにそれはうまくいきました、それが助けになることを願っています;)

于 2012-12-13T12:14:02.977 に答える
4

別の方法として、この例SwingWorkerで提案されているように、暫定的な進捗状況を使用して表示することを検討してください。

于 2011-03-19T12:50:39.787 に答える
2

私はこれを使用していますが、動作します-元のコード(実行時に再描画するために見つけた修正なし)はここからです: http://inversionconsulting.blogspot.com/2008/03/java-jdialog-and-jprogressbar- example.html

しかし、私はそれを(わずかな変更を加えて)次のように統合しました:

JProgressBar pb = new JProgressBar(0,100);

pb.setPreferredSize(new Dimension(275,30));
pb.setString("Running");
pb.setStringPainted(true);
pb.setValue(0);

JLabel label = new JLabel("Progress: ");
JPanel center_panel = new JPanel();

center_panel.add(label);
center_panel.add(pb);

JDialog dialog = new JDialog((JFrame)null, "Working ...");

dialog.getContentPane().add(center_panel, BorderLayout.CENTER);
dialog.pack();
dialog.setVisible(true);
dialog.setLocationRelativeTo(null); // center on screen

後のコードでは、ループを実行しているときに (変数 'tot' を使用して 1 から 10 になる)、ダイアログを再描画し、プログラムがループを実行するときに進行状況バーを更新します。上記のページ リンク) (私は複数のスレッドを使用していません。これはすべてメイン スレッドにあります):

//set progress bar
pb.setValue(tot*10);
//repaint it
dialog.getContentPane().paintAll(pb.getGraphics());

この解決策を見つけるには、多くの時間と試行錯誤が必要でした。私と同じように、あなたにとってもうまくいくことを願っています。

于 2011-05-28T23:25:22.807 に答える
0

validate()を試しましたか (コンポーネントをコンテナに追加した後に必要です) ? また、ソース コードを投稿して、確認できるようにすることも検討してください。幸運を。

于 2011-03-19T13:03:06.940 に答える