Class AbstractGameComponent

  • All Implemented Interfaces:
    GameComponent, java.io.Serializable, java.lang.Cloneable
    Direct Known Subclasses:
    DIY, Marker

    public abstract class AbstractGameComponent
    extends java.lang.Object
    implements GameComponent
    Provides default implementations for the GameComponent interface.
    Author:
    Chris Jennings
    See Also:
    Serialized Form
    • Method Summary

      All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Deprecated Methods 
      Modifier and Type Method Description
      void clearAll()
      Set all game component data to a neutral, blank state.
      AbstractGameComponent clone()
      Returns a deep copy of this game component.
      double computeIdealScaleForImage​(java.awt.image.BufferedImage image, java.lang.String imageKey)  
      double computeMinimumScaleForImage​(java.awt.image.BufferedImage image, java.lang.String imageKey)  
      void coreCheck()
      Checks if all required libraries and extensions are installed.
      abstract Sheet[] createDefaultSheets()
      Creates a set of default sheets that are compatible with this component and associates them with the component as if by calling GameComponent.setSheets(ca.cgjennings.apps.arkham.sheet.Sheet[]).
      static java.lang.String filterComponentText​(java.lang.String source)
      Given a string from a game component that may contain markup or other special coding, return a copy of the string containing plain text with all coding removed and newlines converted to spaces.
      java.lang.String getComment()
      Returns the design rationale comments associated with this component.
      java.awt.image.BufferedImage getDefaultPortrait​(java.lang.String portraitKey)
      Given a portrait image key name (without the "-portrait-template"), return the appropriate portrait image.
      java.lang.String getFullName()
      Returns the "full name" of this component.
      java.lang.String getName()
      Returns the name of this component.
      Settings getSettings()
      Returns a Settings instance that will return this component's private settings.
      Sheet[] getSheets()
      Returns the sheets attached to this component to draw its faces, or null if no sheets are attached.
      java.lang.String[] getSheetTitles()
      Returns human-readable names for the sheets used by this component.
      boolean hasChanged()
      Returns true if this component has been modified since the last call to hasChanged().
      boolean hasUnsavedChanges()
      Returns the value of this component's unsaved changes flag.
      static double idealScaleForImage​(double idealWidth, double idealHeight, double imageWidth, double imageHeight)
      static java.awt.image.BufferedImage imagePathToImage​(java.lang.String path)
      Deprecated.
      Use StrangeImage.get(java.lang.String) to load user-supplied images.
      boolean isDeckLayoutSupported()
      Returns true if components of this type can be placed in a deck.
      protected void markChanged()
      A convenience method that can be used to mark a default sheet or group of sheets as having changed.
      void markChanged​(int sheetIndex)
      Called to signal that changes have been made that require the ithe sheet to be redrawn.
      void markSaved()
      This method is called by the component's editor when the the component is saved to clear the component's unsaved changes flag.
      void markUnsavedChanges()
      This method sets the component's unsaved changes flag.
      protected void read​(java.io.ObjectInputStream in)
      Provides default code to read this object's values from a subclass.
      void setComment​(java.lang.String comment)
      Sets the design rationale comment associated with this component.
      void setName​(java.lang.String name)
      Sets the name of the component.
      protected void setNameImpl​(java.lang.String name)
      Sets the component name without marking any sheets as changed or marking the component as having unsaved changes.
      void setSheets​(Sheet[] sheets)
      Sets the sheets that are attached to this component to draw its faces.
      protected void write​(java.io.ObjectOutputStream out)
      Provides default code to write this object's values from a subclass.
      • Methods inherited from class java.lang.Object

        equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • comments

        protected java.lang.String comments
      • privateSettings

        protected Settings privateSettings
      • hasUndrawnChanges

        protected transient boolean hasUndrawnChanges
      • sheets

        protected transient Sheet[] sheets
    • Constructor Detail

      • AbstractGameComponent

        public AbstractGameComponent()
    • Method Detail

      • getName

        public java.lang.String getName()
        Description copied from interface: GameComponent
        Returns the name of this component. This is not the name of the component type, but the name of the specific component. For example, a component that represents a game item would return the name of the item.
        Specified by:
        getName in interface GameComponent
        Returns:
        the component's name; possibly a shortened version of the full name
        See Also:
        GameComponent.getFullName()
      • setName

        public void setName​(java.lang.String name)
        Sets the name of the component. If the new name is different from the existing name, and there are sheets installed, then any sheets which are not subclasses of UndecoratedCardBack will be marked as changed. In addition, the component is marked as having unsaved changes. To change this behaviour, you can override this method; see setNameImpl(java.lang.String).
        Parameters:
        name - the new name of the component
        Throws:
        java.lang.NullPointerException - if the name is null
      • setNameImpl

        protected final void setNameImpl​(java.lang.String name)
        Sets the component name without marking any sheets as changed or marking the component as having unsaved changes. Subclasses may call this from within an overridden setName(java.lang.String) method to change the default behaviour for marking sheets.
        Parameters:
        name - the new name of the component
        Throws:
        java.lang.NullPointerException - if the name is null
      • clone

        public AbstractGameComponent clone()
        Description copied from interface: GameComponent
        Returns a deep copy of this game component. The default clone implementation provided by super.clone() will return a shallow copy of the object. This will correctly clone all of this instance's fields that have primitive types. It is then up to you to clone any object fields where the field is not of an immutable type. Images used to store portraits, although not technically immutable, are treated as immutable by Strange Eons. So long as you also follow this convention, you can save memory by sharing the shallow copy of the image.

        Debugging tip: One operation that makes use of the clone() method is the Spin Off command. If you apply this command, make changes to the copied component, redraw the original component, and notice that changes in the copy have carried over to the original, then you are using a shallow copy rather than a deep copy. (That is, you are sharing a reference to the same mutable object rather than making a copy of the mutable object during the cloning.)

        Specified by:
        clone in interface GameComponent
        Overrides:
        clone in class java.lang.Object
        Returns:
        a deep copy of this component
      • getComment

        public java.lang.String getComment()
        Description copied from interface: GameComponent
        Returns the design rationale comments associated with this component. If there are no comments, it should return an empty string.
        Specified by:
        getComment in interface GameComponent
        Returns:
        design comments supplied by the user of the component
      • setComment

        public void setComment​(java.lang.String comment)
        Sets the design rationale comment associated with this component. If the comment is different from the existing comment, then markUnsavedChanges().
        Parameters:
        comment - the new design comment
        Throws:
        java.lang.NullPointerException - if the comment is null
      • clearAll

        public void clearAll()
        Set all game component data to a neutral, blank state. Marks all sheets as changed, as well as marking the component unsaved. Sets this component's content to an empty state. Typically, this is called from an editor when the user wishes to erase their work and start over.

        The base class implementation will clear the name and comments, mark the sheets changed, clear any set expansion, and mark the component unsaved.

        Specified by:
        clearAll in interface GameComponent
      • getSheetTitles

        public java.lang.String[] getSheetTitles()
        Returns human-readable names for the sheets used by this component. A typical result would be something like ["Front Face", "Back Face"], localized for the user interface language.

        Implementations should assume that the titles are for the same kinds and number of sheets that are returned by GameComponent.createDefaultSheets(). (In other words, if a user of this class decides to use their own sheet implementations, you are not responsible for ensuring the sheet titles are accurate.)

        Note: The returned sheet name may be shared with any number of callers. The values must be considered read-only unless otherwise stated by the subclass documentation.

        The base class implementation will provide suitable localized titles for most cases. It is designed to handle any number of alternating front and back faces, with one exception. If there are exactly three sheets, then it assumes that the third sheet is a token related to the first two.

        Specified by:
        getSheetTitles in interface GameComponent
        Returns:
        an array of sheet titles matching the assigned sheets, or null if there are no sheets attached
        See Also:
        GameComponent.createDefaultSheets()
      • markChanged

        public void markChanged​(int sheetIndex)
        Description copied from interface: GameComponent
        Called to signal that changes have been made that require the ithe sheet to be redrawn. This is typically not called directly. Instead, calling a method like "setName" should check if the name being set is actually different, and if so then call this method for each sheet that may have changed as a result. Plug-ins that customize an existing component may also call this method as needed to reflect new features that they have added.

        Implementations of this method will typically call the Sheet.markChanged() method of the relevant sheet (unless the sheet set is null), set a flag for use by GameComponent.hasChanged(), and then call GameComponent.markUnsavedChanges().

        Specified by:
        markChanged in interface GameComponent
        Parameters:
        sheetIndex - the index of the sheet that needs to be redrawn
      • markChanged

        protected void markChanged()
        A convenience method that can be used to mark a default sheet or group of sheets as having changed. The base class will call markChanged(int) for every sheet.
      • hasChanged

        public boolean hasChanged()
        Description copied from interface: GameComponent
        Returns true if this component has been modified since the last call to hasChanged().
        Specified by:
        hasChanged in interface GameComponent
        Returns:
        true if the component has changed since this was last called
      • hasUnsavedChanges

        public boolean hasUnsavedChanges()
        Description copied from interface: GameComponent
        Returns the value of this component's unsaved changes flag.
        Specified by:
        hasUnsavedChanges in interface GameComponent
        Returns:
        true if this component has unsaved changes
      • markSaved

        public void markSaved()
        Description copied from interface: GameComponent
        This method is called by the component's editor when the the component is saved to clear the component's unsaved changes flag.
        Specified by:
        markSaved in interface GameComponent
      • getSettings

        public Settings getSettings()
        Description copied from interface: GameComponent
        Returns a Settings instance that will return this component's private settings. A component's private settings are saved along with the component when it is written to a file. This can be used to override the default settings for component (which are determined by the the shared game settings for the game associated with the component) as a way to "hack" existing component designs. It can also be used by the component itself to store arbitrary information. DIY components generally use the component's private settings to store the current user-configurable state of the component.

        Note that setting the key with the name Game.GAME_SETTING_KEY ("game") will change the parent scope of the private settings to the relevant game's settings for that game whose code matches the new value. (The initial value of this key is normally set on the component's half using the game code specified in the component's class map entry.)

        Specified by:
        getSettings in interface GameComponent
        Returns:
        the private settings that can be used to override settings for this component
      • coreCheck

        public void coreCheck()
        Description copied from interface: GameComponent
        Checks if all required libraries and extensions are installed. If a required library is not install This method is called when the component is read from a file, and possibly at other times

        This can safely be implemented as an empty method. However, implementing it correctly improves the user experience since they can be notified of which plug-ins they need to install to correctly use the component. In the case of a required but not installed library, the library can actually be downloaded and installed on demand and the component can then be successfully opened.

        Specified by:
        coreCheck in interface GameComponent
        See Also:
        CoreComponents
      • filterComponentText

        public static java.lang.String filterComponentText​(java.lang.String source)
        Given a string from a game component that may contain markup or other special coding, return a copy of the string containing plain text with all coding removed and newlines converted to spaces. Useful for printing a display name.
        Parameters:
        source - the string to filter
        Throws:
        java.lang.NullPointerException - if the source string is null
      • getDefaultPortrait

        public java.awt.image.BufferedImage getDefaultPortrait​(java.lang.String portraitKey)
        Given a portrait image key name (without the "-portrait-template"), return the appropriate portrait image.
      • idealScaleForImage

        @Deprecated
        public static double idealScaleForImage​(double idealWidth,
                                                double idealHeight,
                                                double imageWidth,
                                                double imageHeight)
        Returns the largest scaling factor that, when multiplied by the given image size, ensures that the image will match the ideal size in at least one dimension. The image will either match the ideal size in the other dimension, or else be larger than the other ideal dimension. If the image is opaque, the result is the scaling factor to obtain the smallest image with the same aspect ratio that would completely cover the ideal image area.
        Parameters:
        idealWidth - the width of the area the image must cover
        idealHeight - the height of the area the image must cover
        imageWidth - the current width of the image to be fitted
        imageHeight - the current height of the image to be fitted
        Returns:
        the scale that would ensure that the image would just cover the specified area
      • computeMinimumScaleForImage

        public double computeMinimumScaleForImage​(java.awt.image.BufferedImage image,
                                                  java.lang.String imageKey)
      • computeIdealScaleForImage

        public double computeIdealScaleForImage​(java.awt.image.BufferedImage image,
                                                java.lang.String imageKey)
      • imagePathToImage

        @Deprecated
        public static java.awt.image.BufferedImage imagePathToImage​(java.lang.String path)
        Deprecated.
        Use StrangeImage.get(java.lang.String) to load user-supplied images.
        Returns a bitmap image for a user-supplied path. The path may name a local file or be any of the special URL paths supported by StrangeImage. If the path points to a vector image (and vector support is installed), then the image will be converted to a bitmap automatically, at a size and resolution based on
        Parameters:
        path - the path to locate an image for
        Returns:
        a bitmap image for the path; if the path does not point to a valid image, a stand-in "missing image" image will be returned
      • write

        protected final void write​(java.io.ObjectOutputStream out)
                            throws java.io.IOException
        Provides default code to write this object's values from a subclass. For historical reasons, nothing is written by this class's default serialization mechanism. Subclasses therefore have to read and set the name, comment, and settings instances themselves. This method can be called from a subclass writeObject method to do this on behalf of the subclass.
        Parameters:
        out - the stream to write to
        Throws:
        java.io.IOException - if an I/O exception occurs
      • read

        protected final void read​(java.io.ObjectInputStream in)
                           throws java.io.IOException,
                                  java.lang.ClassNotFoundException
        Provides default code to read this object's values from a subclass. For historical reasons, nothing is written by this class's default serialization mechanism. Subclasses therefore have to read and write the name, comment, and settings instances themselves. This method can be called from a subclass readObject method to restore serialized data written with write(java.io.ObjectOutputStream).
        Parameters:
        in - the stream to read from
        Throws:
        java.io.IOException - if an I/O exception occurs
        java.lang.ClassNotFoundException