This guide uses the APP-6A symbology to describe the military symbology functionality. The functionality available for MIL-STD 2525b is exactly the same.

You just need to substitute APP6A with MS2525b in all class names and method names, and app6a with milstd2525b in all package names.

In addition, the LuciadLightspeed support for APP-6B, APP-6C, APP-6D, MIL-STD 2525c and MIL-STD 2525d standards relies on the same APIs as its support for the APP-6A and MIL-STD 2525b standards. This means that you can use the APP-6A API in the same way for APP-6B, APP-6C and APP-6D symbology, and that you can use the MIL-STD 2525b API for MIL-STD 2525c and MIL-STD 2525d symbology.

This guide discusses the customizer tools offered by LuciadLightspeed to set and change the properties of military symbols.

How to customize a symbol

If you want to change some symbol properties in your application logic, or if you are creating a GUI customizer component to let users change those symbol properties , you can make use of the convenience methods offered by TLcdEditableAPP6AObject and TLcdEditableMS2525bObject.

These classes allow you to retrieve or set a value, and enumerate the possible values for many symbol properties, such as the symbol’s affiliation or its country, or even the symbol’s type. For example, you can change a weather symbol like the jet stream symbol into a war fighting symbol like air track.

If your domain object does not extend from TLcdEditableAPP6AObject or TLcdEditableMS2525bObject, you can create a temporary instance of one of these classes based on their SIDC symbol code, perform the necessary modifications and then change your SIDC. See ILcdAPP6ACoded.getAPP6ACode to learn how to retrieve the SIDC.

The easiest way to check which SIDC properties are applicable to a symbol is by calling the getPossibleSIDCModifiers method. Next to the symbol modifiers, your symbol also has text modifiers. These text modifiers have been defined in addition to typical symbol properties such as affiliation or status. The getPossibleTextModifiers method allows you to enumerate and inspect the modifiers that are available for your symbol. The following snippet shows an example of this.

Program: Customizing an APP-6C object
// 1) create a APP-6C "fixed wing - reconnaissance" object,
// based on the code from the specification or from a TLcdAPP6ANode
TLcdEditableAPP6AObject object = new TLcdEditableAPP6AObject("10000100001101110000", ELcdAPP6Standard.APP_6C);

// 2) query the available SIDC modifiers
System.out.println("available modifiers:");
for (TLcdEditableAPP6AObject.TextModifier modifier : object.getPossibleSIDCModifiers()) {
  System.out.println(modifier.getName());
}

// 3) query the possible values of the "standardIdentity2" modifier.
//    This returns a collection containing, among others, the value "Friend".
System.out.println("available values:");
for (String value : object.getTextModifier("standardIdentity2").getPossibleValues()) {
  System.out.println(value);
}

// 4) change the "standardIdentity2" modifier.
object.putTextModifier("standardIdentity2", "Friend");
// The "standardIdentity2" modifier is encoded in the fourth digit of the symbol code,
// so the following statement is true:
"10020100001101110000".equals(object.getFormattedSIDC());

// 5) change the "AdditionalInformation" modifier.
//    This modifier is stored as a separate text modifier.
object.putTextModifier("AdditionalInformation", "this is an example symbol");

Refer to the Define military symbols guide for more information about the SIDC and text modifiers. The next section shows how to use these methods to create your own GUI customizer component.

Customizing symbols with the sample customizer

The samples contain a compact and fully customizable GUI component for all supported symbol properties. This customizer is demonstrated in the both the GXY view and Lightspeed view symbology samples, and works as shown in Figure 1, “The sample customizer”.

sample customizer
Figure 1. The sample customizer

You can create such a customizer using the SymbolCustomizerFactory class. The resulting component consists of several AbstractSymbolCustomizer implementations, each of which binds a specific symbol property to a GUI widget.

Most SymbolCustomizer implementations are simple combo boxes, like SymbolComboBoxCustomizer, or text fields, like SymbolTextFieldCustomizer. The SymbolHierarchyCustomizer, on the other hand, is a special implementation that allows users to change the type of the symbol. Program: Connecting a search widget to a customizer that changes the symbol type shows how changing the hierarchy type of a symbol works. The customizer creates a symbol selection widget as the GUI component. When users select a symbol type from the hierarchy, the applyChange method is called with the logic to apply and undo the symbol change.

