11.1 Column component constraints.
The Column component has support for several constraints: 1) Required property. When set to true, a row cannot be posted unless the value in the column has been set. 2) Min/Max properties. When these are set, the string property values are parsed using the Column.DisplayMask property into an internal representation that is used to apply the Min/Max constraint. 3) Default property. When new rows are added, this value is filled in instead of a Variant.UNASSIGED_NULL. Like Min/Max properties, this value is parsed using the Column.DisplayMask property. 4) ReadOnly property. This prevents edits through DataSet APIs. 5) Editable property. This allows edits through the DataSet APIs (programatically), but data-aware JBCL controls will treat this as a ReadOnly column.
11.2 Custom constraints.
To apply custom constraints, there is a Column.validate() event that can be wired through the JBuilder property inspector. There are also several editing events for StorageDataSets that can be used for row level constraints.
11.3 Edit and display masks.
All formatting and parsing of data in the DataSet package is controlled by the VariantFormatter class, which is uniquely defined for every Column in a DataSet. To simplify the use of this class, there is also a String property (displayMask) for each Column, which will construct a VariantFormatter for its Column using the basic "pattern" syntax defined in the JDK's Format (java.text) classes.
There are actually four distinct kinds of patterns:
1) Numeric
2) Date and time
3) String
4) Boolean
The syntax for each of these pattern types can be found in the help system, but are essentially the same as those described in the corresponding java.text classes in the JDK.
The default VariantFormatter implementations for each Column are normally provided by some simple implementations were written to be fast. Formats which might include punctuation characters (such as a comma for separating groups of thousands, or a decimal point) explicitly set the displayMask in order to use the more sophisticated formatting methods.
Basic data display and data entry is controlled by the Column displayMask property.
Advanced keystroke-by-keystroke data entry is controlled by the (optional) Column editMask property.
Importing and exporting a text file is controlled by the exportDisplayMask property.
Setting a displayMask (or editMask or exportDisplayMask) to an empty string or null has special meaning; it selects its pattern from the default Locale. This is actually the default behavior of JBuilder for fields which are of type Date, Time, Timestamp, BigDecimal, Double, etc. By doing this, JBuilder assures that an app using the defaults will automatically select the proper display format when it finds itself running under a different Locale.
Any app which wants to override this behavior should explicitly set the displayMask property in the appropriate Column objects of a DataSet.
11.4 Error handling.
With programmatic usage of the DataExpress components, most error handling is surfaced through checked Java exceptions. All DataExpress exception classes are DataSetExceptions or derive from the DataSetException class . DataSetExceptions can have other types of Exceptions (i.e. IOException and SQLException) chained to them. In these cases, the DataSetException has an appropriate message that describes the error from the perspective of a higher level API. The DataSetException method getExceptionChain() can be used to obtain any chained exceptions. The chained exceptions (singly linked list) are non-DataSetExceptions that were encountered at a lower level API.
The dataset package has some built-in DataSetException handling support for JBCL data-aware controls. The controls themselves don't know what a DataSetException is. They just expect all of their data update and access operations to work. The built-in DataSetException handling support for JBCL data-aware controls works as follows: If a control performs an operation that causes a DataSetException to occur, an Exception dialog is presented with the message of the error. This Exception Dialog has a details button that will display the stack trace. The Exception Dialog will also show a previous/next button if the DataSetException has chained exceptions. If the exception thrown is ValidationException (an extension of DataSetException), the Exception Dialog will only be shown if there are no StausEvent listeners on the DataSet. ValidationExceptions are caused by constraint violations like min, max, edit mask, updating read only columns, etc. If a StatusBarControl is wired to a DataSet, it will automatically wire itself as a StatusEvent listener. This way, the user will see the constraint violations in the status bar.
11.5 Overriding default DataSetException handling for controls
As mentioned before, If a StatusEvent Listener is added to the DataSet, ValidationExceptions will not be presented with an Exception Dialog. DataSetException handling for controls can be disabled for a particular DataSet by setting the DataSet DisplayErrors property to false. Complete control for DataSetException handling to all controls and DataSets can be accomplished by wiring the static ExceptionEvent listener off of DataSetException.
Most of the dataset events throw DataSetException. This is very useful when your event handlers use DataSet APIs (which usually throw DataSetException). This keeps you from having to code try/catch blocks for all the event handlers you write. The before events off of EditListener (adding, deleting, updating, canceling, modifying, inserting) can all be denied by throwing an exception that derives from the Java Exception class. If an exception thrown from these event handlers does not derive from DataSetException, it is chained to a generic ValidationException, with an error code of ValidationException.APPLICATION_ERROR. The message from the application exception is copied to this newly created ValidationException. The application exception is then chained to the newly created ValidationException so it is not thrown away. Finally, the ValidationException is thrown. What is nice about this is that applications can throw an exception in these event handlers with a custom message, and it will be handled by the built-in DataExpress error handling. So, if there is a StatusBarControl, the message from the application's Exception will show up in the status line.