Использование прогресс бара при длительном процессе, запускаемого со второй секунды ожидания
Ожидает приглашения
Некоторое время назад, столкнулся с одной задачкой, связанной с прогресс баром.
На случай, если кто то столкнется с подобной проблемой, решил выложить одно из возможных решений.
Нужно было сделать progressBar в приложении.
Он должен был появляться, при выполнении определенной задачи больше 2 секунд.
При этом, он должен быть поверх окна пользователя.
Кроме того, заранее неизвестно, сколько времени может занять выполнение задачи.
Графический интерфейс приложения построен на основе Swing, так что, его средства я и использовал.
Если коротко, при запуске процесса, который может долго выполняться, параллельно запускается таймер с задачей показа прогресс бара. В этом таймере можно задать отсрочку до запуска бара.
Сам прогресс бар описывается в отдельном классе, для удобства использования его в различных местах программы.
Все основные моменты прокомментированы в коде.
На случай, если кто то столкнется с подобной проблемой, решил выложить одно из возможных решений.
Описание проблемы
Нужно было сделать 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);
}
}
}