Вопрос по java, swing, timer, sleep, progress-bar – Как использовать Swing Timer для задержки загрузки индикатора выполнения

1

Мне нужно найти способ использовать Swing Timer с индикатором выполнения. Я попытался с помощью Thread.sleep (), но приложение зависло при его использовании. Есть ли способы использовать таймер качания вместо сна ()?

public void piiEros(int dist)
{
    Pii pii = new Pii();
    pii.setVisible(true);
    for(int pc = 0;100 > pc; pc++)
    {
        try {
            Thread.sleep(dist/100);
        } catch (InterruptedException ex) {
            Logger.getLogger(Trav.class.getName()).log(Level.SEVERE, null, ex);
        }
        pii.pg.setValue(pc);
    }
    pii.dispose();
    o.Eros();
}

ЗАМЕЧАНИЯ: Pii - это класс с Progress Bar. Dist - скорость, с которой он загружается. Trav - это класс, в котором находится метод. Pc означает%, сколько сделано, отображается на панели. О. Эрос открывает другой графический интерфейс.

Извините за код, пробелы просто удаляются. РЕДАКТИРОВАТЬ: Eng Фуад исправил отступы, спасибо! Matthew
Не спать на EDT! Кстати, когда дело доходит до индикатора выполнения, используйте SwingWorker. Branislav Lazic
Наверное, лучше использовать SwingWorker MadProgrammer
Вот более читаемый код:dropbox.com/s/402vcqi3ah4kcbn/ST%20PG.JPG Matthew

Ваш Ответ

2   ответа
2

Вы можете изменить свойpiiEros метод таким образом:

public void piiEros(int dist)
{
    final Pii pii = new Pii();
    pii.setVisible(true);
    javax.swing.Timer  timer = new javax.swing.Timer(dist/100, new ActionListener()
    {
      public void actionPerformed(ActionEvent evt)
      {
        pii.pg.setValue(pg.getValue()++);
        if ( pii.pg.getValue() > 100 )
        {
          timer.stop();
          pii.dispose();
          o.Eros();
        }
      }
    });
    timer.setInitialDelay(0);
    timer.setRepeats(true);
    timer.start();
}
(Не нужно звонитьsetDelay, вы'мы уже установлены в конструкторе;)) MadProgrammer
Да, мне нравится быть уверенным;) MadProgrammer
IDE не делаетМне нравится, что javax.swing.Timer вызывается в методе, и я всегда добавляю имя объекта, который я хочу создать раньше, поэтому теперь это выглядит так: Timer timer = new Timer (dist / 100, new ActionListener () Matthew
@MadProgrammer: Особо предупредительный характер .. lol ..;) Vishal K
Мог'не понимаю твою точку зрения. ты имеешь в виду, что твоя IDE жалуется, когда видит?javax.swing.Timer Vishal K
4

Возможно, проще (в конечном итоге) использоватьSwingWorker, Он предоставляет ряд полезных методов для обновления пользовательского интерфейса (из контекста потока диспетчеризации событий), позволяя при этом продолжить выполнение в фоновом режиме ...

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestSwingWorker02 {

    public static void main(String[] args) {
        new TestSwingWorker02();
    }

    public TestSwingWorker02() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridBagLayout());
            JProgressBar pb = new JProgressBar();
            add(pb);

            new ProgressWorker(pb, 40).execute();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

    public class ProgressWorker extends SwingWorker<void, integer=""> {

        private int delay;
        private JProgressBar pb;

        public ProgressWorker(JProgressBar progressBar, int delay) {
            this.pb = progressBar;
            this.delay = delay;
        }

        @Override
        protected void process(List<integer> chunks) {
            // Back in the EDT...
            pb.setValue(chunks.get(chunks.size() - 1)); // only care about the last one...
        }

        @Override
        protected Void doInBackground() throws Exception {
            for (int index = 0; index < 100; index++) {
                publish(index);
                Thread.sleep(delay);
            }
            return null;
        }

        @Override
        protected void done() {
            // Back in the EDT...
            //pii.dispose();
            //o.Eros();
        }

    }

}
</integer></void,>

SwingWorker позволяет отделить логику. вdoInBackground метод, который вы можете сосредоточиться на той части кода, которая должна работать за пределами EDT, вы можетеpublish обновления обратно в EDT иprocess их отдельно. Когда это'всеdone вы можете убирать по мере необходимости.

SwingWorker также предоставляет функции мониторинга прогресса, так что в вашем случае это ненужно использовать /publishprocess часть API, если вы нене хочу Это позволит вам прикрепитьPropertyChangeListener работнику без необходимости выставлять ему индикатор выполнения. (Но я сделал для примера)

public class ProgressWorker extends SwingWorker<void, integer=""> {

    private int delay;
    private JProgressBar pb;

    public ProgressWorker(JProgressBar progressBar, int delay) {
        this.pb = progressBar;
        this.delay = delay;
        // You can use a property change listener to monitor progress updates...
        addPropertyChangeListener(new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                if ("progress".equalsIgnoreCase(evt.getPropertyName())) {
                    pb.setValue((Integer)evt.getNewValue());
                }
            }

        });
    }

    @Override
    protected Void doInBackground() throws Exception {
        for (int index = 0; index < 100; index++) {
            setProgress(index);
            Thread.sleep(delay);
        }
        return null;
    }

    @Override
    protected void done() {
        // Back in the EDT...
        //pii.dispose();
        //o.Eros();
    }

}
</void,>
Лично я нахожу это чище и легче следовать (но ям просто так) MadProgrammer
+1 за современный и чистый ответ ..;). Но неВы думаете, что для такой маленькой задачиSwingWorker довольно большой. Vishal K
Понятно .. Программистсвой вкус ..;) Vishal K

Похожие вопросы