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}