001/* 002 * Copyright 2010-2015 Institut Pasteur. 003 * 004 * This file is part of Icy. 005 * 006 * Icy is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * Icy is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with Icy. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package icy.gui.frame.progress; 020 021import icy.common.listener.ProgressListener; 022import icy.system.thread.ThreadUtil; 023import icy.util.StringUtil; 024 025import java.awt.BorderLayout; 026 027import javax.swing.BorderFactory; 028import javax.swing.JProgressBar; 029 030/** 031 * A progress TaskFrame (thread safe) 032 * 033 * @author fab & stephane 034 */ 035public class ProgressFrame extends TaskFrame implements ProgressListener, Runnable 036{ 037 /** 038 * gui 039 */ 040 JProgressBar progressBar; 041 042 /** 043 * length (in bytes) of download 044 */ 045 protected double length; 046 /** 047 * current position (in bytes) of download 048 */ 049 protected double position; 050 051 /** 052 * current message 053 */ 054 protected String message; 055 /** 056 * current tooltip 057 */ 058 protected String tooltip; 059 060 /** 061 * internals 062 */ 063 // private final SingleProcessor processor; 064 065 public ProgressFrame(final String message) 066 { 067 super(""); 068 069 // default 070 length = 100d; 071 position = -1d; 072 // processor = new SingleProcessor(true); 073 this.message = message; 074 075 ThreadUtil.invokeLater(new Runnable() 076 { 077 @Override 078 public void run() 079 { 080 progressBar = new JProgressBar(); 081 progressBar.setString(buildMessage(message)); 082 progressBar.setStringPainted(true); 083 progressBar.setIndeterminate(true); 084 progressBar.setBorder(BorderFactory.createEmptyBorder()); 085 progressBar.setMinimum(0); 086 // this is enough for a smooth progress 087 progressBar.setMaximum(1000); 088 089 mainPanel.setLayout(new BorderLayout()); 090 mainPanel.add(progressBar, BorderLayout.CENTER); 091 092 pack(); 093 } 094 }); 095 } 096 097 protected String buildMessage(String message) 098 { 099 return " " + message + " "; 100 } 101 102 @Override 103 public void run() 104 { 105 // don't spent too much time in EDT 106 ThreadUtil.sleep(10); 107 updateDisplay(); 108 } 109 110 public void refresh() 111 { 112 // refresh (need single delayed execution) 113 ThreadUtil.runSingle(this); 114 } 115 116 protected void updateDisplay() 117 { 118 // repacking need to be done on EDT 119 ThreadUtil.invokeNow(new Runnable() 120 { 121 @Override 122 public void run() 123 { 124 // position information 125 if ((position != -1d) && (length > 0d)) 126 { 127 // remove indeterminate state 128 if (progressBar.isIndeterminate()) 129 progressBar.setIndeterminate(false); 130 131 // set progress 132 final int value = (int) (position * 1000d / length); 133 if (progressBar.getValue() != value) 134 progressBar.setValue(value); 135 } 136 else 137 { 138 // set indeterminate state 139 if (!progressBar.isIndeterminate()) 140 progressBar.setIndeterminate(true); 141 } 142 143 final String text = buildMessage(message); 144 145 // set progress message 146 if (!StringUtil.equals(progressBar.getString(), text)) 147 { 148 progressBar.setString(text); 149 // so component is resized according to its string length 150 progressBar.invalidate(); 151 152 // repack frame 153 pack(); 154 } 155 156 // set tooltip 157 if (!StringUtil.equals(progressBar.getToolTipText(), tooltip)) 158 progressBar.setToolTipText(tooltip); 159 } 160 }); 161 } 162 163 public String getMessage() 164 { 165 return message; 166 } 167 168 public void setMessage(String value) 169 { 170 if (message != value) 171 { 172 message = value; 173 refresh(); 174 } 175 } 176 177 // we want tooltip set on the progress component only 178 @Override 179 public void setToolTipText(String value) 180 { 181 if (tooltip != value) 182 { 183 tooltip = value; 184 refresh(); 185 } 186 } 187 188 /** 189 * @return the length 190 */ 191 public double getLength() 192 { 193 return length; 194 } 195 196 /** 197 * @param value 198 * the length to set 199 */ 200 public void setLength(double value) 201 { 202 if (length != value) 203 { 204 length = value; 205 refresh(); 206 } 207 } 208 209 /** 210 * @return the position 211 */ 212 public double getPosition() 213 { 214 return position; 215 } 216 217 /** 218 * increment progress position 219 */ 220 public void incPosition() 221 { 222 setPosition(position + 1); 223 } 224 225 /** 226 * @param value 227 * the position to set 228 */ 229 public void setPosition(double value) 230 { 231 if (position != value) 232 { 233 position = value; 234 refresh(); 235 } 236 } 237 238 /** 239 * @deprecated use {@link #setPosition(double)} instead 240 */ 241 @Deprecated 242 public void setProgress(int value) 243 { 244 setPosition(value); 245 } 246 247 @Override 248 public boolean notifyProgress(double position, double length) 249 { 250 setPosition(position); 251 setLength(length); 252 253 return true; 254 } 255 256}