Class AbstractGameComponent
- java.lang.Object
-
- ca.cgjennings.apps.arkham.component.AbstractGameComponent
-
- All Implemented Interfaces:
GameComponent,java.io.Serializable,java.lang.Cloneable
public abstract class AbstractGameComponent extends java.lang.Object implements GameComponent
Provides default implementations for theGameComponentinterface.- Author:
- Chris Jennings
- See Also:
- Serialized Form
-
-
Field Summary
Fields Modifier and Type Field Description protected java.lang.Stringcommentsprotected booleanhasUndrawnChangesprotected SettingsprivateSettingsprotected Sheet[]sheets
-
Constructor Summary
Constructors Constructor Description AbstractGameComponent()
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Deprecated Methods Modifier and Type Method Description voidclearAll()Set all game component data to a neutral, blank state.AbstractGameComponentclone()Returns a deep copy of this game component.doublecomputeIdealScaleForImage(java.awt.image.BufferedImage image, java.lang.String imageKey)doublecomputeMinimumScaleForImage(java.awt.image.BufferedImage image, java.lang.String imageKey)voidcoreCheck()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 callingGameComponent.setSheets(ca.cgjennings.apps.arkham.sheet.Sheet[]).static java.lang.StringfilterComponentText(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.StringgetComment()Returns the design rationale comments associated with this component.java.awt.image.BufferedImagegetDefaultPortrait(java.lang.String portraitKey)Given a portrait image key name (without the "-portrait-template"), return the appropriate portrait image.java.lang.StringgetFullName()Returns the "full name" of this component.java.lang.StringgetName()Returns the name of this component.SettingsgetSettings()Returns aSettingsinstance that will return this component's private settings.Sheet[]getSheets()Returns the sheets attached to this component to draw its faces, ornullif no sheets are attached.java.lang.String[]getSheetTitles()Returns human-readable names for the sheets used by this component.booleanhasChanged()Returnstrueif this component has been modified since the last call tohasChanged().booleanhasUnsavedChanges()Returns the value of this component's unsaved changes flag.static doubleidealScaleForImage(double idealWidth, double idealHeight, double imageWidth, double imageHeight)static java.awt.image.BufferedImageimagePathToImage(java.lang.String path)Deprecated.UseStrangeImage.get(java.lang.String)to load user-supplied images.booleanisDeckLayoutSupported()Returnstrueif components of this type can be placed in a deck.protected voidmarkChanged()A convenience method that can be used to mark a default sheet or group of sheets as having changed.voidmarkChanged(int sheetIndex)Called to signal that changes have been made that require theithe sheet to be redrawn.voidmarkSaved()This method is called by the component's editor when the the component is saved to clear the component's unsaved changes flag.voidmarkUnsavedChanges()This method sets the component's unsaved changes flag.protected voidread(java.io.ObjectInputStream in)Provides default code to read this object's values from a subclass.voidsetComment(java.lang.String comment)Sets the design rationale comment associated with this component.voidsetName(java.lang.String name)Sets the name of the component.protected voidsetNameImpl(java.lang.String name)Sets the component name without marking any sheets as changed or marking the component as having unsaved changes.voidsetSheets(Sheet[] sheets)Sets the sheets that are attached to this component to draw its faces.protected voidwrite(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
-
Methods inherited from interface ca.cgjennings.apps.arkham.component.GameComponent
convertFrom, convertTo, createDefaultEditor, createUpgradeConversionTrigger, getClassName
-
-
-
-
Method Detail
-
getName
public java.lang.String getName()
Description copied from interface:GameComponentReturns 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:
getNamein interfaceGameComponent- 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 ofUndecoratedCardBackwill be marked as changed. In addition, the component is marked as having unsaved changes. To change this behaviour, you can override this method; seesetNameImpl(java.lang.String).- Parameters:
name- the new name of the component- Throws:
java.lang.NullPointerException- if the name isnull
-
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 overriddensetName(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 isnull
-
clone
public AbstractGameComponent clone()
Description copied from interface:GameComponentReturns a deep copy of this game component. The default clone implementation provided bysuper.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:
clonein interfaceGameComponent- Overrides:
clonein classjava.lang.Object- Returns:
- a deep copy of this component
-
getFullName
public java.lang.String getFullName()
Returns the "full name" of this component. Typically this is the same asGameComponent.getName(), butGameComponent.getName()may optionally return a shorter name. For example, a component that represents a human character might return the character's first name fromGameComponent.getName()and their full name from this method.This base class implementation returns
getName().- Specified by:
getFullNamein interfaceGameComponent- Returns:
- the full name of the component
- See Also:
GameComponent.getName()
-
getComment
public java.lang.String getComment()
Description copied from interface:GameComponentReturns the design rationale comments associated with this component. If there are no comments, it should return an empty string.- Specified by:
getCommentin interfaceGameComponent- 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, thenmarkUnsavedChanges().- Parameters:
comment- the new design comment- Throws:
java.lang.NullPointerException- if the comment isnull
-
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:
clearAllin interfaceGameComponent
-
setSheets
public void setSheets(Sheet[] sheets)
Description copied from interface:GameComponentSets the sheets that are attached to this component to draw its faces. Once set, the array is owned by the component and must not be modified.- Specified by:
setSheetsin interfaceGameComponent- Parameters:
sheets- the sheets to associate with the component, ornullto clear the associated sheets- See Also:
GameComponent.getSheets(),GameComponent.createDefaultSheets()
-
getSheets
public Sheet[] getSheets()
Description copied from interface:GameComponentReturns the sheets attached to this component to draw its faces, ornullif no sheets are attached. The returned array is owned by the game component and must not be modified.- Specified by:
getSheetsin interfaceGameComponent- Returns:
- the sheets that will be updated by calls to
GameComponent.markChanged(int). - See Also:
GameComponent.getSheets()
-
createDefaultSheets
public abstract Sheet[] createDefaultSheets()
Description copied from interface:GameComponentCreates a set of default sheets that are compatible with this component and associates them with the component as if by callingGameComponent.setSheets(ca.cgjennings.apps.arkham.sheet.Sheet[]). As withGameComponent.getSheets(), the returned sheets are owned by the component and must not be modified.- Specified by:
createDefaultSheetsin interfaceGameComponent- Returns:
- the newly created sheets
-
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:
getSheetTitlesin interfaceGameComponent- Returns:
- an array of sheet titles matching the assigned sheets, or
nullif there are no sheets attached - See Also:
GameComponent.createDefaultSheets()
-
markChanged
public void markChanged(int sheetIndex)
Description copied from interface:GameComponentCalled to signal that changes have been made that require theithe 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 isnull), set a flag for use byGameComponent.hasChanged(), and then callGameComponent.markUnsavedChanges().- Specified by:
markChangedin interfaceGameComponent- 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 callmarkChanged(int)for every sheet.
-
hasChanged
public boolean hasChanged()
Description copied from interface:GameComponentReturnstrueif this component has been modified since the last call tohasChanged().- Specified by:
hasChangedin interfaceGameComponent- Returns:
trueif the component has changed since this was last called
-
markUnsavedChanges
public void markUnsavedChanges()
Description copied from interface:GameComponentThis method sets the component's unsaved changes flag. It is typically called fromGameComponent.markChanged(int).- Specified by:
markUnsavedChangesin interfaceGameComponent
-
hasUnsavedChanges
public boolean hasUnsavedChanges()
Description copied from interface:GameComponentReturns the value of this component's unsaved changes flag.- Specified by:
hasUnsavedChangesin interfaceGameComponent- Returns:
trueif this component has unsaved changes
-
markSaved
public void markSaved()
Description copied from interface:GameComponentThis method is called by the component's editor when the the component is saved to clear the component's unsaved changes flag.- Specified by:
markSavedin interfaceGameComponent
-
getSettings
public Settings getSettings()
Description copied from interface:GameComponentReturns aSettingsinstance 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 componentsgenerally 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 therelevant game's settingsfor 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:
getSettingsin interfaceGameComponent- Returns:
- the private settings that can be used to override settings for this component
-
isDeckLayoutSupported
public boolean isDeckLayoutSupported()
Description copied from interface:GameComponentReturnstrueif components of this type can be placed in a deck. Typically, only components that don't have faces returnfalse. (Decks themselves, for example, cannot be placed inside other decks.)- Specified by:
isDeckLayoutSupportedin interfaceGameComponent- Returns:
trueif and only if this component can be added to a deck- See Also:
GameComponent.createDefaultSheets(),Deck.isDeckLayoutSupported(java.io.File)
-
coreCheck
public void coreCheck()
Description copied from interface:GameComponentChecks 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 timesThis 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:
coreCheckin interfaceGameComponent- 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 isnull
-
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 coveridealHeight- the height of the area the image must coverimageWidth- the current width of the image to be fittedimageHeight- 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.UseStrangeImage.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 byStrangeImage. 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.IOExceptionProvides 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 subclasswriteObjectmethod 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.ClassNotFoundExceptionProvides 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 subclassreadObjectmethod to restore serialized data written withwrite(java.io.ObjectOutputStream).- Parameters:
in- the stream to read from- Throws:
java.io.IOException- if an I/O exception occursjava.lang.ClassNotFoundException
-
-