// 
//     Licensed to the Apache Software Foundation (ASF) under one
//     or more contributor license agreements.  See the NOTICE file
//     distributed with this work for additional information
//     regarding copyright ownership.  The ASF licenses this file
//     to you under the Apache License, Version 2.0 (the
//     "License"); you may not use this file except in compliance
//     with the License.  You may obtain a copy of the License at
// 
//       http://www.apache.org/licenses/LICENSE-2.0
// 
//     Unless required by applicable law or agreed to in writing,
//     software distributed under the License is distributed on an
//     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//     KIND, either express or implied.  See the License for the
//     specific language governing permissions and limitations
//     under the License.
//

= DevFaqPropertyEditorHints
:jbake-type: wiki
:jbake-tags: wiki, devfaq, needsreview
:jbake-status: published
:keywords: Apache NetBeans wiki DevFaqPropertyEditorHints
:description: Apache NetBeans wiki DevFaqPropertyEditorHints
:toc: left
:toc-title:
:syntax: true

== I have a Node.Property. I want to control its appearance or custom editor somehow.  What options are available?

NetBeans built-in property editors support a number of "hints" which will affect how the property editor behaves.  A few are global to all property editors;  the rest are specific to property editors for specific types.

link:http://bits.netbeans.org/dev/javadoc/org-openide-explorer/org/openide/explorer/doc-files/propertyViewCustomization.html[http://bits.netbeans.org/dev/javadoc/org-openide-explorer/org/openide/explorer/doc-files/propertyViewCustomization.html]

Note that all of these are _hints_ - a property editor is free to ignore them or not support them in the future.  However all of these have been present since NetBeans 3.6 and are _should_ still work as of NetBeans 6.9.

|===
|Property Type |Hint Name |Value Type |Effect 

|Any |`suppressCustomEditor` |`java.lang.Boolean` |Causes the property not to show a [...] button in the property sheet 

|Any |`valueIcon` |`javax.swing.Icon` |Causes the property not to show an icon beside the value (should be 16x16 or smaller) when not in edit mode 

|Most editors (string, etc.) |`htmlDisplayValue` |`java.lang.String` |An HTML-ized string which should be rendered using HTML rendering, not literally.  The subset of HTML supported by link:http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/HtmlRenderer.html[org.openide.awt.HtmlRenderer] is supported.  Generally the value should be a formatted variant of the actual value - otherwise when the user edits the value, it will suddenly seem to have changed. 

|All property editors |`nameIcon` |`java.awt.Image` or `javax.swing.Icon` |An icon which should be displayed next to the property name in the property sheet (16x16 or smaller) 

|All property editors |`helpID` |`java.lang.String` |A JavaHelp help ID to provide custom help for this property's _custom editor_ (not when the property sheet has focus) 

|All property editors |`postSetAction` |`javax.swing.Action` |An action which should be invoked after the property sheet has updated the property's value from the property editor (not very useful unless you need access to the `TableCellEditor` - not sure what this was used for) 

|`java.lang.String` and editors which show a combo box |`initialEditValue` |`java.lang.String` |A string which should be the initial value when the user starts editing, even if the actual property value is null 

|Most editors (string, etc.) |`htmlDisplayValue` |`java.lang.String` |An HTML-ized string which should be rendered using HTML rendering.  Has effect only when a cell in the property sheet or tree table or outline is _not_ in edit mode. 

|Any editor that shows a combo box in the property sheet |`canEditAsText` |`java.lang.Boolean` |Causes the combo box to be editable by text entry 

|`java.io.File` and `java.io.File[]` |_See the link:DevFaqNodePropertyForFiles.asciidoc[separate FAQ entry for File properties]_ 

|`java.lang.String[]` (array of strings) |`item.separator` |`java.lang.String` |The delimiter for splitting a user entered string into an array (the default is a , character) 

|`java.lang.Integer` |`stringKeys` |`java.lang.String[]` (array of strings) |Keys - allows an integer editor to show a combo box with strings, instead of a text editor.  If this property is used, the additional hint `intValues`; for custom code generation in the form editor, optionally `codeValues` may also be set. 

|`java.lang.Integer` |`intValues` |`int[]` (_not `java.lang.Integer`_ - array of ints) |The values that map to the strings passed in the `stringKeys` hint 

|`java.lang.Integer` |`codeValues` |`java.lang.String[]` (array of strings) |The value that should be returned by the property editor's `getJavaInitializationString()` method if the corresponding value is selected 

|`java.lang.Boolean` |`stringValues` |`java.lang.String[]` (array of strings) |Alternate names to show instead of `true` and `false` (note, this will result in a radio-button boolean editor instead of a checkbox; to use radio buttons in all boolean editors, set the system property `netbeans.ps.forceRadioButtons` to `true`) 

|`java.lang.String` |`instructions` |`java.lang.String` |Localized instructions to the user which should be visible above the text field/area in the custom editor 

|`java.lang.String` |`oneline` |`java.lang.Boolean` |Instruct the custom editor to use a single-line JTextField instead of a mult-line JTextArea 

|`java.awt.Image` |`images` |`java.awt.Image[]` |An array of images the user can select from 

|`java.awt.Image` |`values` |`java.lang.String[]` |Names for the images passed in the `images` hint 

|`java.awt.Image` |`descriptions` |`java.lang.String[]` |An array of descriptions corresponding to the array of images passed in the `images` hint 

|`java.lang.Object` (yes, you can have a property of Object and there is an editor for it - the user can select from all objects of a type in the link:DevFaqDefaultLookup.asciidoc[default Lookup] or a specific lookup [see below] using a combo box) |`superClass` |`java.lang.Class` |The superclass, passed to `Lookup.getDefault().lookupAll()` to find all possible values 

|`java.lang.Object` |`nullValue` |`java.lang.Object` (must be of the same type as the type passed in the `superClass` hint) |The value the editor should show if the property initially has a value of null 

|`java.lang.Object` |`lookup` |`org.openide.util.Lookup` |A specific lookup for this editor to query for possible values, instead of using the default lookup

=== Apache Migration Information

The content in this page was kindly donated by Oracle Corp. to the
Apache Software Foundation.

This page was exported from link:http://wiki.netbeans.org/DevFaqPropertyEditorHints[http://wiki.netbeans.org/DevFaqPropertyEditorHints] , 
that was last modified by NetBeans user Jmborer 
on 2015-02-05T15:53:11Z.

 
|===

*NOTE:* This document was automatically converted to the AsciiDoc format on 2018-02-07, and needs to be reviewed.
