Where to Find Up-to-date yFiles Information

This page is from the outdated yFiles for Java 2.13 documentation. You can find the most up-to-date documentation for all yFiles products on the yFiles documentation overview page.

Please see the following links for more information about the yFiles product family of diagramming programming libraries and corresponding yFiles products for modern web apps, for cross-platform Java(FX) applications, and for applications for the Microsoft .NET environment.

More about the yFiles product family Close X

Basic Functionality

Creating Model and View

Class OptionHandler is the settings framework's central class. It presents a kind of container to add so-called "option items" to, and notifies registered listeners of any change to the value or state of such an option item.

An option item is a descendant of abstract class OptionItem that represents a specific type of value, e.g., a boolean value, an integral value, but also a color object or an enumeration type. Example 10.1, “Option handler setup” shows the creation of a simple option handler where several option items are added to an OptionHandler instance.

Example 10.1. Option handler setup

public OptionHandler createOptionHandlerForNode(NodeRealizer nr)
{
  // Create a new OptionHandler object. 
  OptionHandler oh = new OptionHandler("Node Properties");
  // The first section holds the properties. 
  oh.useSection("Properties");
  // Add a number of different option items to this option handler. 
  oh.addString("Label", nr.getLabelText());
  oh.addColor("Fill Color", nr.getFillColor());
  oh.addDouble("Width", nr.getWidth(), 0.0, 100.0);
  
  // Return the created option handler. 
  return oh;
}

Option items are the fundamental blocks that actually hold data, and in conjunction with classes OptionHandler and OptionSection they make up the model. Presentation of the model's data and also the handling of any user interaction with it is the responsibility of so-called "editors," i.e., implementations of interface Editor. Following the MVC paradigm, multiple editors (in other words, multiple views) can be associated with an option item.

Note

An option handler itself is also represented by an editor.

The settings framework knows several ways to create an actual user interface for the editor of an option handler. With the single line presented in Example 10.2, “Showing a default modal dialog for an option handler” a default modal dialog for an option handler can be readily created and displayed. The resulting dialog features OK, Reset, and Cancel buttons.

Example 10.2. Showing a default modal dialog for an option handler

// Create a default modal dialog for the option handler. 
// If "OK" was pressed, 'result' is true. 
boolean result = oh.showEditor();

By means of an EditorFactory an editor of type Editor can be retrieved that handles an option handler's entire presentation and also the user interaction. Interface Editor defines the general contract for an option handler's editor and provides the following method to retrieve a proper javax.swing.JComponent:

JComponent getComponent()
Description Getting a proper Swing component for displaying the editor.

Note that the JComponent features all embedded item editors, however has no buttons yet.

Table 10.1, “Predefined editor factory implementations” lists the predefined editor factory implementations from package y.option. These support different presentation styles.

Table 10.1. Predefined editor factory implementations

Classname Description
DefaultEditorFactory Creates a dialog-style presentation for an option handler.
TableEditorFactory Creates a table-style presentation for an option handler.

Note

Both DefaultEditorFactory and TableEditorFactory actually return an editor that has type DefaultCompoundEditor instead of only Editor.

Figure 10.3, “Dialog presentation” shows the results of using the services of class DefaultEditorFactory for option handler presentation.

Figure 10.3. Dialog presentation

Dialog presentation.

The code snippet in Example 10.3, “Creating a dialog-based presentation of an option handler” demonstrates the use of DefaultEditorFactory to create a dialog-based presentation for an option handler.

Example 10.3. Creating a dialog-based presentation of an option handler

// 'nr' is of type NodeRealizer. 

// Create an option handler for a node's properties. 
OptionHandler oh = createOptionHandlerForNode(nr);

// Instantiate a new DefaultEditorFactory object and let it create a 
// dialog-based (as opposed to table-based) presentation, the so-called 
// "editor," for the given OptionHandler instance. 
Editor ed = new DefaultEditorFactory().createEditor(oh);

// Get the editor's JComponent that holds the actual presentation of the 
// properties. 
JComponent ohEditorComponent = ed.getComponent();

Figure 10.4, “Table presentation” shows the results of using the services of class TableEditorFactory for option handler presentation.

Figure 10.4. Table presentation

Table presentation.

The code snippet in Example 10.4, “Creating a table-based presentation of an option handler” demonstrates the use of TableEditorFactory to create a table-based presentation for an option handler.

Example 10.4. Creating a table-based presentation of an option handler

// 'nr' is of type NodeRealizer. 

// Create an option handler for a node's properties. 
OptionHandler oh = createOptionHandlerForNode(nr);

