Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как привязать JProgressBar к проходу по ResultSet? 
V
    Опции темы
Данкинг
Дата 11.5.2009, 21:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Yersinia pestis
****


Профиль
Группа: Завсегдатай
Сообщений: 8302
Регистрация: 7.11.2006
Где: მოსკოვი

Репутация: нет
Всего: 130



Есть набор данных, в процессе перебора которого хочу отображать прогресс в JProgressBar. Как сиё осуществить? smile 
Код

JProgressBar gauge=new JProgressBar();
...
 ResultSet rs = st.executeQuery("SELECT * FROM base");
 ...
   rs.beforeFirst();
   while (rs.next())
   {
     gauge.setValue(???? непонятно, какое значение задавать);
     System.out.println(rs.getString("addr"));
   }



--------------------
There's nothing left but silent epitaphs.
PM MAIL WWW   Вверх
Connie
Дата 12.5.2009, 09:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 382
Регистрация: 12.8.2008

Репутация: 8
Всего: 9



Данкинг, проблема, как я понимаю в том, что кол-во отбираемых записей не известно.

Я бы сделал два запроса
Код

select COUNT(какое то уникальное поле) AS counts FROM base;


В результате бы получил таблицу с одной записью, которая покажет сколько будет отбираться всего записей.

Ну а второй уже
Код

ResultSet rs = st.executeQuery("SELECT * FROM base");

PM MAIL WWW   Вверх
frodo5
Дата 12.5.2009, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 17.3.2009

Репутация: нет
Всего: нет



тут не все так просто, gauge.setValue(???? непонятно, какое значение задавать); придется делать в отдельном потоке, если хотите чтобы результат отрисовывался в каждом цикле а не после окончания всех циклов прохода результ сэта
PM MAIL   Вверх
Connie
Дата 12.5.2009, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 382
Регистрация: 12.8.2008

Репутация: 8
Всего: 9



frodo5, ну тогда можно использовать SwingWorker
PM MAIL WWW   Вверх
Данкинг
Дата 12.5.2009, 10:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Yersinia pestis
****


Профиль
Группа: Завсегдатай
Сообщений: 8302
Регистрация: 7.11.2006
Где: მოსკოვი

Репутация: нет
Всего: 130



Цитата(frodo5 @  12.5.2009,  10:59 Найти цитируемый пост)
придется делать в отдельном потоке, если хотите чтобы результат отрисовывался в каждом цикле а не после окончания всех циклов прохода результ сэта 

Вот я про это же. А пример можно? smile 


--------------------
There's nothing left but silent epitaphs.
PM MAIL WWW   Вверх
math64
Дата 12.5.2009, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 5
Всего: 72



Код

thread = new Thread(new Runnable() {
  public void run() {
     ...
     setGaugeValue(value); // Не вызывать слишком часто!
     ...
  }
  private setGaugeValue(final int value) {
     SwingUtilities.invokeLater(new Runnable() {
       public void run() {
         gauge.setValue(value);
       }
     });
  }
});

PM   Вверх
Данкинг
Дата 12.5.2009, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Yersinia pestis
****


Профиль
Группа: Завсегдатай
Сообщений: 8302
Регистрация: 7.11.2006
Где: მოსკოვი

Репутация: нет
Всего: 130



Не работает. smile Вначале выполняется проход по таблице, затем уже изменяются значения прогрессбара:
Код

 while (rs.next()) {
            rr += 1;
            final int value = rr;
            Thread thread=new Thread(new Runnable(){
             public void run(){
             setter(value);
             }
             private void setter(final int value){
              SwingUtilities.invokeLater(new Runnable(){
               public void run(){
                  System.out.println("sddddddddddddddddd");
                   gauge.setValue(value);
              }
              });
             }
            });//thread
                thread.start();
                     System.out.println(rs.getString("addr"));
                 }



--------------------
There's nothing left but silent epitaphs.
PM MAIL WWW   Вверх
math64
Дата 12.5.2009, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 5
Всего: 72



