# Customizing how Properties are displayed

## Customizing property editors

The core implementation provides a set of property editors for common types of properties. These editors implement the org.openide.explorer.propertysheet.ExPropertyEditor interface. It allows passing custom values to the property editor instances. This can be useful for customizing the property editors appearance.

You may want to customize the property editor behavior in different situations:

### When creating a new bean

The properties can be passed to BeanInfo. They are propagated through BeanNode to the property editor. For example if you have a java.io.File property in your bean you can use this in the BeanInfo:

    // assuming you have this line generated by the ide in the BeanInfo class
    properties[PROPERTY_testFile] = new PropertyDescriptor ( "testFile", TestBean.class, "getTestFile", "setTestFile" );
    // or alternatively if you return your own array of PropertyDescriptors for
    // your bean apply it to the appropriate PropertyDescriptor

    // you can add a custom parameter to the PropertyDescriptor
    properties[PROPERTY_testFile].setValue("files", Boolean.FALSE);
    // (the property editor will not allow selecting files)

### When creating a new node

You can directly pass the custom parameters to the properties. One example is when overriding method createSheet - you can use the property there. Or anywhere where you have access to the org.openide.nodes.Node.Property value of the property edited by the property editor.

        protected Sheet createSheet() {
            Sheet s = Sheet.createDefault();
            try {
                PropertySupport.ReadWrite p = new PropertySupport.ReadWrite (
                        "myDirectory", // NOI18N
                        java.io.File.class,
                        getString ("PROP_directory"),
                        getString ("HINT_directory")
                    ) {
                        public Object getValue () {
                            return <get the value from somewhere>
                        }

                        public void setValue (Object o) {
                            <do something with the value>
                        }
                    };
                p.setValue("files", Boolean.FALSE); // passing the custom property value here
                s.get (Sheet.PROPERTIES).put(p);
            } catch (Exception ex) {
                ErrorManager.getDefault().notify(ex);
            }
            return s;
        }

`JarDataObject` is an example from NetBeans sources, though this module is now obsolete.

`MountIterator` is an example from NetBeans sources.

### When do you want to disable/enable OK when displaying custom property editor

If you provide your own property editor implementation which supplies a GUI custom editor, that component will be displayed in a separate window with OK and Cancel buttons. Implement ExPropertyEditor on your PropertyEditor. In your implementation of ExPropertyEditor.attachEnv(), cache the instance of PropertyEnv that is passed to it. To enable the OK button, call `env.setState(PropertyEnv.STATE_VALID)`. To disable it, call `env.setState(PropertyEnv.STATE_INVALID)`.

### Custom parameters in core editors

Following table presents all property editors in core that can be used with the mechanism of passing named properties. If you pass a property that is not supported in the editor (or if you pass wrong argument type) the custom parameter is ignored.

Property type | Parameter name | Parameter type | Description
--- | --- | --- | ---
java.io.File | directories | Boolean | should directories be selectable as values for the property
files | Boolean | should files be selectable as values for the property
filter | javax.swing.filechooser.FileFilter, java.io.FileFilter, java.io.FilenameFilter | the value can be of any of the supported types and represents filter for the file dialog
currentDir | java.io.File | the dir that should be preselected when displaying the dialog
baseDir | java.io.File | an absolute directory which can be used as a base against which relative filenames should be interpreted. Incoming relative paths may be resolved against this base directory when e.g. opening a file chooser, as with the two-argument `File` constructors. Outgoing paths which can be expressed relative to this base directory may be relativized, according to the discretion of the implementation; currently files selected in the file chooser which are under the base directory (including the base directory itself) will be relativized, while others will be left absolute. The empty abstract pathname (`new File("")`) is used to represent the base directory itself.
org.openide.ServiceType | createNew | Boolean | if set to true new instances of the services are created as values, default is false
superClass | java.lang.Class | parent class of the service displayed in custom property editor, if not set org.openide.ServiceType is used
noneServiceClass | org.openide.ServiceType | service representing no service
org.openide.loaders.DataObject | currentFolder | org.openide.loaders.DataFolder | selected data object right after displaying the component
rootFolder | org.openide.loaders.DataFolder | root folder of displayed tree
rootNode | org.openide.nodes.Node | root Node of displayed tree, when not specified the filesystems repository root node is used instead
cookies | Class[] | allows you to filter DataObjects based on presence of specified cookies.
dataFilter | org.openide.loaders.DataFilter | displays data objects filtered by this filter
folderFilter | org.openide.loaders.DataFilter | should filter displayed folders
nodeAcceptor | org.openide.nodes.NodeAcceptor | filters displayed nodes by supplied acceptor
label | String | label of the tree component
title | String | title of the dialog if used as dialog
inset | Integer | width of border around the tree component
description | String | accessible description in the dialog
java.lang.Object | superClass | java.lang.Class | Should contain superclass that the value in this property is allowed to be
nullValue | Boolean, String | Either Boolean.TRUE or a String, in such case the string represents human readable name of the null value
node | org.openide.nodes.Node | A node to display as root of the custom editor
lookup | org.openide.util.Lookup | A lookup to use to query for results.
java.lang.String | instructions | String | Should contain localized instructions to the user, to be displayed in the String custom editor
oneline | Boolean | Instructs the property editor that the custom editor should present a one-line text control (JTextField or equivalent) rather than a multi-line text control (JTextArea or equivalent).
suppressCustomEditor | Boolean | Instructs the property editor to suppress the custom editor button on the property sheet.
htmlDisplayValue | String | When it is set the property editor will use htmlDisplayValue as a string to be shown to the user. Given HTML is interpreted as described in `HtmlRenderer`. So it gives a possibility to show property values e.g. in red, bold, ... font. Be aware that due to the performance reason, the given html longer than 511 bytes will not be interpretted as html. See issue 44152 for details.
java.lang.String[] | item.separator | String | Contains the separator that is used when composing individual items into `getAsText` value and parse the text when doing `setAsText`. Since version 5.7.
java.lang.Integer and primitive integer | stringKeys | String[] | Should contain internationalized strings that should be used as tags in a combo box. Number of elements must be >= 1. If this hint is supplied, the hint `intKeyValues` must also be supplied
intValues | int[] | The values the string keys correspond to. Must have the same number of elements as the string array
codeValues | String[] | Values to use in `getJavaInitializationString()` in place of hardcoding numbers (useful for constants)
java.lang.Boolean and primitive boolean | stringValues | String[] | Should contain an array of two internationalized strings to be used for user displayable text for the boolean values, in the order false, true - for example, `new String[] {"off","on"}`.