// Instantiate a new TableEditorFactory object and let it create a table-based 
// (as opposed to dialog-based) presentation, the so-called "editor," for the 
// given OptionHandler instance. 
Editor ed = new TableEditorFactory().createEditor(oh);

// Get the editor's JComponent that holds the actual presentation of the 
// properties. 
JComponent ohEditorComponent = ed.getComponent();

Synchronizing Editors and Option Items

To keep the model (option item) and its views (editors) in sync, it is necessary that any modification of values or state on either of the two sides can be propagated to the other side. Interface Editor supports different policies for explicit synchronization:

  • propagation of any modifications from view(s) to model ("push" semantics)
  • propagation of any modifications from model to view(s) ("pull" semantics)

Related to synchronization issues is resetting values to their original value to undo any modifications on the view's side. Figure 10.5, “Synchronization policies between editors and option items” depicts the synchronization policies and directions supported by the model-view architecture of editors and option items.

Figure 10.5. Synchronization policies between editors and option items

Synchronization policies.

In addition to explicit synchronization, a table-style editor created by TableEditorFactory by default also supports bi-directional implicit synchronization. Whenever a value or a state in either model or view changes, the change is immediately propagated to the other side.

Implicit synchronization can be controlled using the following methods. They are supported by class TableEditorFactory as a convenience, however, ItemEditor also provides these methods.

boolean isAutoAdopt()
boolean isAutoCommit()

void setAutoAdopt(boolean autoAdopt)
void setAutoCommit(boolean autoCommit)
Description Methods to control implicit synchronization of a table-style editor.

Defining Dependencies Between Option Items

Class ConstraintManager offers convenient means to define so-called contraints for option items. Constraints denote dependencies between option items, more specifically between the value and the state of option items. They are used to impose modifications to a "target" option item's state in response to a change in value of a "source" option item.

ConstraintManager has a number of methods that can be directly used to define a dependency to automatically enable/disable a single option item or a group of option items:

Figure 10.6, “Option handler with constrained option item” depicts the effects of constrained option items where a boolean option item is automatically disabled due to the enumeration option item's value.

Figure 10.6. Option handler with constrained option item

Dialog presentation.

The constraint to automatically enable/disable the boolean option item from Figure 10.6, “Option handler with constrained option item” is established as seen in Example 10.5, “Defining a simple constraint for option items”.

Example 10.5. Defining a simple constraint for option items

public OptionHandler createConstrainedOptionHandlerForNode(NodeRealizer nr)
{
  // Create a new OptionHandler object. 
  OptionHandler oh = new OptionHandler("Node Properties");
  // Add a number of different option items to this handler. 
  oh.addString("Label", nr.getLabelText());
  // Define a set of possible values for the enum option item. 
  String shapeType[] = {"Rectangle", "Rounded Rectangle", "Ellipse"};
  int tmp = -1;
  if (nr instanceof ShapeNodeRealizer) 
    tmp = (int)((ShapeNodeRealizer)nr).getShapeType();
  oh.addEnum("Shape Type", shapeType, tmp);
  
  // To be used as the target for a constraint. 
  oh.addBool("Make Real Circle", false);
  
  // Create a new ConstraintManager object that defines constraints for some 
  // option items. 
  ConstraintManager cm = new ConstraintManager(oh);
  cm.setEnabledOnValueEquals("Shape Type", "Ellipse", "Make Real Circle");
  
  // Return the created option handler. 
  return oh;
}

Dependencies between option items can also be defined using multiple "source" option items. The following methods take as parameter an object of type ConstraintManager.Condition that can be used to formulate a condition that combines the values of more than one option item:

The following methods from class ConstraintManager can be used to create Condition objects. Using methods from static inner class Condition which offer logical operations like AND, INVERSE, OR, and XOR, any number of conditions can furthermore be combined to create new Condition objects of increased complexity.

Note that class ConstraintManager provides its services using the general events and listener mechanism, i.e., as a listener for property change events. Using the same general mechanism, it is easily possible to have arbitrarily complex conditional modifications applied to any option item's value or state. The following methods from class OptionHandler can be used to (de)register custom property change listeners for single properties as well as all properties managed by an option handler.

Important

There is no check or validation scheme provided to ensure that the entirety of dependencies defined for an option handler's items is free from any circular dependencies.

Undefined Values in Option Items

Normally, an option item holds a value of specific type. There may arise situations, however, where an option item cannot display anything useful, and instead should show a blank entry to indicate a so-called "undefined value" state. Such situations may be:

  • The value to be presented by the option item is not compatible with its type. This may be due to the type being bounded, or consisting of only a set of distinct values (as in an enumeration option item).
  • An application has multiple values for one option item to be displayed.

