+ public final Object getHighLevelState(String stateID)
+ {
+ int indexOfDot = stateID.indexOf('.');
+ if (indexOfDot == -1)
+ {
+ if (highLevelAtomicStates.contains(stateID))
+ return getAtomicHighLevelState(stateID);
+ return super.getHighLevelState(stateID);
+ }
+ return getSubcomponentHighLevelState(stateID.substring(0, indexOfDot), stateID.substring(indexOfDot + 1));
+ }
+
+ /**
+ * This method is called in {@link #getHighLevelState(String, Object)} when the state ID is not atomic. The default implementation uses
+ * the information given to {@link #addHighLevelStateSubcomponentID(String, GUIComponent)
+ * add}/{@link #removeHighLevelStateSubcomponentID(String)} to decide which subcomponent to delegate to. <br>
+ * Note that {@link #addHighLevelStateSubcomponentID(String, GUIComponent) add}/{@link #removeHighLevelStateSubcomponentID(String)}
+ * don't affect whether this method will be called.
+ *
+ * @author Daniel Kirschten
+ */
+ protected Object getSubcomponentHighLevelState(String subcomponentID, String subcomponentHighLevelStateID)
+ {
+ GUIComponent subcomponent = subcomponentsByHighLevelStateSubcomponentID.get(subcomponentID);
+ if (subcomponent != null)
+ return subcomponent.getHighLevelState(subcomponentHighLevelStateID);
+ return super.getHighLevelState(subcomponentID + "." + subcomponentHighLevelStateID);
+ }
+
+ /**
+ * This method is called in {@link SubmodelComponent#getHighLevelState(String)} when the state ID is in the set of allowed atomic state
+ * IDs. <br>
+ * See {@link GUIComponent#setHighLevelState(String, Object)} for details about atomic state IDs.
+ *
+ * @author Daniel Kirschten
+ */
+ @SuppressWarnings("static-method") // this method is intended to be overridden
+ protected Object getAtomicHighLevelState(String stateID)
+ {
+ throw new IllegalStateException("Unknown high level state ID: " + stateID);
+ }
+
+ private static void checkHighLevelStateIDPart(String stateIDPart)
+ {
+ if (stateIDPart.indexOf('.') != -1)
+ throw new IllegalArgumentException("Illegal high level state ID part (contains dot): " + stateIDPart);
+
+ }
+
+ // "graphical" operations
+
+ /**
+ * Sets the factor by which the submodel is scaled when rendering and calls redrawListeners. Note that the submodel interface pins will
+ * stay at their position relative to the supermodel, which means they will move relative to the submodel.
+ *
+ * @author Daniel Kirschten
+ */
+ protected void setSubmodelScale(double submodelScale)