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}