/
DefaultSignalHead.java
193 lines (168 loc) · 5.51 KB
/
DefaultSignalHead.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
package jmri.implementation;
import java.util.Arrays;
/**
* Default implementation of the basic logic of the SignalHead interface.
*
* This class only claims support for the Red, Yellow and Green appearances, and
* their corresponding flashing forms. Support for Lunar is deferred to
* DefaultLunarSignalHead or an extended class.
*
* @author Bob Jacobsen Copyright (C) 2001, 2009
*/
public abstract class DefaultSignalHead extends AbstractSignalHead {
public DefaultSignalHead(String systemName, String userName) {
super(systemName, userName);
}
public DefaultSignalHead(String systemName) {
super(systemName);
}
@Override
public void setAppearance(int newAppearance) {
int oldAppearance = mAppearance; // store the current appearance
mAppearance = newAppearance;
appearanceSetsFlashTimer(newAppearance);
/* there are circumstances (admittedly rare) where signals and turnouts can get out of sync
* allow 'newAppearance' to be set to resync these cases - P Cressman
* if (oldAppearance != newAppearance) */
updateOutput();
// notify listeners, if any
firePropertyChange("Appearance", oldAppearance, newAppearance);
}
/**
* Call to set timer when updating the appearance.
*
* @param newAppearance the new appearance
*/
protected void appearanceSetsFlashTimer(int newAppearance) {
if (mLit && ((newAppearance == FLASHGREEN)
|| (newAppearance == FLASHYELLOW)
|| (newAppearance == FLASHRED)
|| (newAppearance == FLASHLUNAR))) {
startFlash();
}
if ((!mLit) || ((newAppearance != FLASHGREEN)
&& (newAppearance != FLASHYELLOW)
&& (newAppearance != FLASHRED)
&& (newAppearance != FLASHLUNAR))) {
stopFlash();
}
}
@Override
public void setLit(boolean newLit) {
boolean oldLit = mLit;
mLit = newLit;
if (oldLit != newLit) {
if (mLit && ((mAppearance == FLASHGREEN)
|| (mAppearance == FLASHYELLOW)
|| (mAppearance == FLASHRED)
|| (mAppearance == FLASHLUNAR))) {
startFlash();
}
if (!mLit) {
stopFlash();
}
updateOutput();
// notify listeners, if any
firePropertyChange("Lit", oldLit, newLit);
}
}
/**
* Set the held parameter.
* <p>
* Note that this does not directly effect the output on the layout; the
* held parameter is a local variable which effects the aspect only via
* higher-level logic.
*
* @param newHeld new Held state, true if Held, to be compared with current
* Held state
*/
@Override
public void setHeld(boolean newHeld) {
boolean oldHeld = mHeld;
mHeld = newHeld;
if (oldHeld != newHeld) {
// notify listeners, if any
firePropertyChange("Held", oldHeld, newHeld);
}
}
/**
* Type-specific routine to handle output to the layout hardware.
* <p>
* Does not notify listeners of changes; that's done elsewhere. Should use
* the following variables to determine what to send:
* <ul>
* <li>mAppearance
* <li>mLit
* <li>mFlashOn
* </ul>
*/
abstract protected void updateOutput();
/**
* Should a flashing signal be on (lit) now?
*/
protected boolean mFlashOn = true;
javax.swing.Timer timer = null;
/**
* On or off time of flashing signal
*/
int delay = 750;
/**
* Start the timer that controls flashing.
*/
protected void startFlash() {
// note that we don't force mFlashOn to be true at the start
// of this; that way a flash in process isn't disturbed.
if (timer == null) {
timer = new javax.swing.Timer(delay, (java.awt.event.ActionEvent e) -> {
timeout();
});
timer.setInitialDelay(delay);
timer.setRepeats(true);
}
timer.start();
}
private void timeout() {
mFlashOn = !mFlashOn;
updateOutput();
}
/*
* Stop the timer that controls flashing.
* <p>
* This is only a resource-saver; the actual use of
* flashing happens elsewhere.
*/
protected void stopFlash() {
if (timer != null) {
timer.stop();
}
mFlashOn = true;
}
final static private int[] VALID_STATES = new int[]{
DARK,
RED,
YELLOW,
GREEN,
FLASHRED,
FLASHYELLOW,
FLASHGREEN,}; // No int for Lunar
final static private String[] VALID_STATE_NAMES = new String[]{
Bundle.getMessage("SignalHeadStateDark"),
Bundle.getMessage("SignalHeadStateRed"),
Bundle.getMessage("SignalHeadStateYellow"),
Bundle.getMessage("SignalHeadStateGreen"),
Bundle.getMessage("SignalHeadStateFlashingRed"),
Bundle.getMessage("SignalHeadStateFlashingYellow"),
Bundle.getMessage("SignalHeadStateFlashingGreen"),}; // Lunar not included
@Override
public int[] getValidStates() {
return Arrays.copyOf(VALID_STATES, VALID_STATES.length);
}
@Override
public String[] getValidStateNames() {
return Arrays.copyOf(VALID_STATE_NAMES, VALID_STATE_NAMES.length);
}
@Override
boolean isTurnoutUsed(jmri.Turnout t) {
return false;
}
}