Код

final String sql = "SELECT ...";
Thread thread=new Thread(new Runnable(){
  public void run(){
    ResultSet rs = statement.executeQuery(sql);
    int rr = 0;
    while (rs.next()) {
      rr += 1;
      setter(rr);
    }
  }
  private void setter(final int value){
    SwingUtilities.invokeLater(new Runnable(){
      public void run(){
         System.out.println("sddddddddddddddddd");
         gauge.setValue(value);
      }
    });
  }
});//thread
thread.start();
System.out.println(rs.getString("addr"));


Добавлено через 5 минут и 37 секунд
Нужно добавть обработку икслючений и проверку что предыдущий invokeLater() отработал
PM   Вверх
Данкинг
Дата 12.5.2009, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Yersinia pestis
****


Профиль
Группа: Завсегдатай
Сообщений: 8302
Регистрация: 7.11.2006
Где: მოსკოვი

Репутация: нет
Всего: 130



Ошибка: Invalid Hanlder

Код

final String SQL="SELECT * FROM " + fn;
        final Connection con = DriverManager.getConnection(url);
        final Statement st =
con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
                ResultSet.CONCUR_UPDATABLE);
        
      Thread thread=new Thread(new Runnable(){
        public void run(){
                try {
                    ResultSet rs = st.executeQuery(SQL);
                    rs.last();
                    int reccount = rs.getRow();
                    int rr = 0;
                    gauge.setMinimum(0);
                    gauge.setMaximum(reccount);
                    rs.beforeFirst();
                    while (rs.next()) {
                        rr += 1;
                        final int value = rr;
                        setter(value);
                        System.out.println(rs.getString("addr"));
                    }
                } catch (SQLException ex) {
                   System.out.println(ex.getMessage());
                }
          }
            private void setter(final int value){
              SwingUtilities.invokeLater(new Runnable(){
               public void run(){
                  System.out.println("sddddddddddddddddd");
                   gauge.setValue(value);
              }
              });
             }
            });//thread
                thread.start();
   
           //JOptionPane.showMessageDialog(null, "Готово!!!");

        con.close();
    }

 smile 


--------------------
There's nothing left but silent epitaphs.
PM MAIL WWW   Вверх
Данкинг
Дата 12.5.2009, 22:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Yersinia pestis
****


Профиль
Группа: Завсегдатай
Сообщений: 8302
Регистрация: 7.11.2006
Где: მოსკოვი

Репутация: нет
Всего: 130



В общем, получилось:
Код

 final String fn=filer.getSelectedFile().getName();
   final String pp=filer.getSelectedFile().getPath().replaceAll(fn, "");
   final String url = "jdbc:odbc:Driver={Microsoft dBase Driver (*.dbf)};DBQ="+pp;
   final Connection con = DriverManager.getConnection(url);
   final Statement st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
                                      ResultSet.CONCUR_UPDATABLE);
   final String sql="SELECT * FROM "+fn;
   Thread thread=new Thread(new Runnable(){
   public void run(){
                try {
                    ResultSet rs = st.executeQuery(sql);
                    int rr = 0;
                    rs.last();
                    int reccount=rs.getRow();
                    gauge.setMaximum(reccount);
                    gauge.setMinimum(0);
                    gauge.setValue(0);
                    rs.beforeFirst();
                    while (rs.next()) {
                        rr += 1;
                        System.out.println(rs.getString("addr"));
                        setter(rr);
                    }
                   
                    con.close();
                     JOptionPane.showMessageDialog(null, "Готово!!!");
                } catch (SQLException ex) {
                    Logger.getLogger(proga.class.getName()).log(Level.SEVERE, null, ex);
                }
   }

  /////////////////
   private void setter(final int value){
    SwingUtilities.invokeLater(new Runnable(){
      public void run(){
      ///   System.out.println("sddddddddddddddddd");
         gauge.setValue(value);
      }
    });
  }
   //////////////////////////
});//thread
thread.start(); 

 smile 
