001package jmri.jmrit.display; 002 003import java.util.Objects; 004import java.util.HashSet; 005import java.util.Set; 006 007import javax.annotation.Nonnull; 008import javax.swing.JCheckBoxMenuItem; 009import javax.swing.JComponent; 010import javax.swing.JMenuItem; 011import javax.swing.JPopupMenu; 012 013import jmri.InstanceManager; 014import jmri.jmrit.logixng.LogixNG; 015import jmri.jmrit.logixng.LogixNG_Manager; 016import jmri.util.ThreadingUtil; 017import jmri.util.swing.JmriMouseEvent; 018 019import org.slf4j.Logger; 020import org.slf4j.LoggerFactory; 021 022/** 023 * 024 * <a href="doc-files/Heirarchy.png"><img src="doc-files/Heirarchy.png" alt="UML class diagram for package" height="33%" width="33%"></a> 025 * @author Howard G. Penny copyright (C) 2005 026 */ 027public class PositionableJComponent extends JComponent implements Positionable { 028 029 protected Editor _editor = null; 030 031 private String _id; // user's Id or null if no Id 032 private final Set<String> _classes = new HashSet<>(); // user's classes 033 034 private ToolTip _tooltip; 035 private boolean _showTooltip = true; 036 private boolean _editable = true; 037 private boolean _positionable = true; 038 private boolean _viewCoordinates = false; 039 private boolean _controlling = true; 040 private boolean _hidden = false; 041 private boolean _emptyHidden = false; 042 private int _displayLevel; 043 private double _scale; // user's scaling factor 044 045 JMenuItem lock = null; 046 JCheckBoxMenuItem showTooltipItem = null; 047 048 private LogixNG _logixNG; 049 private String _logixNG_SystemName; 050 051 public PositionableJComponent(Editor editor) { 052 _editor = editor; 053 _scale = 1.0; 054 } 055 056 @Override 057 public Positionable deepClone() { 058 PositionableJComponent pos = new PositionableJComponent(_editor); 059 return finishClone(pos); 060 } 061 062 protected Positionable finishClone(PositionableJComponent pos) { 063 pos.setLocation(getX(), getY()); 064 pos.setDisplayLevel(getDisplayLevel()); 065 pos.setControlling(isControlling()); 066 pos.setHidden(isHidden()); 067 pos.setPositionable(isPositionable()); 068 pos.setShowToolTip(showToolTip()); 069 pos.setToolTip(getToolTip()); 070 pos.setEditable(isEditable()); 071 pos.updateSize(); 072 return pos; 073 } 074 075 /** {@inheritDoc} */ 076 @Override 077 public void setId(String id) throws Positionable.DuplicateIdException { 078 if (Objects.equals(this._id, id)) return; 079 _editor.positionalIdChange(this, id); 080 this._id = id; 081 } 082 083 /** {@inheritDoc} */ 084 @Override 085 public String getId() { 086 return _id; 087 } 088 089 /** {@inheritDoc} */ 090 @Override 091 public void addClass(String className) { 092 _editor.positionalAddClass(this, className); 093 _classes.add(className); 094 } 095 096 /** {@inheritDoc} */ 097 @Override 098 public void removeClass(String className) { 099 _editor.positionalRemoveClass(this, className); 100 _classes.remove(className); 101 } 102 103 /** {@inheritDoc} */ 104 @Override 105 public void removeAllClasses() { 106 for (String className : _classes) { 107 _editor.positionalRemoveClass(this, className); 108 } 109 _classes.clear(); 110 } 111 112 /** {@inheritDoc} */ 113 @Override 114 public Set<String> getClasses() { 115 return java.util.Collections.unmodifiableSet(_classes); 116 } 117 118 @Override 119 public JComponent getTextComponent() { 120 return this; 121 } 122 123 public void displayState() { 124 } 125 126 // 127 // *************** Positionable methods ********************* 128 // 129 @Override 130 public void setPositionable(boolean enabled) { 131 _positionable = enabled; 132 } 133 134 @Override 135 public boolean isPositionable() { 136 return _positionable; 137 } 138 139 @Override 140 public void setEditable(boolean enabled) { 141 _editable = enabled; 142 showHidden(); 143 } 144 145 @Override 146 public boolean isEditable() { 147 return _editable; 148 } 149 150 @Override 151 public void setViewCoordinates(boolean enabled) { 152 _viewCoordinates = enabled; 153 } 154 155 @Override 156 public boolean getViewCoordinates() { 157 return _viewCoordinates; 158 } 159 160 @Override 161 public void setControlling(boolean enabled) { 162 _controlling = enabled; 163 } 164 165 @Override 166 public boolean isControlling() { 167 return _controlling; 168 } 169 170 @Override 171 public void setHidden(boolean hide) { 172 _hidden = hide; 173 } 174 175 @Override 176 public boolean isHidden() { 177 return _hidden; 178 } 179 180 @Override 181 public void showHidden() { 182 if (!_hidden || _editor.isEditable()) { 183 setVisible(true); 184 } else { 185 setVisible(false); 186 } 187 } 188 189 @Override 190 public void setEmptyHidden(boolean hide) { 191 _emptyHidden = hide; 192 } 193 194 @Override 195 public boolean isEmptyHidden() { 196 return _emptyHidden; 197 } 198 199 @Override 200 public void setValueEditDisabled(boolean isDisabled) { 201 } 202 203 @Override 204 public boolean isValueEditDisabled() { 205 return false; 206 } 207 208 /** 209 * Delayed setDisplayLevel for DnD. 210 * 211 * @param l the new level 212 */ 213 public void setLevel(int l) { 214 _displayLevel = l; 215 } 216 217 @Override 218 public void setDisplayLevel(int l) { 219 int oldDisplayLevel = _displayLevel; 220 _displayLevel = l; 221 if (oldDisplayLevel != l) { 222 log.debug("Changing label display level from {} to {}", oldDisplayLevel, _displayLevel); 223 _editor.displayLevelChange(this); 224 } 225 } 226 227 @Override 228 public int getDisplayLevel() { 229 return _displayLevel; 230 } 231 232 @Override 233 public void setShowToolTip(boolean set) { 234 _showTooltip = set; 235 } 236 237 @Override 238 public boolean showToolTip() { 239 return _showTooltip; 240 } 241 242 @Override 243 public void setToolTip(ToolTip tip) { 244 _tooltip = tip; 245 } 246 247 @Override 248 public ToolTip getToolTip() { 249 return _tooltip; 250 } 251 252 @Override 253 public void setScale(double s) { 254 _scale = s; 255 } 256 257 @Override 258 public double getScale() { 259 return _scale; 260 } 261 262 // no subclasses support rotations (yet) 263 @Override 264 public void rotate(int deg) { 265 } 266 267 @Override 268 public int getDegrees() { 269 return 0; 270 } 271 272 @Override 273 @Nonnull 274 public String getTypeString() { 275 return Bundle.getMessage("PositionableType_PositionableJComponent"); 276 } 277 278 @Override 279 public String getNameString() { 280 return getName(); 281 } 282 283 @Override 284 public Editor getEditor() { 285 return _editor; 286 } 287 288 @Override 289 public void setEditor(Editor ed) { 290 _editor = ed; 291 } 292 293 // overide where used - e.g. momentary 294 @Override 295 public void doMousePressed(JmriMouseEvent event) { 296 } 297 298 @Override 299 public void doMouseReleased(JmriMouseEvent event) { 300 } 301 302 @Override 303 public void doMouseClicked(JmriMouseEvent event) { 304 } 305 306 @Override 307 public void doMouseDragged(JmriMouseEvent event) { 308 } 309 310 @Override 311 public void doMouseMoved(JmriMouseEvent event) { 312 } 313 314 @Override 315 public void doMouseEntered(JmriMouseEvent event) { 316 } 317 318 @Override 319 public void doMouseExited(JmriMouseEvent event) { 320 } 321 322 @Override 323 public boolean storeItem() { 324 return true; 325 } 326 327 @Override 328 public boolean doViemMenu() { 329 return true; 330 } 331 332 @Override 333 public boolean setRotateOrthogonalMenu(JPopupMenu popup) { 334 return false; 335 } 336 337 @Override 338 public boolean setRotateMenu(JPopupMenu popup) { 339 return false; 340 } 341 342 @Override 343 public boolean setScaleMenu(JPopupMenu popup) { 344 return false; 345 } 346 347 @Override 348 public boolean setDisableControlMenu(JPopupMenu popup) { 349 return false; 350 } 351 352 @Override 353 public boolean setTextEditMenu(JPopupMenu popup) { 354 return false; 355 } 356 357 @Override 358 public boolean setEditItemMenu(JPopupMenu popup) { 359 return false; 360 } 361 362 @Override 363 public boolean showPopUp(JPopupMenu popup) { 364 return false; 365 } 366 367 @Override 368 public boolean setEditIconMenu(JPopupMenu popup) { 369 return false; 370 } 371 372 @Override 373 public PositionablePopupUtil getPopupUtility() { 374 return null; 375 } 376 377 @Override 378 public void setPopupUtility(PositionablePopupUtil tu) { 379 } 380 381 @Override 382 public void updateSize() { 383 } 384 385 @Override 386 public int maxWidth() { 387 return getWidth(); 388 } 389 390 @Override 391 public int maxHeight() { 392 return getHeight(); 393 } 394 395 /* 396 ************** end Positionable methods ********************* 397 */ 398 /** 399 * Removes this object from display and persistance 400 */ 401 @Override 402 public void remove() { 403 ThreadingUtil.runOnGUIEventually(() -> _editor.removeFromContents(this) ); 404 cleanup(); 405 // remove from persistance by flagging inactive 406 active = false; 407 } 408 409 /** 410 * To be overridden if any special work needs to be done. 411 */ 412 void cleanup() { 413 } 414 415 boolean active = true; 416 417 /** 418 * Check if the component is still displayed, and should be stored. 419 * 420 * @return true if active; false otherwise 421 */ 422 public boolean isActive() { 423 return active; 424 } 425 426 @Override 427 public jmri.NamedBean getNamedBean() { 428 return null; 429 } 430 431 /** {@inheritDoc} */ 432 @Override 433 public LogixNG getLogixNG() { 434 return _logixNG; 435 } 436 437 /** {@inheritDoc} */ 438 @Override 439 public void setLogixNG(LogixNG logixNG) { 440 this._logixNG = logixNG; 441 } 442 443 /** {@inheritDoc} */ 444 @Override 445 public void setLogixNG_SystemName(String systemName) { 446 this._logixNG_SystemName = systemName; 447 } 448 449 /** {@inheritDoc} */ 450 @Override 451 public void setupLogixNG() { 452 _logixNG = InstanceManager.getDefault(LogixNG_Manager.class) 453 .getBySystemName(_logixNG_SystemName); 454 if (_logixNG == null) { 455 throw new RuntimeException(String.format( 456 "LogixNG %s is not found for positional %s in panel %s", 457 _logixNG_SystemName, getNameString(), getEditor().getName())); 458 } 459 _logixNG.setInlineLogixNG(this); 460 } 461 462 private final static Logger log = LoggerFactory.getLogger(PositionableJComponent.class); 463}