001package jmri.jmrit.etcs.dmi.swing; 002 003import java.beans.PropertyChangeListener; 004 005import jmri.util.TimerUtil; 006 007import org.apiguardian.api.API; 008 009/** 010 * Class to provide a Timer to ensure all flashing DMI Icons flash in unison. 011 * @author Steve Young Copyright (C) 2024 012 */ 013@API(status=API.Status.EXPERIMENTAL) 014public class DmiFlashTimer { 015 016 private final DmiPanel panel; 017 018 private static final String PROP_CHANGE_SLOW_FLASH = "SlowFlash"; 019 private static final String PROP_CHANGE_FAST_FLASH = "FastFlash"; 020 021 private boolean fastFlashOn = false; 022 private boolean slowFlashOn = false; 023 private boolean disposed = false; 024 025 private java.util.TimerTask flashTimer; 026 027 protected DmiFlashTimer(DmiPanel mainPanel) { 028 panel = mainPanel; 029 } 030 031 protected void addFlashListener( PropertyChangeListener pcl, boolean fast ) { 032 log.debug("add pcl {}", pcl); 033 panel.addPropertyChangeListener( 034 ( fast ? PROP_CHANGE_FAST_FLASH : PROP_CHANGE_SLOW_FLASH), pcl); 035 ensureRunning(); 036 } 037 038 protected void removeFlashListener ( PropertyChangeListener pcl, boolean fast ) { 039 040 log.debug("remove pcl {} num listeners {}", pcl, 041 panel.getPropertyChangeListeners(PROP_CHANGE_FAST_FLASH).length + 042 panel.getPropertyChangeListeners(PROP_CHANGE_SLOW_FLASH).length 043 044 ); 045 046 panel.removePropertyChangeListener(( fast ? PROP_CHANGE_FAST_FLASH : PROP_CHANGE_SLOW_FLASH), pcl); 047 048 049 log.debug("remove pcl {} num listeners {}", pcl, 050 panel.getPropertyChangeListeners(PROP_CHANGE_FAST_FLASH).length + 051 panel.getPropertyChangeListeners(PROP_CHANGE_SLOW_FLASH).length 052 053 ); 054 055 if ( panel.getPropertyChangeListeners(PROP_CHANGE_FAST_FLASH).length + 056 panel.getPropertyChangeListeners(PROP_CHANGE_SLOW_FLASH).length == 0 ) { 057 dispose(); 058 } 059 060 } 061 062 private void ensureRunning(){ 063 log.debug("ensureRunning"); 064 disposed = false; 065 if (flashTimer==null) { 066 flashTimer = new java.util.TimerTask(){ 067 @Override 068 public void run() { 069 if ( !disposed ) { 070 triggerFastFlash(); 071 TimerUtil.scheduleOnGUIThread(flashTimer, 250); 072 } 073 } 074 }; 075 TimerUtil.scheduleOnGUIThread(flashTimer, 250); 076 } 077 } 078 079 private void triggerFastFlash(){ 080 fastFlashOn = !fastFlashOn; 081 log.debug("fast flash {}", fastFlashOn ); 082 panel.firePropertyChange(PROP_CHANGE_FAST_FLASH, !fastFlashOn, fastFlashOn); 083 if (!fastFlashOn) { 084 triggerSlowFlash(); 085 } 086 } 087 088 private void triggerSlowFlash(){ 089 slowFlashOn = !slowFlashOn; 090 log.debug("slow flash {}", slowFlashOn ); 091 panel.firePropertyChange(PROP_CHANGE_SLOW_FLASH, !slowFlashOn, slowFlashOn); 092 } 093 094 protected void dispose(){ 095 log.debug("dispose"); 096 disposed = true; 097 if ( flashTimer != null ) { 098 flashTimer.cancel(); 099 flashTimer = null; 100 } 101 } 102 103 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DmiFlashTimer.class); 104 105}