Class TLcdGXYHaloLabelPainter

java.lang.Object
com.luciad.view.gxy.TLcdGXYHaloLabelPainter
All Implemented Interfaces:
ILcdGXYLabelPainter, ILcdGXYLabelPainterProvider, ILcdGXYMultiLabelPainter, Serializable, Cloneable
Direct Known Subclasses:
TLcdGXYHaloLabelPainter2

public class TLcdGXYHaloLabelPainter extends Object implements ILcdGXYMultiLabelPainter, ILcdGXYLabelPainterProvider, Cloneable
A label painter that adds halo effects to labels. A halo is an outline of constant width and color around shapes or text, which is typically drawn in a contrasting color to ensure that the shapes or text are clearly visible on any background.

Wrapping a label painter or label painter provider

This label painter uses the Decorator design pattern to add halo support to any existing ILcdGXYLabelPainter or ILcdGXYLabelPainterProvider implementation. If the decorated class implements both, a cast to either ILcdGXYLabelPainter or ILcdGXYLabelPainterProvider is necessary to select the correct constructor. When the decorated class is passed as a ILcdGXYLabelPainterProvider, this class must also be used as a ILcdGXYLabelPainterProvider, which means that getGXYLabelPainter(Object) must be called before painting any labels.

Delegate requirements

