Как стать автором
Обновить

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

Некоторое время назад, столкнулся с одной задачкой, связанной с прогресс баром.
На случай, если кто то столкнется с подобной проблемой, решил выложить одно из возможных решений.

Описание проблемы


Нужно было сделать progressBar в приложении.
Он должен был появляться, при выполнении определенной задачи больше 2 секунд.
При этом, он должен быть поверх окна пользователя.
Кроме того, заранее неизвестно, сколько времени может занять выполнение задачи.
Графический интерфейс приложения построен на основе Swing, так что, его средства я и использовал.

Описание решения


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

Фрагмент класса, с вызовом прогресс-бара

final ProgressDialog progress = new ProgressDialog();
java.util.Timer timer = new java.util.Timer();
final TimerTask task = new TimerTask() {
  public void run() {
    progress.showDialog();
  }
  };
  // Задаем время, через которое должен включиться progressBar,
  // Если задача еще не выполнена
  timer.schedule( task, 2000 );
  Thread someThread = new Thread(new Runnable(){
    public void run() {
      // Тут идет обработка.
      SwingUtilities.invokeLater(new Runnable(){
	public void run() {
	task.cancel();
	progress.closeDialog();
      }
    });
  }
});
someThread.start(); 


Класс, содержащий в себе прогресс-бар

public class ProgressDialog {
  private final JFrame frame = new JFrame();
  private final JDialog dialog = new JDialog(frame, "Выполнение задачи", false);
  private final JProgressBar progressBar = new JProgressBar();
  /** Конструктор progreeBar и диалога, в котором он содержится */
  public ProgressDialog(){
	frame.setUndecorated(true);
    // Если мы не знаем, сколько времени займет операция, 
    // делаем progressBar в виде "катающегося объекта", а не "ползунка".
    progressBar.setIndeterminate(true);
    // При желании, задаем цвет.
    progressBar.setForeground( new Color(210,105,030));
    // При желании, задаем конкретную форму. В данном случае, progressBar имеет форму мячика,
    // которая описывается в классе ProgressUI.
    progressBar.setUI(new ProgressUI());
    // Убираем рамку из диалога, чтобы был виден только progressBar без кнопок управления окном.
    dialog.setUndecorated(true);
    // добавляем получившийся progressBar в диалог.
    dialog.getContentPane().add(progressBar);
    dialog.pack();
    dialog.setDefaultCloseOperation(0);
    // Задаем центровку диалога.
    Toolkit kit = dialog.getToolkit();
    GraphicsEnvironment ge = GraphicsEnvironment. getLocalGraphicsEnvironment();
    GraphicsDevice[] gs = ge.getScreenDevices();
    Insets in = kit.getScreenInsets(gs[0].getDefaultConfiguration());
    Dimension d = kit.getScreenSize();
    int max_width = (d.width - in.left - in.right);
    int max_height = (d.height - in.top - in.bottom);
    dialog.setLocation((int) (max_width - dialog.getWidth()) / 2, (int) (max_height - dialog.getHeight() ) / 2);
    // Отображаем диалог и progressBar
    dialog.setVisible(true);
    progressBar.setVisible(true);
    dialog.setAlwaysOnTop(true);
  }
  /** Метод, отображающий диалог */
  public void showDialog(){
    dialog.setVisible(true);
    dialog.setAlwaysOnTop(true);
  }
  /** Метод, закрывающий диалог */
  public void closeDialog(){
    if (dialog.isVisible()){
      dialog.getContentPane().remove(progressBar);
      dialog.getContentPane().validate();
      dialog.setVisible(false);
    }
  }
  /** Класс, задающий внешний вид progressBar */
  public static class ProgressUI extends BasicProgressBarUI {
    private Rectangle r = new Rectangle();
    protected void paintIndeterminate(Graphics g, JComponent c) {
      Graphics2D g2d = (Graphics2D) g;
      g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      r = getBox(r);
      g.setColor(progressBar.getForeground());
      g.fillOval(r.x, r.y, r.height, r.height);
    }
  }
}
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.