Увеличение индикатора выполнения на 1 каждую сотую секунды - PullRequest
1 голос
/ 07 апреля 2010

Я пытаюсь увеличить JProgressBar на 1 каждую сотую секунды, и сейчас я использую Thread.sleep(100) внутри оператора while, например:

    try {
         while (i<=100){
            doTime();

         }
    } catch (InterruptedException ex) {
        Logger.getLogger(SplashScreen.class.getName()).log(Level.SEVERE, null, ex);
    }

public void doTime() throws InterruptedException{


        jLabel1.setText("sleeping");
        Thread.sleep(100);
        jLabel1.setText("start");
        i++;
        pb.setValue(i);
        pb.repaint();

}

и если я выполняю отладку с помощью System.out.println, он отображается в режиме реального времени, но графический интерфейс Swing зависает до тех пор, пока он не выпадает из цикла while. Может ли кто-нибудь помочь?

Ответы [ 4 ]

5 голосов
/ 07 апреля 2010

Как сказал деривация, вы должны использовать SwingWorker . Из своего javadoc:

"SwingWorker предназначен для ситуаций, когда вам нужно запустить долгосрочную задачу в фоновом потоке и предоставлять обновления пользовательского интерфейса либо по завершении, либо во время обработки. Подклассы SwingWorker должны реализовывать doInBackground () метод для выполнения фонового вычисления. "

С этим небольшим изменением ProgressBarDemo.java в руководстве по Java вы почти получаете то, что хотите.

    public Void doInBackground() {
        Random random = new Random();
        int progress = 0;
        //Initialize progress property.
        setProgress(0);
        while (progress < 100) {
            //Sleep for up to one second.
            try {
                //original code: Thread.sleep(random.nextInt(1000));
                Thread.sleep(10);
            } catch (InterruptedException ignore) {}
            //Make random progress.
            //originalcode: progress += random.nextInt(10);
            progress++;
            setProgress(Math.min(progress, 100));
        }
        return null;
    }
2 голосов
/ 07 апреля 2010

Проблема в том, что вы спите в потоке событий Swing. Вы захотите создать новый поток для запуска цикла, а затем обновить этот цикл выполнения в потоке событий колебания.

Я бы использовал рабочий поток Swing для цикла. Затем используйте invokeLater для обновления индикатора выполнения.

Еще один хороший учебник по качели / нити .

1 голос
/ 07 апреля 2010

Если doTime() вызывается в потоке диспетчеризации событий (EDT), что следует, так как он вызывает код пользовательского интерфейса (jLabel1.setText() и другие), то он должен не вызывать sleep() совсем. Вы не хотите заморозить свой пользовательский интерфейс.

Правильный способ сделать это - использовать таймер , чтобы проснуться в правильные моменты (скажем, каждые 10 мс) и обновлять прогресс. Код Jala также является хорошим ответом и является официальным Swing Way для ведения дел (таймеры более низкого уровня, чем SwingWorkers).

1 голос
/ 07 апреля 2010

Помимо того, что сказал деривация, вы спите в течение 100 миллисекунд. Это означает, что вы обновляете только каждую десятую секунды, а не каждую сотую. ​​

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...