Pull to refresh

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

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

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


Нужно было сделать 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);
    }
  }
}
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.