2

ここに表示する非常に単純なコードを作成しました。進行状況を確認するために JDialog を表示するボタンがあります。invoke late を使用して EDT を通過していますが、ループは run メソッドにありません。私のバーは更新されていませんか?ここにコードがあります

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class JBarEx extends JFrame {
private JTextField progStatus = new JTextField("Undefined");
private JButton dialogBtn = new JButton("Show Progression dialog");
final JDialog dlg = new JDialog((JFrame) null, "prog Title", false);
final JProgressBar dpb = new JProgressBar(0, 100);

public JBarEx() {
    JPanel pan = new JPanel();
    dialogBtn.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            showProgress();
        }
    });
    progStatus.setEditable(false);
    pan.add(progStatus);
    pan.add(dialogBtn);
    setContentPane(pan);
    this.setSize(200, 100);
    setVisible(true);
}

public void showProgress() {
    dlg.add(BorderLayout.CENTER, dpb);
    dlg.add(BorderLayout.NORTH, new JLabel("prog message"));
    dlg.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
    dlg.setSize(300, 75);
    dlg.setLocationRelativeTo(null);
    dlg.setVisible(true);

    for (int i = 0; i < 100; i++) {
        final int ii = i;
        try {
            Thread.sleep(25);
            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    updateBar(ii);

                }
            });
        }
        catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

public void updateBar(int newValue) {
    dpb.setValue(newValue);
}

public static void main(String[] args) {
    JBarEx jbx = new JBarEx();
}

}

4

3 に答える 3

1

他の人が指摘したようにループを修正しても、イベント ディスパッチ スレッドはブロックされます。イベントリスナーから呼び出されるループforが実行されます。showProgress()更新はイベント キューにプッシュされますが、ループが完了するまで処理されません。

代わりにスイングタイマーを使用してください。このようなもの:

Timer timer = new Timer(25, new ActionListener() {
    private int position;

    @Override
    public void actionPerformed(ActionEvent e) {
         position++;
         if (position < lastPosition) {
             updateBar(position);
         } else {
             ((Timer) e.getSource).stop();
         }
    }
});
timer.start();

lastPositionプログレスバーを停止させたい状態はどこになりますか。

そのバグとは関係ありませんが、それでもバグですが、イベント ディスパッチ スレッドの外部でスイング コンポーネントを作成しないでください。最初からすぐに実行するのが最善です。

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            JBarEx jbx = new JBarEx();
        }
    });
}
于 2013-09-16T19:43:05.530 に答える
0
for (int i = 0; i < 0; i++) {

このコードを入力することはないため、 updateBar(..) メソッドを呼び出すことはありません

この場合、 iは 0 より大きい必要があります。1 の場合、updateBar は 1 回呼び出され、2 の場合、updateBar は 2 回呼び出されます。

また、するのではなく

Thread.sleep(25);

これらはスケジューリングに役立ち、スリープの必要性を取り除くので、Javaエグゼキュータを見てください

于 2013-09-16T19:35:08.073 に答える