+ // pins
+
+ /**
+ * Adds the given pin to this component and calls pinAddedListeners and redrawListeners.
+ *
+ * @throws IllegalArgumentException if the pin doesn't belong to this component
+ * @throws IllegalArgumentException if there already is a pin with the given name
+ *
+ * @author Daniel Kirschten
+ */
+ protected void addPin(Pin pin)
+ {
+ if (pin.component != this)
+ throw new IllegalArgumentException("Can't add a pin not belonging to this component!");
+ if (pinsByName.containsKey(pin.name))
+ throw new IllegalArgumentException("Duplicate pin name: " + pin.name);
+ pinsByName.put(pin.name, pin);
+ callPinAddedListeners(pin);
+ pin.addRedrawListener(redrawListenerForSubcomponents);
+ requestRedraw();
+ }
+
+ /**
+ * Removes the given pin from this component and calls pinAddedListeners and redrawListeners.
+ *
+ * @throws NullPointerException if there was no pin with this name
+ *
+ * @author Daniel Kirschten
+ */
+ protected void removePin(String name)
+ {
+ Pin pin = pinsByName.remove(name);
+ callPinRemovedListeners(pin);
+ pin.removeRedrawListener(redrawListenerForSubcomponents);
+ requestRedraw();
+ }
+
+ /**
+ * Returns a collection of pins of this component.
+ *
+ * @author Daniel Kirschten
+ */
+ public Map<String, Pin> getPins()
+ {
+ return pinsUnmodifiable;
+ }
+
+ /**
+ * Returns the pin with the given name of this component.
+ *
+ * @throws IllegalArgumentException if there is no pin with the given name
+ *
+ * @author Daniel Kirschten
+ */
+ public Pin getPin(String name)
+ {
+ Pin pin = pinsByName.get(name);
+ if (pin == null)
+ throw new IllegalArgumentException("No pin with the name " + name);
+ return pin;
+ }
+
+ // high-level access
+
+ /**
+ * Sets the given high-level state to the given value. <br>
+ * A high level state ID consists of parts separated by dots ('.').<br>
+ * The last part (the part after the last dot) is called "atomic high level state ID". The parts before that part are called
+ * "subcomponent ID"s.<br>
+ * If there is no dot in a high level state ID, the whole high level state ID is called atomic.<br>
+ * Note that subcomponent IDs don't have to correspond to actual subcomponents. For example, a RAM component may supply subcomponent IDs
+ * "c0000", "c0001" ... "cFFFF" without actually having a subcomponent for each cell. It also is allowed for an atomic high level state
+ * ID to be delegated to a subcomponent.
+ *
+ * @author Daniel Kirschten
+ */
+ @SuppressWarnings({ "static-method", "unused" }) // this method is intended to be overridden
+ public void setHighLevelState(String stateID, Object newState)
+ {
+ throw new IllegalArgumentException("No high level state with ID " + stateID);
+ }
+
+ /**
+ * Gets the current value of the given high-level state. <br>
+ * See {@link #setHighLevelState(String, Object)} for an explanation of high-level state IDs.
+ *
+ * @author Daniel Kirschten
+ */
+ @SuppressWarnings("static-method") // this method is intended to be overridden
+ public Object getHighLevelState(String stateID)
+ {
+ throw new IllegalArgumentException("No high level state with ID " + stateID);
+ }
+
+ // "graphical" operations
+
+ /**
+ * Sets the position of this component and calls componentMovedListeners and redrawListeners.
+ *
+ * @author Daniel Kirschten
+ */