The latter occurs whenever the content of an option handler is derived from multiple entities, which have different values for at least one property. A simple example would be an option handler that is used to show the size property of two nodes, and the size of the first differs from that of the second node. The option handler's option item should consequently indicate the "undefined value" state for the size property.

The following methods can be used to explicitly set this special state for an option item:

boolean isValueUndefined()
void setValueUndefined(boolean valueUndefined)
Description Getter and setter method for undefined values in option items.

Note

When using method setValueUndefined on an option item, it should be invoked last.

A special case regarding undefined values is presented in Example 10.6, “Simple OptionHandler dialog”. Class EnumOptionItem automatically assumes "undefined value" state whenever a value has been set that is not contained in the set of allowed ones. To enforce this behavior, method setValueUndefined is overridden and simply ignores arguments that contradict the current state.

Example 10.6. Simple OptionHandler dialog

public OptionHandler createEnumerationOptionHandlerForNode(NodeRealizer nr)
{
  // Create a new OptionHandler object. 
  OptionHandler oh = new OptionHandler("Node Properties");
  // Add a number of different option items to this handler. 
  oh.addString("Label", nr.getLabelText());
  // Define a set of possible values for the enum option item. 
  String shapeType[] = {"Rectangle", "Rounded Rectangle", "Ellipse"};
  int tmp = -1;
  if (nr instanceof ShapeNodeRealizer) 
    tmp = (int)((ShapeNodeRealizer)nr).getShapeType();
  oh.addEnum("Shape Type", shapeType, tmp);
  
  // Return the created option handler. 
  return oh;
}

Internationalization and Localization

The settings framework supports the task of localizing option handlers by means of so-called GUI factories, i.e., implementations of interface GuiFactory. A GUI factory can be registered with an OptionHandler object, which will then use it to replace the names of option items, enumeration values, and also the option handler's name itself by localized versions thereof. Figure 10.7, “German localized option handler” depicts the German localized version of an option handler in dialog presentation.

Figure 10.7. German localized option handler

German localized option handler.

Example 10.7, “Option handler internationalization” shows the option handler's setup where option item names, etc. are given placeholder names.

Note

To emphasize their purpose, the placeholder names consist of all-caps letters and underscores.

Example 10.7. Option handler internationalization

public OptionHandler createI18nOptionHandlerForNode(NodeRealizer nr)
{
  // Create a new OptionHandler object. 
  OptionHandler oh = new OptionHandler("NODE_PROPERTIES");
  // Add a number of different option items to this handler. 
  oh.addString("LABEL", nr.getLabelText());
  // Define a set of possible values for the enum option item. 
  String shapeType[] = {"RECTANGLE", "ROUNDED_RECTANGLE", "ELLIPSE"};
  int tmp = -1;
  if (nr instanceof ShapeNodeRealizer) 
    tmp = (int)((ShapeNodeRealizer)nr).getShapeType();
  oh.addEnum("SHAPE_TYPE", shapeType, tmp);
  
  // Return the created option handler. 
  return oh;
}

Commonly, localized text is stored in resource bundle properties files that contain key/value pairs where the value holds the actual localization. Class ResourceBundleGuiFactory loads such a resource bundle properties file and makes the contents accessible. Example 10.8, “Localization using class ResourceBundleGuiFactory” demonstrates how a ResourceBundleGuiFactory instance is used in conjunction with an option handler.

Example 10.8. Localization using class ResourceBundleGuiFactory

public void localizeOptionHandler(OptionHandler oh, 
                                  String language, String country)
{
  // Set the locale as given by 'language' and 'country'. 
  Locale.setDefault(new Locale(language, country));
  
  try {
    // Create a new ResourceBundleGuiFactory object which retrieves localized 
    // Strings from a resource bundle. 
    ResourceBundleGuiFactory rbgf = new ResourceBundleGuiFactory();
    
    // Use the GUI factory to load the information specific to this class (more 
    // specifically, its option handlers). 
    rbgf.addBundle("MyOptionHandlerLocalization");
    
    // Register the GUI factory with the option handler, so that it can 
    // retrieve the localized information. 
    oh.setGuiFactory(rbgf);
  } 
  catch (MissingResourceException mrEx) {
    System.err.println(mrEx);
  }
}

