001package jmri.jmrit.display; 002 003import java.awt.Color; 004import java.awt.Container; 005import java.awt.Dimension; 006import java.awt.Font; 007import java.awt.Point; 008import java.awt.Rectangle; 009import java.util.Set; 010 011import javax.swing.JComponent; 012import javax.swing.JPopupMenu; 013import javax.swing.border.Border; 014 015import jmri.JmriException; 016import jmri.NamedBean; 017import jmri.jmrit.logixng.InlineLogixNG; 018import jmri.util.swing.JmriMouseEvent; 019 020/** 021 * Defines display objects. 022 * <p> 023 * These are capable of: 024 * <ul> 025 * <li>Being positioned by being dragged around on the screen. (See 026 * {@link #setPositionable}) 027 * <li>Being hidden. (See {@link #setHidden}) 028 * <li>Controlling the layout. (See {@link #setControlling}) 029 * </ul><p> 030 * These are manipulated externally, for example by a subclass of 031 * {@link Editor}. They are generally not stored directly as part of the state 032 * of the object, though they could be, but as part of the state of the external 033 * control. 034 * <p> 035 * Instead of the usual MouseEvent handling methods, e.g mouseClicked(...), 036 * Positionables have similar methods called doMouseClicked invoked by the 037 * {@link Editor} subclass that contains them, so the Editor can handle e.g. box 038 * selection, etc. 039 * 040 * <a href="doc-files/Heirarchy.png"><img src="doc-files/Heirarchy.png" alt="UML class diagram for package" height="33%" width="33%"></a> 041 * @see PositionableJComponent 042 * @see PositionableLabel 043 * @author Bob Jacobsen Copyright (c) 2002 044 * @author Pete Cressman Copyright (c) 2010 045 */ 046public interface Positionable extends Cloneable, InlineLogixNG { 047 048 /** 049 * Sets the Id of this Positionable 050 * @param id the id or null if no id 051 * @throws jmri.jmrit.display.Positionable.DuplicateIdException if another 052 * Positionable in the editor already has this id 053 */ 054 void setId(String id) throws Positionable.DuplicateIdException; 055 056 /** 057 * Gets the Id of this Positionable 058 * @return the id or null if no id 059 */ 060 String getId(); 061 062 /** 063 * Add a class name to this Positionable 064 * @param className the class name 065 * @throws IllegalArgumentException className is null or has a comma 066 */ 067 public void addClass(String className); 068 069 /** 070 * Remove a class name to this Positionable 071 * @param className the class name 072 */ 073 public void removeClass(String className); 074 075 /** 076 * Remove a class name to this Positionable 077 */ 078 public void removeAllClasses(); 079 080 /** 081 * Gets the class names of this Positionable 082 * @return the classes 083 */ 084 Set<String> getClasses(); 085 086 void setPositionable(boolean enabled); 087 088 boolean isPositionable(); 089 090 void setEditable(boolean enabled); 091 092 boolean isEditable(); 093 094 void setShowToolTip(boolean set); 095 096 boolean showToolTip(); 097 098 void setToolTip(ToolTip tip); 099 100 ToolTip getToolTip(); 101 102 void setViewCoordinates(boolean enabled); 103 104 boolean getViewCoordinates(); 105 106 void setControlling(boolean enabled); 107 108 boolean isControlling(); 109 110 void setHidden(boolean enabled); 111 112 boolean isHidden(); 113 114 void showHidden(); 115 116 void setEmptyHidden(boolean enabled); 117 118 boolean isEmptyHidden(); 119 120 int getDisplayLevel(); 121 122 void setDisplayLevel(int l); 123 124 Editor getEditor(); 125 126 void setEditor(Editor ed); 127 128 void updateSize(); 129 130 int maxWidth(); 131 132 int maxHeight(); 133 134 /** 135 * Make a deep copy of Positional object. Implementation should create a new 136 * object and immediately pass the object to finishClone() returning the 137 * result of finishClone(). i.e. implementation must be: 138 * <p> 139 * {@code public Positionable deepClone() { Subtype t = new Subtype(); return finishClone(t); 140 * } } 141 * <p> 142 * Then finishClone() finishes the deep Copy of a Positional object. 143 * Implementation should make deep copies of the additional members of this 144 * sub class and then pass Positionable p to super.finishClone(). i.e. 145 * implementation must terminate with statement return super.finishClone(p); 146 * See IndicatorTurnoutIcon extends TurnoutIcon extends PositionableLabel 147 * for an example of how to continue deep cloning a chain of subclasses. 148 * 149 * @return the copy 150 */ 151 Positionable deepClone(); 152 153 /** 154 * Get the type of the positional as a String. 155 * 156 * @return the type to display 157 */ 158 String getTypeString(); 159 160 /** 161 * Get the name of the positional as a String. This is often the display 162 * name of the NamedBean being positioned. 163 * 164 * @return the name to display 165 */ 166 @Override 167 String getNameString(); 168 169 /** 170 * {@inheritDoc} 171 */ 172 @Override 173 public default String getTypeName() { 174 NamedBean nb = getNamedBean(); 175 return nb != null ? nb.getBeanType() : null; 176 } 177 178 /** 179 * Add additional menu items to the menu. 180 * 181 * @param popup the menu to add the menu items to 182 * @return true if adding items; false otherwise 183 */ 184 boolean setRotateOrthogonalMenu(JPopupMenu popup); 185 186 /** 187 * Add additional menu items to the menu. 188 * 189 * @param popup the menu to add the menu items to 190 * @return true if adding items; false otherwise 191 */ 192 boolean setRotateMenu(JPopupMenu popup); 193 194 /** 195 * Add additional menu items to the menu. 196 * 197 * @param popup the menu to add the menu items to 198 * @return true if adding items; false otherwise 199 */ 200 boolean setScaleMenu(JPopupMenu popup); 201 202 /** 203 * Add additional menu items to the menu. 204 * 205 * @param popup the menu to add the menu items to 206 * @return true if adding items; false otherwise 207 */ 208 boolean setEditIconMenu(JPopupMenu popup); 209 210 /** 211 * Add additional menu items to the menu. 212 * 213 * @param popup the menu to add the menu items to 214 * @return true if adding items; false otherwise 215 */ 216 boolean setEditItemMenu(JPopupMenu popup); 217 218 /** 219 * Add additional menu items to the menu. 220 * 221 * @param popup the menu to add the menu items to 222 * @return true if adding items; false otherwise 223 */ 224 boolean setDisableControlMenu(JPopupMenu popup); 225 226 /** 227 * Add additional menu items to the menu. 228 * 229 * @param popup the menu to add the menu items to 230 * @return true if adding items; false otherwise 231 */ 232 boolean setTextEditMenu(JPopupMenu popup); 233 234 boolean showPopUp(JPopupMenu popup); 235 236 void setScale(double s); 237 238 double getScale(); 239 240 void rotate(int deg); 241 242 int getDegrees(); 243 244 JComponent getTextComponent(); 245 246 void remove(); 247 248 /** 249 * Check if a permanent copy of this Positionable should be stored. 250 * 251 * @return true if this Positionable should be stored; false otherwise 252 */ 253 boolean storeItem(); 254 255 /** 256 * Use the 'Standard' presentation of the popup menu items. The editor will 257 * call this method to find out whether it should create any popup viewing 258 * menu items. 259 * 260 * @return true if Editor may add the standardpopup menu items 261 */ 262 boolean doViemMenu(); 263 264 /** 265 * Utility to handle Margins, Borders and other common popup items 266 * 267 * @return null if these item do not apply 268 */ 269 PositionablePopupUtil getPopupUtility(); 270 271 void setPopupUtility(PositionablePopupUtil tu); 272 273 jmri.NamedBean getNamedBean(); 274 275 // Mouse-handling events. See 276 // Editor class for more information on how these are used. 277 void doMousePressed(JmriMouseEvent event); 278 279 void doMouseReleased(JmriMouseEvent event); 280 281 void doMouseClicked(JmriMouseEvent event); 282 283 void doMouseDragged(JmriMouseEvent event); 284 285 void doMouseMoved(JmriMouseEvent event); 286 287 void doMouseEntered(JmriMouseEvent event); 288 289 void doMouseExited(JmriMouseEvent event); 290 291 // The following are common for all JComponents 292 Rectangle getBounds(Rectangle r); 293 294 boolean contains(int x, int y); 295 296 @Override 297 int getX(); 298 299 @Override 300 int getY(); 301 302 Point getLocation(); 303 304 void setLocation(int x, int y); 305 306 void setLocation(Point p); 307 308 void setSize(int width, int height); 309 310 void setVisible(boolean b); 311 312 int getWidth(); 313 314 int getHeight(); 315 316 Container getParent(); 317 318 void setOpaque(boolean isOpaque); 319 320 boolean isOpaque(); 321 322 void setBackground(Color bg); 323 324 Color getBackground(); 325 326 void setForeground(Color bg); 327 328 Color getForeground(); 329 330 Font getFont(); 331 332 void setBorder(Border border); 333 334 Dimension getPreferredSize(); 335 336 void invalidate(); 337 338 void repaint(); 339 340 boolean requestFocusInWindow(); 341 342 @Override 343 public default String getEditorName() { 344 return getEditor().getName(); 345 } 346 347 348 public static class DuplicateIdException extends JmriException { 349 } 350 351}