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