public abstract class ALspSwingLabelStyler extends ALspLabelStyler
Styler that can use Swing components as label content.
Use getComponentStyle
in the implementation of your style
method.
This styler makes sure that the used Swing components are painted on the Event Dispatch Thread. Because of this, the styler can only be used for awt views.
Implement getComponent
to specify the component to use. You can
re-use the same component instance for different domain objects, similar to Swing cell
renderers.
Call componentChanged
whenever the component for a domain object
has become invalid and needs to be updated.
The following code shows how this class can be implemented:
private static class ComponentStyler extends ALspSwingLabelStyler {
private SwingComponent fSwingComponent = ...;
@Override
public void style( Collection<?> aObjects, ALspLabelStyleCollector aStyleCollector, TLspContext aContext ) {
for ( Object object : aObjects ) {
// Retrieve the style that represents the Swing component and use it
ALspStyle componentStyle = getComponentStyle( object, SUBLABEL_ID, aContext );
// The returned style can be null initially, until the component been rendered to in icon. A style change event
// will be fired automatically when this happens. In subsequent calls, the style will not be null anymore.
if ( componentStyle != null ) {
aStyleCollector.object( object ).label( SUBLABEL_ID ).styles( styles ).submit();
}
}
}
@Override
protected JComponent getComponent( Object aObject, Object aSublabelId, TLspContext aContext ) {
// Return the component to use for the given label
fSwingComponent.adjustForLabel( aObject, aSubLabelId );
return fSwingComponent;
}
}
Modifier | Constructor and Description |
---|---|
protected |
ALspSwingLabelStyler()
Creates a new
ALspSwingLabelStyler that can be used to paint labels using
Swing components. |
protected |
ALspSwingLabelStyler(ALspInteractiveLabelProvider aInteractiveLabelProvider,
TLspPaintRepresentationState aPaintRepresentationState,
boolean aInvalidateOnModelChangeEvent)
Creates a new
ALspSwingLabelStyler that can be used for interactive labels (see
TLspInteractiveLabelsController ). |
Modifier and Type | Method and Description |
---|---|
void |
allComponentsChanged(TLspContext aContext)
Notify this styler that the components for all domain objects have changed.
|
void |
componentChanged(Object aObject,
Object aSublabelId,
TLspContext aContext)
Notify this styler that the component for the given domain object and sublabel id has changed.
|
protected abstract JComponent |
getComponent(Object aObject,
Object aSublabelId,
TLspContext aContext)
This method retrieves the component for the given object.
|
protected ALspStyle |
getComponentStyle(Object aObject,
Object aSublabelId,
TLspContext aContext)
Returns the style that contains the representation of the component for the given domain object
and sublabel id.
|
protected boolean |
isInteractiveEditedLabel(Object aObject,
Object aSubLabelID,
TLspContext aContext)
Returns if the given label is interactively edited.
|
protected BufferedImage |
paintImage(JComponent aComponent,
Dimension aDimension,
Object aObject,
Object aSublabelID,
TLspContext aContext)
This method paints an image of the given component, for the given label.
|
protected boolean |
shouldInvalidateLabel(Object aObject,
Object aSubLabelID,
TLspContext aContext)
This method indicates if the content of the given label should be invalidated.
|
style, style
addStyleChangeListener, fireStyleChangeEvent, fireStyleChangeEvent, removeStyleChangeListener
protected ALspSwingLabelStyler()
Creates a new ALspSwingLabelStyler
that can be used to paint labels using
Swing components. When this styler is used, the components are not added to the swing
hierarchy. They are painted offscreen instead, and painted using a regular label painter.
Note that labels are not updated automatically when the content changes. To do this, it is required to
call componentChanged
. Alternatively, it is possible
to use the other constructor with the last argument set to true
. In that case, the componentChanged
method
is called automatically when model changes occur.
protected ALspSwingLabelStyler(ALspInteractiveLabelProvider aInteractiveLabelProvider, TLspPaintRepresentationState aPaintRepresentationState, boolean aInvalidateOnModelChangeEvent)
Creates a new ALspSwingLabelStyler
that can be used for interactive labels (see
TLspInteractiveLabelsController
).
When TLspInteractiveLabelsController
makes a label interactive, it adds a Swing label to the Swing
hierarchy. When this happens, a problem occurs: the label painter doesn't know anything about the interactive
label, so it also paints a label for the same object. Because of this, the label would be painted twice. Once
as a Swing component in the Swing hierarchy, and once by the label painter. This constructor solves this problem
by making sure that the label painter paints an empty (completely transparent) label when a label becomes
interactive. It knows when a label becomes interactive by registering a ILspInteractiveLabelListener
to the given ALspInteractiveLabelProvider
.
It is possible to make sure that labels are invalidated
on model changes by passing true
to this constructor.
It is possible to make sure that labels are invalidated on model changes by passing
true
to this constructor. In that case, the shouldInvalidateLabel
method is called as well. This method can be used to filter out changes that are not needed,
and can thus be used to improve the performance of this styler. When aInvalidateOnModelChangeEvent
is
false
, and the content of the label changes at runtime, the componentChanged
method should be called manually.
aInteractiveLabelProvider
- the interactive label provider. Can be null
if no
interactive labels are used.aPaintRepresentationState
- the paint representation and state for which this styler is used. This argument
should not be null
when aInteractiveLabelProvider
is not null
,
or when aInvalidateOnModelChangeEvent
is true
.aInvalidateOnModelChangeEvent
- true
to invalidate labels on model changes.protected boolean shouldInvalidateLabel(Object aObject, Object aSubLabelID, TLspContext aContext)
This method indicates if the content of the given label should be invalidated. Note that this method is only
called when using the ALspSwingLabelStyler(ALspInteractiveLabelProvider, TLspPaintRepresentationState, boolean)
constructor with true
as argument. In that case, this method will be called when model changes
occur.
This is useful to improve the performance of ALspSwingLabelStyler
when the content of the labels
changes at runtime. It allows to filter out changes that don't affect the content of the label. This is
useful for moving tracks which for example display their height and their callsign. The callsign doesn't change,
but the height might change sometimes. When the track moves, its location changes all the time, resulting
in a model change, but the height doesn't necessarily change, so it shouldn't be necessary to calculate the
content of the label.
When this method returns true
, this class will invalidate the content of the given label. It will
also call ALspInteractiveLabelProvider#updateInteractiveLabel()
when the given label is interactive.
By default, this method always returns true
.
aObject
- the domain object of the labelaSubLabelID
- the sublabel IDaContext
- the context.protected abstract JComponent getComponent(Object aObject, Object aSublabelId, TLspContext aContext)
Similar to the Swing cell renderers, you can re-use a single component instance for different domain objects.
aObject
- a domain objectaSublabelId
- a sublabel idaContext
- the contextprotected final boolean isInteractiveEditedLabel(Object aObject, Object aSubLabelID, TLspContext aContext)
getComponent
method.
This method can only return true
when using the
constructor that takes an ALspInteractiveLabelProvider
as argument, and when this
ALspInteractiveLabelProvider
notifies this styler that a
label is interactively edited.aObject
- the domain object of the labelaSubLabelID
- the sublabel IDaContext
- the context.protected BufferedImage paintImage(JComponent aComponent, Dimension aDimension, Object aObject, Object aSublabelID, TLspContext aContext)
aComponent
- the component to paint as an image.aDimension
- the dimension of the component (and the resulting image)aObject
- the domain object of the label.aSublabelID
- the sublabel ID.aContext
- the context.public void componentChanged(Object aObject, Object aSublabelId, TLspContext aContext)
Notify this styler that the component for the given domain object and sublabel id has changed.
Calling this method can trigger expensive operations on the Swing Event Dispatch Thread. So for performance reasons, it is advised to call this method only when strictly necessary. For example, an object can change, but when this change doesn't affect the Swing label, it is advised not to call this method.
aObject
- a domain objectaSublabelId
- a sublabel idaContext
- the context.public void allComponentsChanged(TLspContext aContext)
aContext
- the contextprotected ALspStyle getComponentStyle(Object aObject, Object aSublabelId, TLspContext aContext)
Returns the style that contains the representation of the component for the given domain object and sublabel id.
Note that this call can return null
if the representation is not available yet. In that case, this call
will make sure the representation is created, and that a style change is fired when that happens. In subsequent
calls, the style will not be null
anymore.
aObject
- a domain objectaSublabelId
- a sublabel idaContext
- the context.null
if not available