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    void setValueEditDisabled(boolean disabled);
121
122    boolean isValueEditDisabled();
123
124    int getDisplayLevel();
125
126    void setDisplayLevel(int l);
127
128    Editor getEditor();
129
130    void setEditor(Editor ed);
131
132    void updateSize();
133
134    int maxWidth();
135
136    int maxHeight();
137
138    /**
139     * Make a deep copy of Positional object. Implementation should create a new
140     * object and immediately pass the object to finishClone() returning the
141     * result of finishClone(). i.e. implementation must be:
142     * <p>
143     * {@code public Positionable deepClone() { Subtype t = new Subtype(); return finishClone(t);
144     * } }
145     * <p>
146     * Then finishClone() finishes the deep Copy of a Positional object.
147     * Implementation should make deep copies of the additional members of this
148     * sub class and then pass Positionable p to super.finishClone(). i.e.
149     * implementation must terminate with statement return super.finishClone(p);
150     * See IndicatorTurnoutIcon extends TurnoutIcon extends PositionableLabel
151     * for an example of how to continue deep cloning a chain of subclasses.
152     *
153     * @return the copy
154     */
155    Positionable deepClone();
156
157    /**
158     * Get the type of the positional as a String.
159     *
160     * @return the type to display
161     */
162    String getTypeString();
163
164    /**
165     * Get the name of the positional as a String. This is often the display
166     * name of the NamedBean being positioned.
167     *
168     * @return the name to display
169     */
170    @Override
171    String getNameString();
172
173    /**
174     * {@inheritDoc}
175     */
176    @Override
177    public default String getTypeName() {
178        NamedBean nb = getNamedBean();
179        return nb != null ? nb.getBeanType() : null;
180    }
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 setRotateOrthogonalMenu(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 setRotateMenu(JPopupMenu popup);
197
198    /**
199     * Add additional menu items to the menu.
200     *
201     * @param popup the menu to add the menu items to
202     * @return true if adding items; false otherwise
203     */
204    boolean setScaleMenu(JPopupMenu popup);
205
206    /**
207     * Add additional menu items to the menu.
208     *
209     * @param popup the menu to add the menu items to
210     * @return true if adding items; false otherwise
211     */
212    boolean setEditIconMenu(JPopupMenu popup);
213
214    /**
215     * Add additional menu items to the menu.
216     *
217     * @param popup the menu to add the menu items to
218     * @return true if adding items; false otherwise
219     */
220    boolean setEditItemMenu(JPopupMenu popup);
221
222    /**
223     * Add additional menu items to the menu.
224     *
225     * @param popup the menu to add the menu items to
226     * @return true if adding items; false otherwise
227     */
228    boolean setDisableControlMenu(JPopupMenu popup);
229
230    /**
231     * Add additional menu items to the menu.
232     *
233     * @param popup the menu to add the menu items to
234     * @return true if adding items; false otherwise
235     */
236    boolean setTextEditMenu(JPopupMenu popup);
237
238    boolean showPopUp(JPopupMenu popup);
239
240    void setScale(double s);
241
242    double getScale();
243
244    void rotate(int deg);
245
246    int getDegrees();
247
248    JComponent getTextComponent();
249
250    void remove();
251
252    /**
253     * Check if a permanent copy of this Positionable should be stored.
254     *
255     * @return true if this Positionable should be stored; false otherwise
256     */
257    boolean storeItem();
258
259    /**
260     * Use the 'Standard' presentation of the popup menu items. The editor will
261     * call this method to find out whether it should create any popup viewing
262     * menu items.
263     *
264     * @return true if Editor may add the standardpopup menu items
265     */
266    boolean doViemMenu();
267
268    /**
269     * Utility to handle Margins, Borders and other common popup items
270     *
271     * @return null if these item do not apply
272     */
273    PositionablePopupUtil getPopupUtility();
274
275    void setPopupUtility(PositionablePopupUtil tu);
276
277    jmri.NamedBean getNamedBean();
278
279    // Mouse-handling events.  See
280    // Editor class for more information on how these are used.
281    void doMousePressed(JmriMouseEvent event);
282
283    void doMouseReleased(JmriMouseEvent event);
284
285    void doMouseClicked(JmriMouseEvent event);
286
287    void doMouseDragged(JmriMouseEvent event);
288
289    void doMouseMoved(JmriMouseEvent event);
290
291    void doMouseEntered(JmriMouseEvent event);
292
293    void doMouseExited(JmriMouseEvent event);
294
295    // The following are common for all JComponents
296    Rectangle getBounds(Rectangle r);
297
298    boolean contains(int x, int y);
299
300    @Override
301    int getX();
302
303    @Override
304    int getY();
305
306    Point getLocation();
307
308    void setLocation(int x, int y);
309
310    void setLocation(Point p);
311
312    void setSize(int width, int height);
313
314    void setVisible(boolean b);
315
316    int getWidth();
317
318    int getHeight();
319
320    Container getParent();
321
322    void setOpaque(boolean isOpaque);
323
324    boolean isOpaque();
325
326    void setBackground(Color bg);
327
328    Color getBackground();
329
330    void setForeground(Color bg);
331
332    Color getForeground();
333
334    Font getFont();
335
336    void setBorder(Border border);
337
338    Dimension getPreferredSize();
339
340    void invalidate();
341
342    void repaint();
343
344    boolean requestFocusInWindow();
345
346    @Override
347    public default String getEditorName() {
348        return getEditor().getName();
349    }
350
351
352    public static class DuplicateIdException extends JmriException {
353    }
354
355}