И несколько вопросов:
1. Зачем переменные (как в моём примере) объявлять Final, иначе они в потоке не видны?
2. Зачем обновление прогрессбара выносить в отдельный поток? В каких случаях следует делать подобное?
 smile 


--------------------
There's nothing left but silent epitaphs.
PM MAIL WWW   Вверх
math64
Дата 13.5.2009, 08:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 5
Всего: 72



1. Зачем переменные (как в моём примере) объявлять Final, иначе они в потоке не видны?
Некоторые final из твоего примера действительно не нужны, но остальные нужны.
Если у тебя хорошая IDE, примени рефакторинг Convert Anonimous To Inner - нужные final-переменные станут полями вложенного класса, инициализированными в конструкторе. Рефакторинг можешь отменить.
2. Зачем обновление прогрессбара выносить в отдельный поток? В каких случаях следует делать подобное?
Оно не выносится в отдельный поток, с ставятся в очередь в специальный поток Swing, занимающийся перерисовкой.
Если в ResultSet будет много записей, а обрабатывать ты их будешь быстрее, чем Swing будет прорисовывать JProgressBar, ...
Строго говоря,
Код

                    gauge.setMaximum(reccount);
                    gauge.setMinimum(0);
                    gauge.setValue(0);

и
Код

                     JOptionPane.showMessageDialog(null, "Готово!!!");

нужно тоже вызывать через invokeLater()
PM   Вверх
Данкинг
Дата 13.5.2009, 11:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Yersinia pestis
****


Профиль
Группа: Завсегдатай
Сообщений: 8302
Регистрация: 7.11.2006
Где: მოსკოვი

Репутация: нет
Всего: 130



Цитата(math64 @  13.5.2009,  09:00 Найти цитируемый пост)
нужно тоже вызывать через invokeLater() 

Т.е. так же писать для них свои функции с invokeLater() ?


--------------------
There's nothing left but silent epitaphs.
PM MAIL WWW   Вверх
math64
Дата 13.5.2009, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 5
Всего: 72



Цитата(Данкинг @  13.5.2009,  11:07 Найти цитируемый пост)
Т.е. так же писать для них свои функции с invokeLater() ?

Да, по идее для них то же нужно  писать функции с invokeLater, можно использовать один вложенный класс вместо аномимного:
Код

class Invoke implements Runnable {
   private int value;
   private JProgressBar gauge;
   private volatile boolean invoked;
   public Invoke(JProgressBar gauge, int value, int reccount) {
      this.gauge = gauge;
      this.value = value;
      this.reccount = reccount;
      invoked = false;
      SwingUtilities.invokeLater(this);
   }
   public void setValue(int value) {
      this.value = value;
      if (invoked || value == reccount) {
        invoked = false;
        SwingUtilities.invokeLater(this);
      }
   }
   public void run() {
      if (value == 0) {
        gauge.setMaximum(reccount);
        gauge.setMinimum(0);
        gauge.setValue(0);
      } else {
        gauge.setValue(value);
        if (value == reccount) {
          JOptionPane.showMessageDialog(null, "Готово!!!");
        }
      }
      invoked = true;
   }
}

PM   Вверх
Данкинг
Дата 13.5.2009, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Yersinia pestis
****


Профиль
Группа: Завсегдатай
Сообщений: 8302
Регистрация: 7.11.2006
Где: მოსკოვი

Репутация: нет
Всего: 130



math64, спасибо, обещаю разобраться. smile 


--------------------
There's nothing left but silent epitaphs.
PM MAIL WWW   Вверх
math64
Дата 13.5.2009, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 5
Всего: 72



Тут немножко неправльно - showMessageDialog() может быть вызвано несколько раз
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   jk1
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, jk1.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: GUI и Java FX приложения | Следующая тема »


 




[ Время генерации скрипта: 0.0907 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.