Note
Resolvers have quite a history in QF-Test. In version 2.0 SWT support was added to QF-Test.
The ComponentNameResolver interface of previous QF-Test versions had been
built for AWT/Swing Components and was not portable. It was replaced
with the more generic NameResolver interface and associated
ResolverRegistry methods.
With QF-Test version 3.1, both NameResolver and FeatureResolver
were replaced with more elegant versions named - for lack of alternatives -
NameResolver2 and FeatureResolver2. These modern versions pass
the default name or feature determined by QF-Test directly to the resolver's method which
greatly simplifies implementation of the interface.
Similarly, the old ItemNameResolver that was only available for Swing was
replaced with the new ItemNameResolver2 with a matching
ItemValueResolver2, which work for all engines. For backwards compatibility
all the old interfaces and methods are still available and will continue to work, but
they should no longer be used in new tests and are no longer documented here.
This extension API lets you install hooks that can modify the way QF-Test recognizes and
records components and items. This is a very powerful feature that gives you
fine-grained control over QF-Test's component management. It is far less complicated than
it looks. Using the resolvers module described in subsection 39.1.10, a full featured resolver can be implemented and installed
with a minimum of code.
The following kinds of hooks are currently provided:
-
A
ClassNameResolver can change the class that QF-Test records for a
component. For Swing and SWT its use is rather limited, because it is only allowed
to return an actual base class of the component's class. However, for web
applications this is perhaps the most important of all resolvers, because it can
assign arbitrary custom class names to DOM nodes, thus turning deeply nested
hierarchies of <DIV> nodes into something useful. See also
section 6.4 about the pseudo class hierarchy for web
applications.
-
A
NameResolver2 can change (or provide) the name of a GUI element as
set with setName() for AWT/Swing, setData(name, ...) for
SWT or via the "id" attribute of a DOM node for web applications. This can be very
useful when setting names in the source code is not an option, like for third-party
code or when child components of complex components are not readily accessible. For
example, QF-Test provides a name resolver for Swing's JFileChooser dialog
which you can read more about in the Tutorial's chapter about the standard library.
-
Web
An
IdResolver can change, suppress or provide the "id" attribute of a
DOM node at an early stage which makes it very efficient.
-
A
FeatureResolver2 can provide a feature for a GUI element.
-
An
ExtraFeatureResolver can provide extra features for a GUI element.
-
An
ItemNameResolver2 can change (or provide) the textual representation
of the index for addressing a sub-item of a complex component.
-
An
ItemValueResolver2 can change (or provide) the textual
representation of the value of a sub-item of a complex component as used for a
'Check text' or retrieved via a 'Fetch text' node.
-
Swing
A
TreeTableResolver helps QF-Test recognize TreeTable components. A
TreeTable is a mixture between a table and a tree. It is not a standard Swing
component, but most TreeTables are implemented similarly by using a tree as the
renderer component for one column of the table. Once QF-Test recognizes a TreeTable as
such, it treats the row indexes of all table cells as tree indexes which is a lot
more useful in that context than standard table row indexes. In addition, geometry
information for cells in the tree column is based on tree nodes instead of table
cells.
Multiple resolvers with different tasks can be created and registered at run-time. The
respective interfaces can be implemented directly by Java classes. However, this
would make the code of your application depend on QF-Test classes. The preferred
alternative is to implement the resolver interfaces in Jython or Groovy, ideally via
the Jython resolvers module or the Groovy Resolvers class.
That way the whole mechanism can be strictly separated from the SUT and will not
interfere with the build process.
Before we explain how to (un-)register resolvers, we'll take a look at their
interfaces.
The
de.qfs.apps.qftest.extensions.ClassNameResolver
interface consists of a single method:
| |
|
|
| |
String getClassName(Object element, String name) |
| Parameters |
element |
The element to determine the class name for.
|
name |
The original class name that QF-Test would use without a resolver.
|
| Returns |
The class name to use or null if the element is not handled by this resolver.
|
| |
|
| |
After QF-Test determines the class name of a GUI element the registered
ClassNameResolvers get a chance to override this class name.
The first resolver that returns a non-null value determines the outcome. If no
resolvers are registered or all of them return null the original class name is used.
For Swing and SWT applications classes are matched based on actual class hierarchy, so
the ClassNameResolver is restricted to the actual class of the element or
any of its base classes. It can still be useful in case you don't want to activate the
option Record system class only but still record a system class or some
other general base class for certain components. Swing and SWT classes are not cached
so the resolver is called every time QF-Test needs the class of an element.
For web applications QF-Test uses a pseudo class hierarchy which is described in section 6.4. The resolver is free to return any arbitrary class name,
which QF-Test then treats like a sub-class of the element's pseudo class. For performance
reasons classes are cached for web elements so the resolver will only be called at
most once for each element.
The
de.qfs.apps.qftest.extensions.NameResolver2
interface consists of a single method:
| |
|
|
| |
String getName(Object element, String name) |
| Parameters |
element |
The element to determine the name for.
|
name |
The original name that QF-Test would use without a resolver.
|
| Returns |
The name to use or null if the element is not handled by this resolver. Returning
an empty string suppresses the original name.
|
| |
|
| |
After QF-Test determines the name of a GUI element the registered
NameResolvers get a chance to override or suppress this name. The first
resolver that returns a non-null value determines the outcome. If no resolvers are
registered or all of them return null the original name is used.
In some cases it may be desirable to suppress an element's name,
for example for names which are not unique or which - even worse -
vary depending on the situation. To do so,
getName should return the empty string.
The
de.qfs.apps.qftest.extensions.IdResolver
interface consists of a single method:
| |
|
|
| |
String getId(DomNode node, String id) |
| Parameters |
node |
The DomNode to determine the ID for.
|
id |
The "id" attribute that QF-Test has determined, possibly with suppressed numerals,
depending on the setting of the option Eliminate all numerals from 'id' attributes.
To implement the resolver based on the original "id" attribute, simply fetch this
with node.getAttribute("id").
|
| Returns |
The ID or null if the element is not handled by this resolver. Returning an empty
string will suppress or hide the node's actual ID.
|
| |
|
| |
When QF-Test registers the nodes of a web page's DOM it also caches the "id" attribute of
those nodes. Since many web applications are based on automatically generated IDs,
some processing is often required, similar to the suppression of numerals that QF-Test
does automatically, depending on the option Eliminate all numerals from 'id' attributes.
The "id" attribute of a node can show up in multiple places, most notably as the
node's 'Name' (depending on the option Turn 'id' attribute into name where "unique enough"), its 'Feature' and an
'Extra feature'. Thus it is much more efficient to implement an
IdResolver to modify the ID once, than to implement separate
Name-, Feature- and ExtraFeatureResolvers.
More importantly, changing a node's "id" attribute can have a major impact on whether
the attribute is unique and QF-Test's mechanism for using an ID as a 'Name' takes
uniqueness into account, so an IdResolver is allowed to return non-unique
IDs whereas a NameResolver2 is not.
The de.qfs.apps.qftest.extensions.FeatureResolver2
interface consists of a single method:
| |
|
|
| |
String getFeature(Object element, String feature) |
| Parameters |
element |
The element to determine the feature for.
|
feature |
The original feature that QF-Test would use without a resolver.
|
| Returns |
The feature to use or null if the element is not handled by this resolver.
Returning an empty string suppresses the original feature.
|
| |
|
| |
After QF-Test determines the feature of a GUI element the registered
FeatureResolvers get a chance to override or suppress this feature. The
first resolver that returns a non-null value determines the outcome. If no resolvers
are registered or all of them return null the original feature is used.
To suppress an element's feature, getFeature
should return the empty string.
The de.qfs.apps.qftest.extensions.ExtraFeatureResolver
interface consists of a single method:
| |
|
|
| |
ExtraFeatureSet getExtraFeatures(Object element, ExtraFeatureSet features) |
| Parameters |
element |
The element to determine the extra features for.
|
features |
The extra features determined by QF-Test itself, an empty set in case there are
none. These can be modified in place or ignored and a different ExtraFeatureSet
returned.
|
| Returns | The original features modified in place or a different set, null if the
element is not handled by this resolver. To suppress all the element's original
extra features return an empty ExtraFeatureSet.
|
| |
|
| |
After QF-Test has determined the extra features for a GUI element, the registered
ExtraFeatureResolvers will get a chance to override these features. In
contrast to other resolvers, QF-Test does not stop when the first resolver returns a
non-null value. Instead it passes its result as input to the next resolver which makes
it possible to register several ExtraFeatureResolvers that handle
different extra features. If no resolvers are registered or all of them return null,
QF-Test will proceed to use the original set.
Of course, in order to be able to implement the getExtraFeatures method properly, you
need to know the details for the API of the classes involved, namely
ExtraFeature and ExtraFeatureSet. These are explained below.
For an example implementation please see example 39.6.
Instances of the class de.qfs.apps.qftest.shared.data.ExtraFeature
represent one extra feature for a GUI element, comprising its name and value along
with information about whether the feature is expected to match, whether it is a
regular expression and whether the match should be negated. For possible states the
class defines the constants STATE_IGNORE, STATE_SHOULD_MATCH and STATE_MUST_MATCH.
| |
|
|
| |
ExtraFeature (String name, String value) |
| Parameters |
name | The name of the ExtraFeature. |
value | The value of the ExtraFeature. |
| |
ExtraFeature (int state, String name, String value) |
| Parameters |
state |
The state of the ExtraFeature. Possible values are STATE_IGNORE,
STATE_SHOULD_MATCH, STATE_MUST_MATCH.
|
name | The name of the ExtraFeature. |
value | The value of the ExtraFeature. |
| |
int getState() |
| Returns | The state of the ExtraFeature. |
| |
void setState(int state) |
| Parameters |
state | The state to set. |
| |
String getName() |
| Returns | The name of the ExtraFeature. |
| |
void setName(String name) |
| Parameters |
name | The name to set. |
| |
String getValue() |
| Returns | The value of the ExtraFeature. |
| |
void setValue(String value) |
| Parameters |
value | The value to set. |
| |
boolean getRegexp() |
| Returns | Whether the ExtraFeature's value is a regular expression. |
| |
void setRegexp(boolean regexp) |
| Parameters |
regexp | The regexp state to set. |
| |
boolean getNegate() |
| Returns | The negate state of the ExtraFeature. |
| |
void setNegate(boolean negate) |
| Parameters |
negate | The negate state to set. |
| |
|
| |
The class de.qfs.apps.qftest.shared.data.ExtraFeatureSet collects
ExtraFeatures into set:
| |
|
|
| |
ExtraFeatureSet () |
| |
void add(ExtraFeature extraFeature) |
| Parameters |
extraFeature | The extra feature to add. |
| |
ExtraFeature get(String name) |
| Parameters |
name | The name of the extra feature to get. |
| Returns |
The extra feature or null if no feature by that name is stored in the set.
|
| |
ExtraFeature remove(String name) |
| Parameters |
name | The name of the extra feature to remove. |
| Returns |
The extra feature that was removed or null if no feature by that name was stored
in the set.
|
| |
ExtraFeature[] toArray() |
| Returns | An array of the contained extra features, sorted by name. |
| |
|
| |
Note
Unless you use the resolvers module described in subsection 39.1.10, an ItemNameResolver2 must be registered with
the ItemRegistry described in subsection 39.2.4 and not
the ResolverRegistry.
The de.qfs.apps.qftest.extensions.items.ItemNameResolver2
interface consists of a single method:
| |
|
|
| |
String getItemName(Object element, Object item, String name) |
| Parameters |
element |
The GUI element to which the item belongs.
|
item |
The item to get the name for. Its type depends on the GUI element and the
registered ItemResolvers as described in subsection 39.2.5.
|
name |
The original name that QF-Test would use without a resolver.
|
| Returns |
The name to use or null if the resolver does not handle this element or item.
|
| |
|
| |
After QF-Test determines the name for an item's index the registered
ItemNameResolvers get a chance to override. The
first resolver that returns a non-null value determines the outcome. If no resolvers
are registered or all of them return null the original name is used.
Note
Unless you use the resolvers module described in subsection 39.1.10, an ItemValueResolver2 must be registered with
the ItemRegistry described in subsection 39.2.4 and not
the ResolverRegistry.
The de.qfs.apps.qftest.extensions.items.ItemValueResolver2
interface consists of a single method:
| |
|
|
| |
String getItemValue(Object element, Object item, String value) |
| Parameters |
element |
The GUI element to which the item belongs.
|
item |
The item to get the value for. Its type depends on the GUI element and the
registered ItemResolvers as described in subsection 39.2.5.
|
value |
The original value that QF-Test would use without a resolver.
|
| Returns |
The value to use or null if the resolver does not handle this element or item.
|
| |
|
| |
After QF-Test determines the value for an item's index the registered
ItemValueResolvers get a chance to override. The
first resolver that returns a non-null value determines the outcome. If no resolvers
are registered or all of them return null the original value is used.
Note This interface is irrelevant for SWT. Multi-column SWT trees
are automatically supported by QF-Test.
A
de.qfs.apps.qftest.extensions.TreeTableResolver
must implement the following two methods:
| |
|
|
| |
JTree getTree(JTable table) |
| Parameters |
table |
The JTable component to determine the tree for.
|
| Returns |
The tree or null if the JTable is a plain table and not a TreeTable.
|
| |
int getTreeColumn(JTable table) |
| Parameters |
table |
The JTable component to determine the tree's column index for.
|
| Returns |
The column index or -1 if the JTable is a plain table and not a TreeTable. The
column index must always be given in the table's model coordinates, not in view
coordinates.
|
| |
|
| |
Most TreeTableResolvers are trivial to implement. The following Jython
example works well for the org.openide.explorer.view.TreeTable component
used in the popular netBeans IDE, provided that the resolver is registered for the
TreeTable class:
|
|
class TTResolver(TreeTableResolver):
def getTree(self, table):
return table.getCellRenderer(0,0)
def getTreeColumn(self, table):
return 0 |
|
|
| | Example 39.1: TreeTableResolver for the netBeans IDE. | |
Resolvers of all kinds can be implemented in Java, Jython or Groovy and then
registered with the ResolverRegistry. Before describing this relatively
complex process in detail in the following section, we'll show some resolver examples
implemented with the help of the resolvers module provided with
QF-Test. Unless you want to understand how the resolvers module itself works
or want to implement a resolver in Java, these examples should be sufficient to get
you going and skip the following sections.
Except for the more complex ItemResolver and Checker
interfaces described in the following sections, which are not supported by the
resolvers module, a resolver consists of a single method that needs to be
implemented (one and a half in case of the TreeTableResolver). What makes
resolvers difficult at Java level is the need for describing such a method as an
interface that has to implemented by a class. Then an instance of that class has to be
created and registered for use by QF-Test. If you don't get it right on first try, that
instance has to be deregistered before a new instance from a new class can be created
and instance thereof registered, otherwise there may be interference between the two
versions of the resolver. Add some code for error handling and you've got many times
more glue code than actual "flesh".
Fortunately, methods are first level objects in Jython, as are Groovy closures. This
and the fact that the glue code is practically the same for all resolvers make it
possible to move the tedious parts out of the way into a module and concentrate on the
actual task at hand. Following is an example of a NameResolver2 for
JMenuItems that promotes the label of a menu item to a component name for
menus that have no name of their own:
|
|
def getName(menuItem, name):
if not name:
return menuItem.getLabel()
resolvers.addNameResolver2("menuItems", getName,
"javax.swing.JMenuItem") |
|
|
| | Example 39.2: Simple Jython NameResolver2 for JMenuItems | |
As you see it took only four lines of code to do that. The first three lines define a
getName method for the resolver. The fourth line calls the
addNameResolver2 function of the resolvers module which is
always automatically available in Jython 'SUT script' nodes. The three
parameters are an identifier for the resolver, the actual method and one or more
optional targets, in this case the class name of the components for which we want to
register the resolver.
Give it a try. Copy the example above into an 'SUT script' node and execute
it. If your application is based on SWT instead of Swing, replace
getLabel() with getText() and
javax.swing.JMenuItem with org.eclipse.swt.MenuItem. Then
record some menu actions into a new, empty test-suite. You'll find that all recorded
menu item components without their own name will now have names set according to their
labels. If setName is not used in your application and the labels of menu
items are more or less static while the structure of the items changes often, this
could even be a very useful thing. To install the resolver permanently, just move the
'SUT script' node right after the 'Wait for client to connect' node of your SUT startup
sequence.
The same can be done in Groovy via the resolvers object that is also
always available and has the same API. It expects a closure to create a resolver from
as follows:
|
|
def getName = {menuItem, name ->
if (name == null) {
return menuItem.getLabel()
}
}
resolvers.addNameResolver2("menuItems", getName,
"javax.swing.JMenuItem") |
|
|
| | Example 39.3: Simple Groovy NameResolver2 for JMenuItems | |
It is possible to register a resolver for multiple component classes at once:
|
|
def getName(com, name):
return com.getLabel()
resolvers.addNameResolver2("labels", getName, "javax.swing.JLabel",
"javax.swing.AbstractButton") |
|
|
| | Example 39.4: Registering a NameResolver2 for multiple target classes | |
The other resolvers work similarly. Following is an example for an
ItemNameResolver2 that makes the ID of a JTable column
available as an item index:
|
|
def getColumnId(table, item, name):
if item[1] < 0: # whole column addressed
id = table.getColumnModel().getColumn(i).getIdentifier()
if id:
return str(id)
resolvers.addItemNameResolver2("tableColumnId", getColumnId,
"javax.swing.table.TableColumn") |
|
|
| | Example 39.5: ItemNameResolver for JTable columns | |
FeatureResolvers and ExtraFeatureResolvers are handled just
like NameResolvers, but ExtraFeatureResolvers are a bit more
complex, though not overly so, as the following example shows:
|
|
from de.qfs.apps.qftest.shared.data import ExtraFeature, ExtraFeatureSet
def getExtraFeatures(node, features):
features.add(ExtraFeature(ExtraFeature.STATE_SHOULD_MATCH,
"myname", "myvalue"))
return features
resolvers.addExtraFeatureResolver("silly example", getExtraFeatures,
"INPUT") |
|
|
| | Example 39.6:
ExtraFeatureResolver that adds an extra feature to all INPUT nodes
| |
TreeTableResolvers for Swing
TreeTables are created and registered in a slightly different way:
|
|
def getTree(table):
return table.getTree()
def getColumn(table):
return 0
resolvers.addTreeTableResolver("treeTable", getTree, getColumn,
"my.package.TreeTable") |
|
|
| | Example 39.7:
TreeTableResolver for Swing TreeTable with optional
getColumn method
| |
The above example shows a typical TreeTableResolver. Since almost all
TreeTables display the tree in the first column of the table, the
getColumn method is optional. If none is provided a default
implementation for the first column is used:
|
|
def getTree(table):
return table.getTree()
resolvers.addTreeTableResolver("treeTable", getTree, None,
"my.package.TreeTable") |
|
|
| | Example 39.8: Simplified TreeTableResolver | |
If no dedicated getTree method is available, the cell renderer of the column
containing the tree (typically 0) might work, as it is typically derived from JTree.
|
|
def getTree(table):
return table.getCellRenderer(0,0)
resolvers.addTreeTableResolver("treeTable", getTree,
"my.package.TreeTable") |
|
|
| | Example 39.9: Simple TreeTableResolver using getCellRenderer method | |
Following is the complete API of the resolvers module:
| |
|
|
| |
addNameResolver2(String name, Method method, Object target=None, ...)
|
| Parameters |
name | The name under which to register the resolver. |
method | The method that implements the resolver's
getName() method. |
target |
One or more optional targets to register the resolver for. Each can be any of the
following:
- An individual component
- The fully qualified name of a class
If no target is given a global resolver for all components is registered.
|
| |
addIdResolver(String name, Method method, Object target=None, ...)
|
| Parameters |
name | The name under which to register the resolver. |
method | The method that implements the resolver's
getId() method. |
target |
One or more optional targets to register the resolver for. Each can be any of the
following:
- An individual component
- The fully qualified name of a class
If no target is given a global resolver for all components is registered.
|
| |
addFeatureResolver2(String name, Method method, Object target=None, ...)
|
| Parameters |
name | The name under which to register the resolver. |
method | The method that implements the resolver's
getFeature() method. |
target |
One or more optional targets to register the resolver for. Each can be any of the
following:
- An individual component
- The fully qualified name of a class
If no target is given a global resolver for all components is registered.
|
| |
addExtraFeatureResolver(String name, Method method, Object target=None, ...)
|
| Parameters |
name | The name under which to register the resolver. |
method | The method that implements the resolver's
getExtraFeature() method. |
target |
One or more optional targets to register the resolver for. Each can be any of the
following:
- An individual component
- The fully qualified name of a class
If no target is given a global resolver for all components is registered.
|
| |
addItemNameResolver2(String name, Method method, Object target=None, ...)
|
| Parameters |
name | The name under which to register the resolver. |
method | The method that implements the resolver's
getItemName() method. |
target |
One or more optional targets to register the resolver for. Each can be any of the
following:
- An individual component
- The fully qualified name of a class
If no target is given a global resolver for all components is registered.
|
| |
addItemValueResolver2(String name, Method method, Object target=None, ...)
|
| Parameters |
name | The name under which to register the resolver. |
method | The method that implements the resolver's
getItemValue() method. |
target |
One or more optional targets to register the resolver for. Each can be any of the
following:
- An individual component
- The fully qualified name of a class
If no target is given a global resolver for all components is registered.
|
| |
addTreeTableResolver(String name, Method getTable, Method getColumn=None, Object target=None)
|
| Parameters |
name | The name under which to register the resolver. |
getTable | The method that implements the resolver's
getTable() method. |
getColumn | The method that implements the resolver's
getColumn() method. |
target |
One optional target to register the resolver for. It can be any of the
following:
- An individual component
- The fully qualified name of a class
If no target is given a global resolver for all components is registered.
|
| |
addClassNameResolver(String name, Method method, Object target=None, ...)
|
| Parameters |
name | The name under which to register the resolver. |
method | The method that implements the resolver's
getClassName() method. |
target |
One or more optional targets to register the resolver for. Each can be any of the
following:
- An individual component
- The fully qualified name of a class
If no target is given a global resolver for all components is registered.
|
| |
removeResolver(String name)
|
| Parameters |
name | The name under which the resolver was registered. |
| |
|
| |
Now it is time to take a look at the Java API for registering resolvers on which the
resolvers module is built. The singleton class
de.qfs.apps.qftest.extensions.ResolverRegistry is the central agent for
registering and removing name resolvers.
All kinds of resolvers can be registered on individual components
or on classes. Resolvers registered on a component will only be
called if their service is required for that specific component.
Resolvers registered on a class will be called for every object of that class
or a class derived from it.
NameResolvers, FeatureResolvers and
TreeTableResolvers can also be registered globally so they will be called
for each and every name or feature. This is similar to but more efficient than
registering them on the java.lang.Object class.
If multiple resolvers are registered globally or registered on the same object or
class, the resolver added last will be called first.
The ResolverRegistry API is pretty straightforward:
| |
|
|
| |
static ResolverRegistry instance() |
| Returns | The singleton ResolverRegistry instance. |
| |
static String getElementName(Object element) |
| Parameters |
element | The element to get the name for. |
| Returns |
The name of the element or null if a trivial or special name is
suppressed.
|
| |
static boolean isInstance(Object object, String className) |
| Parameters |
object | The object to check. |
className | The name of the class to test for. |
| Returns |
True if the object is an instance of the given class.
|
| |
void registerNameResolver2(Object element, NameResolver2 resolver) |
| Parameters |
element |
The GUI element to register for.
|
resolver |
The resolver to register.
|
| |
void unregisterNameResolver2(Object element, NameResolver2 resolver) |
| Parameters |
element |
The GUI element to unregister for.
|
resolver |
The resolver to unregister.
|
| |
void registerNameResolver2(String clazz, NameResolver2 resolver) |
| Parameters |
clazz |
The name of the class to register for.
|
resolver |
The resolver to register.
|
| |
void unregisterNameResolver2(String clazz, NameResolver2 resolver) |
| Parameters |
clazz |
The name of the class to unregister for.
|
resolver |
The resolver to unregister.
|
| |
void registerNameResolver2(NameResolver2 resolver) |
| Parameters |
resolver |
The resolver to register.
|
| |
void unregisterNameResolver2(NameResolver2 resolver) |
| Parameters |
resolver |
The resolver to unregister.
|
| |
void registerIdResolver(Object element, IdResolver resolver) |
| Parameters |
element |
The GUI element to register for.
|
resolver |
The resolver to register.
|
| |
void unregisterIdResolver(Object element, IdResolver resolver) |
| Parameters |
element |
The GUI element to unregister for.
|
resolver |
The resolver to unregister.
|
| |
void registerIdResolver(String clazz, IdResolver resolver) |
| Parameters |
clazz |
The name of the class to register for.
|
resolver |
The resolver to register.
|
| |
void unregisterIdResolver(String clazz, IdResolver resolver) |
| Parameters |
clazz |
The name of the class to unregister for.
|
resolver |
The resolver to unregister.
|
| |
void registerIdResolver(IdResolver resolver) |
| Parameters |
resolver |
The resolver to register.
|
| |
void unregisterIdResolver(IdResolver resolver) |
| Parameters |
resolver |
The resolver to unregister.
|
| |
void registerFeatureResolver2(Object element, FeatureResolver2 resolver) |
| Parameters |
element |
The GUI element to register for.
|
resolver |
The resolver to register.
|
| |
void unregisterFeatureResolver2(Object element, FeatureResolver2 resolver) |
| Parameters |
element |
The GUI element to unregister for.
|
resolver |
The resolver to unregister.
|
| |
void registerFeatureResolver2(String clazz, FeatureResolver2 resolver) |
| Parameters |
clazz |
The name of the class to register for.
|
resolver |
The resolver to register.
|
| |
void unregisterFeatureResolver2(String clazz, FeatureResolver2 resolver) |
| Parameters |
clazz |
The name of the class to unregister for.
|
resolver |
The resolver to unregister.
|
| |
void registerFeatureResolver2(FeatureResolver2 resolver) |
| Parameters |
resolver |
The resolver to register.
|
| |
void unregisterFeatureResolver2(FeatureResolver2 resolver) |
| Parameters |
resolver |
The resolver to unregister.
|
| |
void registerExtraFeatureResolver(Object element, ExtraFeatureResolver resolver) |
| Parameters |
element |
The GUI element to register for.
|
resolver |
The resolver to register.
|
| |
void unregisterExtraFeatureResolver(Object element, ExtraFeatureResolver resolver) |
| Parameters |
element |
The GUI element to unregister for.
|
resolver |
The resolver to unregister.
|
| |
void registerExtraFeatureResolver(String clazz, ExtraFeatureResolver resolver) |
| Parameters |
clazz |
The name of the class to register for.
|
resolver |
The resolver to register.
|
| |
void unregisterExtraFeatureResolver(String clazz, ExtraFeatureResolver resolver) |
| Parameters |
clazz |
The name of the class to unregister for.
|
resolver |
The resolver to unregister.
|
| |
void registerExtraFeatureResolver(ExtraFeatureResolver resolver) |
| Parameters |
resolver |
The resolver to register.
|
| |
void unregisterExtraFeatureResolver(ExtraFeatureResolver resolver) |
| Parameters |
resolver |
The resolver to unregister.
|
| |
void registerTreeTableResolver(Component com, TreeTableResolver resolver) |
| Parameters |
com |
The component to register for.
|
resolver |
The resolver to register.
|
| |
void unregisterTreeTableResolver(Component com, TreeTableResolver resolver) |
| Parameters |
com |
The component to unregister for.
|
resolver |
The resolver to unregister.
|
| |
void registerTreeTableResolver(String clazz, TreeTableResolver resolver) |
| Parameters |
clazz |
The name of the class to register for.
|
resolver |
The resolver to register.
|
| |
void unregisterTreeTableResolver(String clazz, TreeTableResolver resolver) |
| Parameters |
clazz |
The name of the class to unregister for.
|
resolver |
The resolver to unregister.
|
| |
void registerTreeTableResolver(TreeTableResolver resolver) |
| Parameters |
resolver |
The resolver to register.
|
| |
void unregisterTreeTableResolver(TreeTableResolver resolver) |
| Parameters |
resolver |
The resolver to unregister.
|
| |
void unregisterResolvers(Object element) |
| Parameters |
element |
The element to unregister for.
|
| |
void unregisterResolvers(String clazz) |
| Parameters |
clazz |
The name of the class to unregister for.
|
| |
|
| |
All exceptions thrown inside a name resolver will be caught and handled by the
ResolverRegistry. However, instead of dumping a stack trace, the registry
will only print a short message like "Exception inside NameResolver2" because some
resolvers may be called very often, so for a buggy resolver printing a stack trace for
every error could flood the net and the client terminal. Therefore name resolvers
should include their own error handling. This can still generate a lot of output in
some cases, but especially for scripts the output will be more useful than a Java
stack trace.