001package jmri.jmrit.symbolicprog; 002 003import java.awt.Color; 004import java.beans.PropertyChangeListener; 005import java.beans.PropertyChangeSupport; 006 007/** 008 * Represents a single CV or Variable value. 009 * Defines common base class methods for CvValue and VariableValue classes 010 * <p> 011 * The ToRead parameter (boolean, unbound) is used to remember whether this 012 * object has been read during a "read all" operation. This allows removal of 013 * duplicate operations. 014 * <p> 015 * The ToWrite parameter (boolean, unbound) is used to remember whether this 016 * object has been written during a "write all" operation. This allows removal 017 * of duplicate operations. 018 * <p> 019 * The Available parameter (boolean, unbound) remembers whether the variable 020 * should be displayed, programmed, etc. 021 * <p> 022 * Variables and CVs track their states, as shown below.<br> 023 * <a href="doc-files/VariableStates.png"><img src="doc-files/VariableStates.png" alt="States for variables and their colors" height="33%" width="33%"></a> 024 * 025 * 026 * @author Bob Jacobsen Copyright (C) 2001, 2005, 2026 027 */ 028public abstract class AbstractValue { 029 030 PropertyChangeSupport prop = new PropertyChangeSupport(this); 031 032 /** 033 * Method to handle color changes for states. 034 * 035 * @param c the desired colour 036 */ 037 abstract void setColor(Color c); 038 039 /** 040 * States, hence colors, of Variables and CVs. 041 * 042 * Note that these as written and read by name in LocoFiles in the roster. 043 * Do not change the name of these values without putting a migration scheme 044 * in place. 045 */ 046 public enum ValueState { 047 /** 048 * Defines state when nothing is known about the real value. 049 */ 050 UNKNOWN(Color.red.brighter(), "Unknown"), 051 052 /** 053 * Defines state where value has been edited, no longer same as in decoder 054 * or file. 055 */ 056 EDITED(Color.orange, "Edited"), 057 058 /** 059 * Defines state where value has been read from (hence same as) decoder, but 060 * perhaps not same as in file. 061 */ 062 READ(null, "Read"), 063 064 /** 065 * Defines state where value has been written to (hence same as) decoder, 066 * but perhaps not same as in file. 067 */ 068 STORED(null, "Stored"), 069 070 /** 071 * Defines state where value was read from a config file, but might not be 072 * the same as the decoder. It is known to have been edited/read/written 073 * at some point. 074 */ 075 FROMFILE(Color.yellow, "FromFile"), 076 077 /** 078 * Defines state where value was read from a config file, but might not be 079 * the same as the decoder. It's unknown whether the item has been edited/read/written 080 * at some point. 081 */ 082 FROMFILEUNKNOWN(Color.yellow, "FromFileUnknown"), 083 084 /** 085 * Defines state where value was defined by the decoder definition default, 086 * and has never been edited or read from or written to the decoder. 087 */ 088 FROMDEFAULT(Color.yellow, "FromDefault"), // ice blue 0xF0F8FF 089 090 /** 091 * Defines state where value was read from a config file, and is the same as 092 * the decoder. 093 */ 094 SAME(null, "Same"), 095 096 /** 097 * Defines state where value was read from a config file, and is the not the 098 * same as the decoder. 099 */ 100 DIFFERENT(Color.red.brighter(), "Different"); 101 102 103 private final Color _color; 104 private final String _name; 105 106 private ValueState(Color color, String name) { 107 this._color = color; 108 this._name = name; 109 } 110 111 /** 112 * Gets the color associated with this state value. 113 * @return the color assigned to this state value or null if 114 * to use default for the component 115 */ 116 public Color getColor() { 117 return _color; 118 } 119 120 /** 121 * Gets the name associated with this state value. 122 * @return the name assigned to this state value 123 */ 124 public String getName() { 125 return _name; 126 } 127 } 128 129 /** 130 * Mark whether this object needs to be read. 131 * 132 * @param state true if the object needs to be read, false otherwise 133 * @see AbstractValue 134 */ 135 public void setToRead(boolean state) { 136 _toRead = state; 137 } 138 139 /** 140 * Ask whether this object needs to be read. 141 * 142 * @return true if the object needs to be read, false otherwise 143 * @see AbstractValue 144 */ 145 public boolean isToRead() { 146 return _toRead; 147 } 148 private boolean _toRead = false; 149 150 /** 151 * Mark whether this object needs to be written. 152 * 153 * @param state true if the object needs to be written, false otherwise 154 * @see AbstractValue 155 */ 156 public void setToWrite(boolean state) { 157 _toWrite = state; 158 } 159 160 /** 161 * Ask whether this object needs to be written. 162 * 163 * @return true if the object needs to be written, false otherwise 164 * @see AbstractValue 165 */ 166 public boolean isToWrite() { 167 return _toWrite; 168 } 169 private boolean _toWrite = false; 170 171 /** 172 * Sets the availability status of the object. 173 * 174 * @param avail {@code true} if the object should be made available, 175 * {@code false} if should be made unavailable 176 */ 177 public void setAvailable(boolean avail) { 178 boolean oldval = this.available; 179 available = avail; 180 if (oldval != available) { 181 prop.firePropertyChange("Available", Boolean.valueOf(oldval), Boolean.valueOf(avail)); 182 } 183 } 184 185 /** 186 * Gets the current availability status of the object. 187 * <p> 188 * Code can use this to determine whether to set object visibility (or other 189 * properties). 190 * 191 * @return {@code true} if the object should be available, {@code false} if 192 * it should be unavailable 193 */ 194 public boolean getAvailable() { 195 return available; 196 } 197 private boolean available = true; 198 199 /** 200 * @param p the listener to be added to the object 201 */ 202 public void addPropertyChangeListener(PropertyChangeListener p) { 203 prop.addPropertyChangeListener(p); 204 } 205 206 /** 207 * @param p the listener to be removed from the object 208 */ 209 public void removePropertyChangeListener(PropertyChangeListener p) { 210 prop.removePropertyChangeListener(p); 211 } 212}