Program: Connecting a search widget to a customizer that changes the symbol type (from samples/symbology/common/gui/customizer/SymbolHierarchyCustomizer)
fBar = new SymbolSelectionBar(EnumSet.of(SymbolSelectionBar.BarComponent.BROWSE), getSymbology(), aHierarchyFilter, aStringTranslator) {
  @Override
  protected void symbolSelected(final String aSIDC) {
    final Object symbol = getSymbol();
    // only apply valid changes
    if (aSIDC == null || symbol == null) {
      return;
    }
    final String oldValue = MilitarySymbolFacade.getSIDC(symbol);
    if ((!aSIDC.equals(oldValue))) {
      // the apply change method takes care of model locking, undoables,
      // and the firing of model and change events.
      applyChange(new Runnable() {
                    @Override
                    public void run() {
                      MilitarySymbolFacade.changeHierarchy(symbol, aSIDC);
                    }
                  },
                  new Runnable() {
                    @Override
                    public void run() {
                      MilitarySymbolFacade.changeHierarchy(symbol, oldValue);
                    }
                  }
      );
    }
  }

SymbolHierarchyCustomizer also allows marking the symbol as a favorite object. You can link a collection of favorites to a toolbar to allow users to rapidly select and create the symbols from this collection.

Customizing symbols with a dialog-based customizer

The LuciadLightspeed MIL-STD 2525b and APP-6A APIs also contain java.beans.Customizer implementations for the creation and customization of symbols:

  • com.luciad.symbology.milstd2525b.view.swing.TLcdMS2525bObjectCustomizer

  • com.luciad.symbology.app6a.view.swing.TLcdAPP6AObjectCustomizer.

Both classes are extensions of the Swing class javax.swing.JPanel, so they can be used in any Swing-based GUI. Figure 2, “APP-6A customizer” contains a screenshot of the APP-6A customizer placed into a javax.swing.JDialog, together with a confirmation button.

app6a customizer
Figure 2. APP-6A customizer

Each customizer allows the user to choose a symbol from a hierarchical tree and further customize its properties: affiliation, status, country, order of battle, echelon, several style options and the available text modifiers.

Removing or replacing child customizers

Each property in the customizer, like the echelon tree, is represented by a separate customizer. These child customizers are created by the protected method createCustomizer(int) at the construction time of a TLcdMS2525bObjectCustomizer or TLcdAPP6AObjectCustomizer instance. The argument of this method is an ID that uniquely defines the customizer. The possible values for the customizer ID argument are listed as constants in TLcdMS2525bObjectCustomizer and TLcdAPP6AObjectCustomizer. You can override this method to create your own customizer for a given ID, or to prevent the display of its default customizer by returning null.

Changing the layout

Apart from the method createCustomizer(int), the classes TLcdMS2525bObjectCustomizer and TLcdAPP6AObjectCustomizer offer a protected method insertCustomizers(int[], Customizer[]) to build the GUI. The second argument represents an array of java.beans.Customizer instances that must be present in the GUI. This requires that each customizer also inherits from the java.awt.Component class, in compliance with the general guideline for java.beans.Customizer implementations. The int array is used to identify each customizer. You can override this method to build a custom layout for TLcdMS2525bObjectCustomizer and TLcdAPP6AObjectCustomizer.

Enumerating and restricting the available symbols

The customizers use the TLcdAPP6ANode and TLcdMS2525bNode trees to enumerate the symbols of a particular symbology. If you want to restrict the collection of symbols available for selection in the symbol tree, you can initialize the sample-based and dialog-based customizers with a com.luciad.util.ILcdFilter. The method accept(Object) is invoked with a code mask of each tree element, "W*A*------*" for example. If the filter returns false, the symbol will not be available in the customizer.

Providing multilingual support

To provide support for different languages, you can configure the customizers with a com.luciad.util.ILcdStringTranslator. The method translate(String) is invoked for each label in the GUI - not for the contents of trees or combo boxes. This enables the user to translate the label into a language other than English.