Example 10.9, “Localization bundle contents” shows the contents of both a German and an English resource bundle properties file. The placeholders that have been set in Example 10.7, “Option handler internationalization” are used to define "paths" that uniquely identify any name used within the option handler. A name's "path" is the result of a dot-separated concatenation of all placeholders of either option sections and/or option items that are "above" it in the option handler's element hierarchy, followed by the placeholder of the name itself. The root element of this element hierarchy is the option handler's name.

Note that names of enumeration values are identified using an additional qualifier, .VALUE, which is inserted after the placeholder of the enumeration option item's name.

Example 10.9. Localization bundle contents

German resource bundle file 'MyOptionHandlerLocalization_de.properties'
=======================================================================
# Sample ResourceBundle properties file

NODE_PROPERTIES = Knotenattribute
NODE_PROPERTIES.LABEL = Beschriftung
NODE_PROPERTIES.SHAPE_TYPE = Form
NODE_PROPERTIES.SHAPE_TYPE.VALUE.RECTANGLE         = Rechteck
NODE_PROPERTIES.SHAPE_TYPE.VALUE.ROUNDED_RECTANGLE = Abgerundetes Rechteck
NODE_PROPERTIES.SHAPE_TYPE.VALUE.ELLIPSE           = Ellipse
NODE_PROPERTIES.SHAPE_TYPE.TOOLTIP = Auswahl m\u00F6glicher Knotenformen

English resource bundle file 'MyOptionHandlerLocalization.properties'
=====================================================================
# Sample ResourceBundle properties file

NODE_PROPERTIES = Node Properties
NODE_PROPERTIES.LABEL = Label
NODE_PROPERTIES.SHAPE_TYPE = Shape Type
NODE_PROPERTIES.SHAPE_TYPE.VALUE.RECTANGLE         = Rectangle
NODE_PROPERTIES.SHAPE_TYPE.VALUE.ROUNDED_RECTANGLE = Rounded Rectangle
NODE_PROPERTIES.SHAPE_TYPE.VALUE.ELLIPSE           = Ellipse
NODE_PROPERTIES.SHAPE_TYPE.TOOLTIP = Selection of possible shapes

Using another qualifier, .TOOLTIP, which can be appended to any option item's path, presents a convenient possibility to add a localized tooltip text for an option item without actually defining such a text in code.

Serialization of Settings

The settings framework supports the convenient (de)serialization of an option handler's entire values. Class PropertiesIOHandler is an implementation of interface OptionsIOHandler that can be used to read settings from/write settings to a java.util.Properties object.

Example 10.10, “Reading an option handler's settings from a file” demonstrates deserialization of such a Properties object from a file.

Example 10.10. Reading an option handler's settings from a file

public Properties deserializeOH(OptionHandler oh)
{
  // Create a new Properties object. 
  Properties p = new Properties();
  
  // Use the Properties object to load the option handler's settings from a file. 
  try {
    // Initialize the given Properties object from a file with the given name. 
    FileInputStream fis = new FileInputStream("MySettings.properties");
    p.load(fis);
    fis.close();
  }
  catch (IOException ioEx) {
    ioEx.printStackTrace();
  }
  
  // Register a PropertiesIOHandler with the option handler. 
  // Upon creation, this handler is initialized with the Properties object that 
  // holds the values for the option items. 
  oh.setOptionsIOHandler(new PropertiesIOHandler(p));
  // Read the values for the option items from the Properties object (using the 
  // services of the PropertiesIOHandler). 
  oh.read();
  
  return p;
}

Example 10.11, “Writing an option handler's settings to file” demonstrates serialization of a given Properties object to a file.

Example 10.11. Writing an option handler's settings to file

public void serializeOH(OptionHandler oh, Properties p)
{
  // Install an IOHandler that 
  oh.setOptionsIOHandler(new PropertiesIOHandler(p));
  
  // Store the option handler's settings to a file. 
  try {
    // Write the given Properties object to file using the given name and 
    // header information. 
    FileOutputStream fos = new FileOutputStream("MySettings.properties");
    p.store(fos, "My saved settings.");
    fos.flush();
    fos.close();
  }
  catch (IOException ioEx) {
    ioEx.printStackTrace();
  }
}

Tutorial Demo Code

The tutorial demo application NodePropertyEditorDemo.java shows both creation and usage of an option handler, synchronization between model and view, and also use of the "undefined value" state for option items. OptionHandlerDemo.java is an extensive demo that focusses on multiple editors and their synchronization with the model.

DiagonalLayoutModule.java shows internationalization and localization (or i18n/l10n for short) aspects, as well as the (de)serialization of option handler settings. For i18n/l10n see also the resource bundle properties files DiagonalLayoutModule.properties or OptionHandlerDemo.properties.