package com.osmand.swing; import java.awt.BorderLayout; import java.awt.Component; import java.lang.reflect.InvocationTargetException; import javax.swing.BorderFactory; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JProgressBar; import com.osmand.IProgress; public class ProgressDialog extends JDialog implements IProgress { private static final long serialVersionUID = -3915486672514402269L; private JProgressBar progressBar; private JLabel label; private Runnable run; private InvocationTargetException exception = null; private Object result; private boolean finished; // Progress variables private static final float deltaToChange = 0.01f; private String taskName; private int deltaWork; public ProgressDialog(Component parent, Runnable run){ this(parent); this.run = run; } public ProgressDialog(Component parent){ super(JOptionPane.getFrameForComponent(parent), true); initDialog(); } public Object run() throws InvocationTargetException, InterruptedException { finished = false; result = null; new WorkerThread().start(); synchronized (this) { if(!finished){ setVisible(true); } } if(exception != null){ throw exception; } return result; } private class WorkerThread extends Thread { @Override public void run() { try { if(run != null){ run.run(); } } catch(RuntimeException e){ exception = new InvocationTargetException(e); } finally { synchronized (this) { finished = true; setVisible(false); } } } } private void initDialog() { JPanel pane = new JPanel(new BorderLayout()); pane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); progressBar = new JProgressBar(); pane.add(progressBar, BorderLayout.SOUTH); label = new JLabel(); pane.add(label, BorderLayout.CENTER); add(pane); label.setText("Please waiting..."); progressBar.setIndeterminate(true); setSize(550, 100); } public Object getResult() { return result; } public void setResult(Object result) { this.result = result; } public void setRunnable(Runnable run) { this.run = run; } @Override public void progress(int deltaWork) { this.deltaWork += deltaWork; if(change(progressBar.getValue() + deltaWork)){ progressBar.setValue(progressBar.getValue() + deltaWork); updateMessage(); } } private void updateMessage() { if(!progressBar.isIndeterminate()){ label.setText(taskName + String.format("\t%.1f %%", progressBar.getValue() * 100f / ((float) progressBar.getMaximum()))); } } public boolean change(int newProgress) { if (newProgress < progressBar.getValue()) { return false; } if ((newProgress - progressBar.getValue()) / ((float) progressBar.getMaximum()) < deltaToChange) { return false; } return true; } @Override public void remaining(int remainingWork) { if(change(progressBar.getMaximum() - remainingWork)){ progressBar.setValue(progressBar.getMaximum() - remainingWork); updateMessage(); } deltaWork = progressBar.getMaximum() - remainingWork - this.progressBar.getValue(); } public boolean isIndeterminate(){ return progressBar.isIndeterminate(); } @Override public void startTask(String taskName, int work) { if(taskName == null){ taskName = ""; } label.setText(taskName); this.taskName = taskName; startWork(work); } @Override public void finishTask() { if (taskName != null) { label.setText(taskName); } progressBar.setIndeterminate(true); } @Override public void startWork(int work) { if(work == 0){ work = 1; } if(work != -1){ progressBar.setMinimum(0); progressBar.setMaximum(work); progressBar.setValue(0); progressBar.setIndeterminate(false); } else { progressBar.setIndeterminate(true); } deltaWork = 0; } }