1 /** 2 * The chess framework library. 3 * More information is available at http://www.jinchess.com/. 4 * Copyright (C) 2002 Alexander Maryanovsky. 5 * All rights reserved. 6 * 7 * The chess framework library is free software; you can redistribute 8 * it and/or modify it under the terms of the GNU Lesser General Public License 9 * as published by the Free Software Foundation; either version 2 of the 10 * License, or (at your option) any later version. 11 * 12 * The chess framework library is distributed in the hope that it will 13 * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public License 18 * along with the chess framework library; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 22 package free.chess; 23 24 import javax.swing.JComponent; 25 import javax.swing.Timer; 26 import java.awt.event.ActionListener; 27 import java.awt.event.ActionEvent; 28 29 30 /** 31 * The abstract superclass of all components who display a chess clock (one part 32 * of it). 33 */ 34 35 public abstract class AbstractChessClock extends JComponent{ 36 37 38 39 /** 40 * The code for the mode where only hours and minutes are displayed. 41 */ 42 43 public static final int HOUR_MINUTE_DISPLAY_MODE = 0; 44 45 46 47 /** 48 * The code for the mode where minutes and seconds are displayed. 49 */ 50 51 public static final int MINUTE_SECOND_DISPLAY_MODE = 1; 52 53 54 55 /** 56 * The code for the mode where minutes, seconds and second tenths are 57 * displayed. 58 */ 59 60 public static final int SECOND_TENTHS_DISPLAY_MODE = 2; 61 62 63 64 /** 65 * The code for the mode where the actual display depends on the current time. 66 */ 67 68 public static final int TIME_DEPENDENT_DISPLAY_MODE = 3; 69 70 71 72 /** 73 * The time that was last set on this clock. Note that if the clock is 74 * running, the actual time is calculated by subtracting from this value 75 * the amount of time that has passed since the clock started running. 76 */ 77 78 private int time; 79 80 81 82 /** 83 * The threshold of time under which the clock displays second tenths, when in 84 * <code>TIME_DEPENDENT_DISPLAY_MODE</code> mode. 85 */ 86 87 private int secondTenthsThreshold = 10*1000; 88 89 90 91 /** 92 * The threshold of time under which the clock displays minutes and seconds, 93 * when in <code>TIME_DEPENDENT_DISPLAY_MODE</code> mode. 94 */ 95 96 private int minutesSecondsThreshold = 20*60*1000; 97 98 99 100 /** 101 * The repaint timer. 102 */ 103 104 private final Timer repaintTimer = new Timer(100, new ActionListener(){ 105 public void actionPerformed(ActionEvent evt){ 106 repaint(); 107 } 108 }); 109 110 111 112 /** 113 * The value of the system clock at the time the clock was set to run. 114 * -1 if the clock is not running. 115 */ 116 117 private long runStart = -1; 118 119 120 121 /** 122 * The current display mode of this clock. Possible values are 123 * {@link #HOUR_MINUTE_DISPLAY_MODE}, {@link #MINUTE_SECOND_DISPLAY_MODE) and 124 * {@link #SECOND_TENTHS_DISPLAY_MODE}. 125 */ 126 127 private int displayMode = TIME_DEPENDENT_DISPLAY_MODE; 128 129 130 131 /** 132 * Is the clock currently active (the current turn belongs to the owner of 133 * this clock). 134 */ 135 136 private boolean isActive = false; 137 138 139 140 141 /** 142 * Creates a new <code>AbstractChessClock</code> with the given initial amount 143 * of time (in milliseconds) on it. 144 */ 145 AbstractChessClock(int time)146 public AbstractChessClock(int time){ 147 this.time = time; 148 } 149 150 151 152 153 /** 154 * Sets the time displayed by this clock, in milliseconds. 155 */ 156 setTime(int time)157 public void setTime(int time){ 158 this.time = time; 159 if (isRunning()) 160 runStart = System.currentTimeMillis(); 161 repaint(); 162 } 163 164 165 166 167 /** 168 * Returns the time displayed by this clock, in milliseconds. 169 */ 170 getTime()171 public int getTime(){ 172 if (isRunning()) 173 return time - (int)(System.currentTimeMillis() - runStart); 174 else 175 return time; 176 } 177 178 179 180 /** 181 * Returns whether the clock is running. 182 */ 183 isRunning()184 public boolean isRunning(){ 185 return runStart >= 0; 186 } 187 188 189 190 /** 191 * Sets the clock's running status. 192 */ 193 setRunning(boolean isRunning)194 public void setRunning(boolean isRunning){ 195 if (isRunning == isRunning()) 196 return; 197 198 if (isRunning){ 199 runStart = System.currentTimeMillis(); 200 repaintTimer.start(); 201 } 202 else{ 203 time = time - (int)(System.currentTimeMillis() - runStart); 204 runStart = -1; 205 repaintTimer.stop(); 206 } 207 } 208 209 210 211 /** 212 * Sets the time thresholds under which the clock switches to display 213 * <code>minutes:seconds</code> and <code>minutes:seconds.tenths</code>, when 214 * in <code>TIME_DEPENDENT_DISPLAY_MODE</code> mode. 215 */ 216 setTimeDependentDisplayModeThresholds(int minutesSeconds, int secondTenths)217 public void setTimeDependentDisplayModeThresholds(int minutesSeconds, int secondTenths){ 218 this.minutesSecondsThreshold = minutesSeconds; 219 this.secondTenthsThreshold = secondTenths; 220 221 repaint(); 222 } 223 224 225 226 /** 227 * Sets the delay between repaints of the clock when it is running, in 228 * milliseconds. 229 */ 230 setRepaintDelay(int delay)231 public void setRepaintDelay(int delay){ 232 repaintTimer.setDelay(delay); 233 } 234 235 236 237 /** 238 * Returns the delay between repaints of the clock when it is running, in 239 * milliseconds. 240 */ 241 getRepaintDelay()242 public int getRepaintDelay(){ 243 return repaintTimer.getDelay(); 244 } 245 246 247 248 /** 249 * Sets the display mode of this clock. Possible values are 250 * {@link #HOUR_MINUTE_DISPLAY_MODE}, {@link #MINUTE_SECOND_DISPLAY_MODE) and 251 * {@link #SECOND_TENTHS_DISPLAY_MODE}. Note that concrete implementations may 252 * ignore this setting. 253 */ 254 setDisplayMode(int displayMode)255 public void setDisplayMode(int displayMode){ 256 switch (displayMode){ 257 case HOUR_MINUTE_DISPLAY_MODE: 258 case MINUTE_SECOND_DISPLAY_MODE: 259 case SECOND_TENTHS_DISPLAY_MODE: 260 case TIME_DEPENDENT_DISPLAY_MODE: 261 break; 262 default: 263 throw new IllegalArgumentException("Unrecognized display mode value: " + displayMode); 264 } 265 266 this.displayMode = displayMode; 267 repaint(); 268 } 269 270 271 272 /** 273 * Returns the current display mode of the clock. Possible values are 274 * {@link #HOUR_MINUTE_DISPLAY_MODE}, {@link #MINUTE_SECOND_DISPLAY_MODE}, 275 * {@link #SECOND_TENTHS_DISPLAY_MODE} and 276 * {@link #TIME_DEPENDENT_DISPLAY_MODE}. 277 */ 278 getDisplayMode()279 public int getDisplayMode(){ 280 return displayMode; 281 } 282 283 284 285 /** 286 * Returns the actual display mode. If the display mode is 287 * <code>TIME_DEPENDENT_DISPLAY_MODE</code>, returns one of the other display 288 * modes based on the current time. 289 */ 290 getActualDisplayMode()291 protected int getActualDisplayMode(){ 292 int displayMode = getDisplayMode(); 293 if (displayMode != TIME_DEPENDENT_DISPLAY_MODE) 294 return displayMode; 295 296 int time = Math.abs(getTime()); 297 if (time < secondTenthsThreshold) 298 return SECOND_TENTHS_DISPLAY_MODE; 299 else if (time < minutesSecondsThreshold) 300 return MINUTE_SECOND_DISPLAY_MODE; 301 else 302 return HOUR_MINUTE_DISPLAY_MODE; 303 } 304 305 306 307 /** 308 * Sets the active flag of this clock. The clock should be set to be active 309 * when its owner is also the owner of the current turn. 310 */ 311 setActive(boolean isActive)312 public void setActive(boolean isActive){ 313 this.isActive = isActive; 314 repaint(); 315 } 316 317 318 319 /** 320 * Returns whether this clock is active. 321 */ 322 isActive()323 public boolean isActive(){ 324 return isActive; 325 } 326 327 328 329 } 330