#### Custom parameters that are not tied with particular editor

These custom parameters affect the display provided by the core implementation. They can be used with any property, they are not bound to one editor.

Affected part | Parameter name | Parameter type | Description
--- | --- | --- | ---
property sheet | `inplaceEditor` | `org.openide.explorer. propertysheet.InplaceEditor` | Allows a property editor to supply an instance of the `InplaceEditor` class to be used inline in the property sheet instead of the default inline editor. Note this effect can be acheived globally for all properties of a given type by writing an `ExPropertyEditor` implementation that calls `PropertyEnv.registerInplaceEditor` in its `attachEnv()` method, and registering that property editor class using one of the mechanisms of `java.beans.PropertyEditorManager`.
`canEditAsText` | `java.lang.Boolean` | useful especially when passing value `Boolean.FALSE` - in this case disable the possibility of editing the the value as text but allows `getAsText` to return non null. Also used by passing `Boolean.TRUE` to indicate that a combo-box editor should allow the user to type their own text into the combo box.
`suppressCustomEditor` | `java.lang.Boolean` | indicates that the property sheet/property panel should not display the custom editor button even if the property editor supports one.
`postSetAction` | `javax.swing.Action` | An action that should be run if, and only if, the user updates the value of the property (or reconfirms the existing value by an explicit gesture, such as pressing enter in the property sheet with an editor opened. This is useful for code which should, for example, scroll the editor to a specific position when the user sets a value, but must differentiate between the user setting the value and the value of the property being set programmatically.
`initialEditValue` | `java.lang.String` | A value that should be used as the initial value in a property editor when the user first clicks it. Used, for example, by the form editor to suggest a generated method name for an event handler, but not display one when the properties are simply painted - it should only appear when the user starts editing. Applies to string and combo box inline editors. Note that a `Property` supplying this should check to ensure it does not already have a value that should be displayed - if the property offers this value, it will always be preferred to the property editor's value.
`longerDisplayName` | `java.lang.String` | title for the property sheet, must be passed to the bean descriptor (or node)
custom property editor display | `title` | `java.lang.String` | title of the custom property dialog, must be passed to the component itself; e.g. `panel.putClientProperty("title", "New Custom Title")`
`helpID` | `java.lang.String` | help ID in the custom property dialog

### Other available property editors

The IDE includes a number of property editors in its default property editor search path. Module authors will sometimes want to make use of the fact that such an editor exists when creating JavaBean-related code; most commonly, this means that node properties and system options may declare a property to be of a certain type without explicitly specifying a property editor for it, and rely on the search path to provide a usable property editor so that the UI will function pleasantly.

These editors are in a private package outside of the `org.openide` hierarchy, so module authors should not attempt to instantiate or otherwise customize them directly. It is possible that NetBeans may decide to remove some such editors if that is necessary for some reason; if this happens, existing module code should not break (as there are no direct references to the deleted classes), but rather properties of that type will cease to be conveniently editable by the user (system options will still be restored from disk correctly, however). If this happens, the module author will need to provide an appropriate editor for the module to be fully functional again.

A few of these editors are for classes in the Open API packages; in such cases, the documentation for the class in question may mention that there is a property editor available.

Also, the following Java platform classes currently have special NetBeans property editors which may be used via the default search path:

- `java.lang.Boolean`
- `java.awt.Color`
- `java.awt.Dimension`
- `java.awt.Font`
- `java.awt.Insets`
- `java.lang.Integer`
- `java.awt.Point`
- `java.awt.Rectangle`
- `java.io.File`
- `java.lang.Class`
- `java.lang.String`
- `java.net.URL`
- `java.util.Date`
- `java.util.Properties`
- `javax.swing.ListModel`
- `javax.swing.table.TableModel`
- all primitive wrapper types, such as `java.lang.Integer`

Beware that some of these editors may not provide the ability to edit the full range of values of the corresponding data type, as they may be specialized for the NetBeans environment.

A number of other editors and property editor extensions are available in the package `org.openide.explorer.propertysheet.editors`, but these are all deprecated; modules are encouraged to instead rely solely on the default editor search path, and to add needed configuration parameters to their `Node.Property`s or `PropertyDescriptor`s so as to be accessible from `PropertyEnv` as used by smart property editors.