Most of the label painters that ship with LuciadLightspeed (e.g. TLcdGXYStampLabelPainter already provide built-in support for halos. In this case, they will have methods analogous to this class to configure the halo appearance and control the use of image caching. If available, the built-in support should be preferred over the use of TLcdGXYHaloLabelPainter.

This implementation can be used with label painters/label painter providers supporting ILcdGXYLabelPainter or ILcdGXYMultiLabelPainter. If your label painter implements ILcdGXYLabelPainter2, we strongly recommend using TLcdGXYHaloLabelPainter2 instead.

Note that when using this label painter, it is important that the delegate label painter's ILcdGXYLabelPainter.labelBoundsSFCT method is correctly implemented. Due to TLcdGXYHaloLabelPainter's use of offscreen images, anything that the delegate label painter draws outside of the returned label bounds may be clipped away.

Halo settings

The color and thickness of the halo are configurable. Note that there is some overhead associated with drawing the halo. This overhead depends on the label thickness, so small values (1 or 2 pixels) are recommended.

To reduce the overhead associated with the halo effect, this painter can perform image caching: the labels and their halos are drawn into an offscreen image and cached, so that subsequent repaints do not require the halo to be recreated. This improves performance considerably, but it is the application's responsibility to ensure the validity of the cache. If an object's label changes over the course of the object's lifetime, the application must call the clearImageCache(Object) method to remove that object's cached image. Note that changing the halo color or thickness automatically clears the entire image cache.

Since:
7.0.17
See Also:
  • Constructor Details

    • TLcdGXYHaloLabelPainter

      public TLcdGXYHaloLabelPainter(ILcdGXYLabelPainter aLabelPainter)
      Creates a new TLcdGXYHaloLabelPainter wrapping the given label painter, with default halo parameters (Color = white, thickness = 1). If the delegate painter is an ILcdGXYLabelPainter2, use TLcdGXYHaloLabelPainter2 instead.
      Parameters:
      aLabelPainter - the ILcdGXYLabelPainter rendering the label.
    • TLcdGXYHaloLabelPainter

      public TLcdGXYHaloLabelPainter(ILcdGXYLabelPainter aLabelPainter, Color aHaloColor, int aHaloThickness)
      Creates a new TLcdGXYHaloLabelPainter wrapping the given label painter, configured with the given halo color and thickness. If the delegate painter is an ILcdGXYLabelPainter2, use TLcdGXYHaloLabelPainter2 instead.
      Parameters:
      aLabelPainter - the ILcdGXYLabelPainter rendering the label.
      aHaloColor - the halo color
      aHaloThickness - the halo thickness
    • TLcdGXYHaloLabelPainter

      public TLcdGXYHaloLabelPainter(ILcdGXYLabelPainterProvider aLabelPainterProvider)
      Creates a new TLcdGXYHaloLabelPainterProvider wrapping the given label painter provider, with default halo parameters (Color = white, thickness = 1). If the delegate painter provider returns an ILcdGXYLabelPainter2 label painters, use TLcdGXYHaloLabelPainter2 instead.

      Note that this constructor demands that the provider is used as a ILcdGXYLabelPainterProvider, which means that getGXYLabelPainter(Object) must be called before using it to paint a label.

      Parameters:
      aLabelPainterProvider - the ILcdGXYLabelPainterProvider rendering the label.
    • TLcdGXYHaloLabelPainter

      public TLcdGXYHaloLabelPainter(ILcdGXYLabelPainterProvider aLabelPainterProvider, Color aHaloColor, int aHaloThickness)
      Creates a new TLcdGXYHaloLabelPainterProvider wrapping the given label painter provider, configured with the given halo color and thickness. If the delegate painter provider is an ILcdGXYLabelPainterProvider2, use TLcdGXYHaloLabelPainter2 instead.

      Note that this constructor demands that the provider is used as a ILcdGXYLabelPainterProvider, which means that getGXYLabelPainter(Object) must be called before using it to paint a label.

      Parameters:
      aLabelPainterProvider - the ILcdGXYLabelPainterProvider rendering the label.
      aHaloColor - the halo color
      aHaloThickness - the halo thickness
  • Method Details

    • isHaloEnabled

      public boolean isHaloEnabled()
      Returns true if the halo effect is on, false otherwise.
      Returns:
      true if the halo effect is on, false otherwise
      See Also:
    • setHaloEnabled

      public void setHaloEnabled(boolean aHaloEnabled)
      Switches the halo effect on or off. If halos are not enabled, label painting is delegated directly to the wrapped label painter, without further intervention by this TLcdGXYHaloLabelPainter.
      Parameters:
      aHaloEnabled - true if halos should be added, false otherwise
    • getHaloThickness

      public int getHaloThickness()
      Returns the current halo thickness.
      Returns:
      the current halo thickness
      See Also:
    • setHaloThickness

      public void setHaloThickness(int aThickness)
      Sets the thickness (in pixels) of the halo to be added around labels. A value of 0 (the default) means that the halo effect is disabled. Note that the performance cost of adding a halo is proportional to the halo's thickness. Also note that changing this property invalidates all currently cached label images.
      Parameters:
      aThickness - the new halo thickness
    • getHaloColor

      public Color getHaloColor()
      Returns the current halo color.
      Returns:
      the current halo color
      See Also:
    • setHaloColor

      public void setHaloColor(Color aColor)
      Sets the color of the halo to be added around labels. The color should be chosen such that it contrasts with the color of the labels themselves. This will ensure that the label is clearly visible on any background.

      Note that changing this property invalidates all currently cached label images.

      Parameters:
      aColor - the new halo color
    • setHaloAlgorithm

      public void setHaloAlgorithm(TLcdHaloAlgorithm aHaloAlgorithm)
      Sets the algorithm to be used for rendering halo's. The choice of the halo algorithm may have a major impact on the overall performance of this painter. See TLcdHaloAlgorithm for more information on the available algorithms.
      Parameters:
      aHaloAlgorithm - the algorithm to be used for rendering halo's.
      See Also:
    • getHaloAlgorithm

      public TLcdHaloAlgorithm getHaloAlgorithm()
      Returns the algorithm that is used for rendering halo's.
      Returns:
      the algorithm that is used for rendering halo's.
      See Also:
    • isUseImageCache

      public boolean isUseImageCache()
      Returns true when label image caching is enabled, false otherwise.
      Returns:
      true when label image caching is enabled, false otherwise
    • setUseImageCache

      public void setUseImageCache(boolean aUseCache)
      Sets whether or not labels should be cached as images. Enabling the cache will improve painting performance significantly, as labels will need to be rendered only once. Two caveats apply, however:
      • Caching requires more memory (one image for each label).
      • A cached image must be removed if its corresponding label changes. This can happen, for instance, if the label displays a dynamically changing property of an object. A typical solution is to create an ILcdModelListener that removes an object from the image cache whenever that object changes.
      Parameters:
      aUseCache - specifies whether image caching should be enabled
      See Also:
    • clearImageCache

      public void clearImageCache()
      Clears the entire label image cache. To remove a single label from the cache, use clearImageCache(Object).
      See Also:
    • clearImageCache

      public void clearImageCache(Object aObject)
      Clears the label image cache for the given object. The next time this object is painted, a new image will be created and cached for it. To remove all cached images in one go, use clearImageCache().
      Parameters:
      aObject - the object for which the cache to be cleared.
      See Also:
    • getDelegateLabelPainter

      public ILcdGXYLabelPainter getDelegateLabelPainter()
      Returns the ILcdGXYLabelPainter to which the rendering of the labels is delegated.
      Returns:
      the ILcdGXYLabelPainter to which the rendering of the labels is delegated.
    • setDelegateLabelPainter

      public void setDelegateLabelPainter(ILcdGXYLabelPainter aDelegateLabelPainter)
      Sets the ILcdGXYLabelPainter to which the rendering of the labels is to be delegated. If the delegate painter is an ILcdGXYLabelPainter2, use TLcdGXYHaloLabelPainter2 instead.
      Parameters:
      aDelegateLabelPainter - the ILcdGXYLabelPainter to which the rendering of the labels is delegated.
    • getDelegateLabelPainterProvider

      public ILcdGXYLabelPainterProvider getDelegateLabelPainterProvider()
      Returns the ILcdGXYLabelPainterProvider to which the rendering of the labels is delegated.
      Returns:
      the ILcdGXYLabelPainterProvider to which the rendering of the labels is delegated.
    • setDelegateLabelPainterProvider

      public void setDelegateLabelPainterProvider(ILcdGXYLabelPainterProvider aDelegateLabelPainterProvider)
      Sets the ILcdGXYLabelPainterProvider to which the rendering of the labels is to be delegated. If the delegate painter provider returns ILcdGXYLabelPainter2 instances, use TLcdGXYHaloLabelPainter2 instead.
      Parameters:
      aDelegateLabelPainterProvider - the ILcdGXYLabelPainterProvider to which the rendering of the labels is delegated.
    • addPropertyChangeListener

      public void addPropertyChangeListener(PropertyChangeListener aPropertyChangeListener)
      Adds a PropertyChangeListener to this painter.
      Parameters:
      aPropertyChangeListener - the receiver of property change events generated by this object
      See Also:
    • removePropertyChangeListener

      public void removePropertyChangeListener(PropertyChangeListener aPropertyChangeListener)
      Removes a PropertyChangeListener from this painter.
      Parameters:
      aPropertyChangeListener - the listener to be removed
      See Also:
    • getGXYLabelPainter

      public ILcdGXYLabelPainter getGXYLabelPainter(Object aObject)
      Always returns this label painter itself.
      Specified by:
      getGXYLabelPainter in interface ILcdGXYLabelPainterProvider
      Parameters:
      aObject - the object for which a label painter is requested
      Returns:
      this label painter itself
    • setObject

      public void setObject(Object aObject)
      Description copied from interface: ILcdGXYLabelPainter
      Sets the Object to be labeled by this ILcdGXYLabelPainter.
      Specified by:
      setObject in interface ILcdGXYLabelPainter
      Parameters:
      aObject - The object to be labeled.
      See Also:
    • getObject

      public Object getObject()
      Description copied from interface: ILcdGXYLabelPainter
      Gets the Object this ILcdGXYLabelPainter can label.
      Specified by:
      getObject in interface ILcdGXYLabelPainter
      Returns:
      the Object this ILcdGXYLabelPainter can label.
      See Also:
    • setLocationIndex

      public void setLocationIndex(int aLocationIndex)
      Description copied from interface: ILcdGXYLabelPainter
      Sets the index of location where to paint the label(s) of the set Object.
      Specified by:
      setLocationIndex in interface ILcdGXYLabelPainter
      Parameters:
      aLocationIndex - the index of the location. Must be between 0 and getPossibleLocationCount() - 1.
      See Also:
    • getLocationIndex

      public int getLocationIndex()
      Description copied from interface: ILcdGXYLabelPainter
      Gets the index of location where to paint the label(s) of the set Object.
      Specified by:
      getLocationIndex in interface ILcdGXYLabelPainter
      Returns:
      the index of the position. Must be between 0 and getPossibleLocationCount() - 1.
      See Also:
    • paintLabel

      public void paintLabel(Graphics aGraphics, int aMode, ILcdGXYContext aGXYContext)
      Description copied from interface: ILcdGXYLabelPainter

      Paints the label of the set Object on aGraphics. aGXYContext should contain the ILcdGXYView for which the label is painted and ILcdGXYLayer to which the object belongs

      The implementation of this method shall define how to paint the label of the set Object in the given mode, considering aGXYContext and the possible locations aLocationIndex (of multiple alternatives).

      The domain Object of the label to be painted and the location index should be set before calling this method using the setObject and setLocationIndex methods respectively.

      Specified by:
      paintLabel in interface ILcdGXYLabelPainter
      Parameters:
      aGraphics - the Graphics instance on which to paint.
      aMode - a combination of ILcdGXYLabelPainter.DEFAULT and ILcdGXYLabelPainter.SELECTED.
      aGXYContext - the ILcdGXYContext in which the label painting has to be performed.
      See Also:
    • getPossibleLocationCount

      public int getPossibleLocationCount(Graphics aGraphics)
      Description copied from interface: ILcdGXYLabelPainter
      Returns the number of possible locations where this ILcdGXYLabelPainter can paint/draw the labels of the set domain Object.

      The domain Object for which the location count is retrieved should be set before calling this method using the ILcdGXYLabelPainter.setObject(java.lang.Object) method.

      Specified by:
      getPossibleLocationCount in interface ILcdGXYLabelPainter
      Parameters:
      aGraphics - the Graphics the label will be painted on.
      Returns:
      the number of possible locations where this ILcdGXYLabelPainter can paint/draw the labels of the set Object.
      See Also:
    • labelBoundsSFCT

      public double labelBoundsSFCT(Graphics aGraphics, int aMode, ILcdGXYContext aGXYContext, Rectangle aRectangleSFCT) throws TLcdNoBoundsException
      Description copied from interface: ILcdGXYLabelPainter

      Calculates the bounds of the label that can be painted. The bounds are set as a side effect in aRectangleSFCT, the orientation of aRectangleSFCT is returned as an angle.

      The bounds represent the upper left point of the label, and a width and a height. The rotation value represents the rotation of the label bounds around the upper left point.

      The object for which the bounds are retrieved and the location index of the label should be set before calling this method using the ILcdGXYLabelPainter.setObject(java.lang.Object) and ILcdGXYLabelPainter.setLocationIndex(int) methods respectively.

      Specified by:
      labelBoundsSFCT in interface ILcdGXYLabelPainter
      Parameters:
      aGraphics - the aGraphics to consider.
      aMode - the representation mode of the label.
      aGXYContext - the ILcdGXYContext the drawing depends on.
      aRectangleSFCT - the Rectangle containing the bounds of the label in view / graphics coordinates as side effect.
      Returns:
      the angle orientation of the rectangle around the labels in RADIANs, clockwise, 0 at 3 o'clock.
      Throws:
      TLcdNoBoundsException - if the Object doesn't have any valid bounds, e.g. if it is always invisible in the current projection.
      See Also:
    • clone

      public Object clone()
      Description copied from interface: ILcdGXYLabelPainter
      Redefines Object.clone to make it public.
      Specified by:
      clone in interface ILcdGXYLabelPainter
      Specified by:
      clone in interface ILcdGXYLabelPainterProvider
      Overrides:
      clone in class Object
    • setLabelIndex

      public void setLabelIndex(int aLabelIndex)

      Sets the label. The results of any subsequent method calls to ILcdGXYLabelPainter.paintLabel(java.awt.Graphics, int, com.luciad.view.gxy.ILcdGXYContext) and ILcdGXYLabelPainter.labelBoundsSFCT(java.awt.Graphics, int, com.luciad.view.gxy.ILcdGXYContext, java.awt.Rectangle) etc. will apply to the label and sublabel indicated by this label index.

      This implementation calls the delegate label painter if it implements ILcdGXYMultiLabelPainter.

      Specified by:
      setLabelIndex in interface ILcdGXYMultiLabelPainter
      Parameters:
      aLabelIndex - The label index. This should be larger than or equal to 0 and less than the result ILcdGXYMultiLabelPainter.getLabelCount(java.awt.Graphics, com.luciad.view.gxy.ILcdGXYContext).
      See Also:
    • getLabelIndex

      public int getLabelIndex()
      Returns the index of the label that is currently painted or scheduled to paint.

      This implementation calls the delegate label painter if it implements ILcdGXYMultiLabelPainter, else it returns 0;

      Specified by:
      getLabelIndex in interface ILcdGXYMultiLabelPainter
      Returns:
      the index of the label that is currently painted or scheduled to paint.
      See Also:
    • getLabelCount

      public int getLabelCount(Graphics aGraphics, ILcdGXYContext aGXYContext)

      Returns the number of labels for the object set to this label painter.

      Note: when returning multiple (moveable) labels for the same object, it might be useful to use TLcdGXYEditControllerModel2.EDIT_WHAT_FIRST_TOUCHED_LABEL to avoid that a mouse drag moves them all together.

      This implementation calls the delegate label painter if it implements ILcdGXYMultiLabelPainter, else it returns 1;

      Specified by:
      getLabelCount in interface ILcdGXYMultiLabelPainter
      Parameters:
      aGraphics - The Graphics currently painting on
      aGXYContext - The ILcdGXYContext currently valid
      Returns:
      The number of label for the given object.
    • getSubLabelIndex

      public int getSubLabelIndex()
      Returns the index of the sublabel to paint.

      This implementation calls the delegate label painter if it implements ILcdGXYMultiLabelPainter, else it returns 0.

      Specified by:
      getSubLabelIndex in interface ILcdGXYMultiLabelPainter
      Returns:
      the index of the sublabel to paint.
      See Also:
    • setSubLabelIndex

      public void setSubLabelIndex(int aSubLabelIndex)
      Sets the sublabel index. The results of any subsequent method calls to ILcdGXYLabelPainter.paintLabel(java.awt.Graphics, int, com.luciad.view.gxy.ILcdGXYContext) and ILcdGXYLabelPainter.labelBoundsSFCT(java.awt.Graphics, int, com.luciad.view.gxy.ILcdGXYContext, java.awt.Rectangle) etc. will apply to the label and sublabel indicated by this sublabel index.

      This implementation calls the delegate label painter if it implements ILcdGXYMultiLabelPainter.

      Specified by:
      setSubLabelIndex in interface ILcdGXYMultiLabelPainter
      Parameters:
      aSubLabelIndex - The sub label index. This should be larger than or equal to 0 and less than the result ILcdGXYMultiLabelPainter.getSubLabelCount(int).
      See Also:
    • getSubLabelCount

      public int getSubLabelCount(int aLabelIndex)
      Return the number of sublabels in a label. The value should be 1 or higher.

      This implementation calls the delegate label painter if it implements ILcdGXYMultiLabelPainter, else it returns 1.

      Specified by:
      getSubLabelCount in interface ILcdGXYMultiLabelPainter
      Parameters:
      aLabelIndex - the index of the label.
      Returns:
      The number of sublabels of the label with the given index.