FeaturesPluginsDocs & SupportCommunityPartners

Yet Another Reusable Display Architecture

$Revision: 1.29 $
Changes: available in CVS
Status: draft

Problem

At least since release 3.2 of the NetBeans IDE, but very likely long time ago people writing NetBeans modules were struggling with presentation of various data structures and by finding ways to make this work in modular NetBeans architecture.

Local solutions were always found when they were really needed, but they differ in their appearance, APIs and capabilities. They are written by different groups and as such they just increase the amount of code we have to maintain, fix and we are not able to reuse it.

A general and reusable display framework would simplify the maintanance and provided a guidance to all module writers and NetBeans API users. It would allow them to reach the best quality code with less effort and prevent needless reinvetion of a new wheel.

History

This is not the first effort to design such general reusable display framework like this. After release of NetBeans 3.2 Petr Hrebejk started an ambicious project with the goal to improve our existing Nodes API and provide solution to problems that were hard to solve then named Looks (see his original document).

The vision of Looks is described in an overview describing problems that have to be solved and solution we can get. The design is covered in a separate document and there is list of known problems in his solution.

Later more projects based on this idea crystalized. The looks matured (see issue 18177), they were simplified (see enode) or completely carbonized, formed a base for a paper about clasification frameworks, but none of these projects ever made it into NetBeans release. The only one that made it into regular build is viewmodel which managed to sneak in as a support library for new debugger APIs. All of these projects solve similar set of problems each using a bit different style each having its weaker and stronger aspects and admirers.

A search for a common replacement, that is going to happen on this page, thus shall start with with thoughtful formulation of goals and needs:

Goal

Provide a general, extensible and resuable infrastructure that will be capable of replacing the current local solutions and will provide easy adoption and migration path to be in wide use in near promotion.

What Our Developers Say

  1. I need to enhance a visualization provided by other module - add and remove actions into popup menu, reorder existing ones, change icon, annotate display name, add additional or remove some children and best of all this shall be done without the dependencies between those modules
  2. Extensions and implementations of debugger modules (JPDA, JSP debuggers, J2EE) need to customize hierarchy of nodes in various debugger views.
    • JSP debugger takes all nodes from the Locals view and packages them into several groups (Implicit variables, etc.) thus changing hierarchy of nodes completely
    • EJB module takes nodes from Call stack view and hides stack frames from application server to clear the view to show only important information
    • JPDA debugger alters names of Hashtable entries to (key=>value)
  3. I need to allow other modules to enhance my view - moreover I may need more than one presentation of my data (either in list or in a tree, with or without the root being visible)
  4. XML module is extensible by external modules in a way that they can provide actions that act on XML nodes. Furthermore, providers of XML actions provide actions based on the XML doctype which is supplied to them by the XML module when they are asked for actions.
  5. A module has to have the control of what extensions will be applied to their nodes. For example, the UML Element node might choose to include in its popup menu actions from VCS module but exclude actions from Code Beautifier module.
  6. I need colorful visualization of element - different fonts, different colors, styles, stroked text, etc.
  7. I need a special capability to be negotiated - like in case of html display name or pluggable functionality for shortening descriptions.
  8. I need to react to changes in list of modules - when a new module providing additions to my view is installed or one of them is disabled I need my view to be updated accordingly.
  9. When more elements is selected the actions invoked need to act on all of them even if they are provided by different modules, in the best case atomically on all of them at once.
  10. New ways to look at java sources are needed. Just list of methods and fields (plus beans view sometimes) is not enough. In J2EE 1.5 the methods will be annotateable with annotations and some of them will have special meaning. We need to enhance java classes in J2EE 1.5 project to show list of bussiness methods, factory methods, etc. But maybe a special filter for navigator view would be enough as well.
  11. In case of an XML file representing file system, the XML module can display a given XML file as a normal XML file (children of the node are XML elements) or it can display it as a file system (children of the node are file objects). User can choose which view is more appropriate and can switch between them.
  12. The external module must be able to change properties of elements. This applies both to property sheet as well as to tree table view, where also the order is significant and is subject to customization as well.
  13. Extensions should be allowed to extend node properties and to add more column to tables and tree tables. Native debuggers would, for example, add a new property PC (program counter) to call stack or thread views
  14. Whenever a change in certain capabilities of an object happens - like change of a property or name or set of subchildren - the view has to be effectively updated to reflect the current state.
  15. For my navigator module I will need to negotiate following capabilities: The default action on an element or what shall happen during drag and drop. It is likely that in future we will need really big tooltips (defacto own window with scrollbars, hyperlinks, etc.) showing at position specified by the module. Also various scrollbar policies will need to be negotiated with providing modules. There will be need for a way to display the empty state (like no members or empty java class). The component with filters will also need to change in navigator and follow the selection of active document.
  16. JPDA debugger extends integer variables' popup menus with Display As Dec,Hex,Oct,Bin menu.
  17. I need to pass thru the context in which I am asking for special capability - the project I am in, the DOCTYPE of XML document, instance of class in which the method is supposed to be called, etc.
  18. I need to allow extensibility of projects UI - for example there is a need for a struts project to enhance the standard web project with new nodes.
  19. There is a need for fast search - after pressing a key the window where user can type shows and either the selection changes according to typed text or only elements that match stay visible.
  20. Do not waste our memory - Right now, when one wants to modify behaviour provided by other module, the common technique is to use FilterNode over node provided by other module. This is not very programmer and memory friendly and given the fact that this is common task, it shall be supporter in much simpler way.
  21. I really need some support for writing reponsive views - I would very warmly welcome a standardized way to write responsive UI application. It is pretty clear that as soon as I start to delegate to 3rd party modules, my component will start to underperform. I'd like to reuse simple and standard infrastracture that would deal with such situation and prevent UI freezes.
  22. Version control systems need to be able to present versioning status (up to date, modified, removed, etc.) of files. These statuses are expected to be visible in the following places:
    • nodes in file explorer – file's label and/or icon is changed according to its status in VCS. Common practice is to alter color or text of file and folders labels
    • nodes in logical views (trees, tables) – when a module creates some sort of logical view that contains visual elements that intuitively map to files (Project view), its elements should contain versioning annotations
    • editor panes – editor pane's title, tab and other gadgets that display file's name should be annotated as well
  23. It would be nice to have means of ordering of GUI extensions and/or means of choosing one that will be used if multiple extensions are found:
    • XML module selects the extension that more closely matches the given doctype
    • VCS annotations may come from VCS or EJB module, whichever 'understands' the given node better
  24. Versioning status may change asynchronously, thus visual components must listen for changes in annotations or update themselves by other means.
  25. Version control systems provide actions (update, commit, diff, etc.) that act on set of files. These actions are supposed to be accessible from the following places:
    • nodes in file explorer – every file or folder that is under version control has to include versioning actions in its popup menu
    • nodes in logical views (trees, tables) – every visual element that intuitively map to a file or set of files (package node) should contain versioning actions in its popup menu
    • editor panes – editor's popup menu could contain versioning actions as well
  26. Versioning systems may provide an extension that would allow the user to switch from the default view of the node to “history” view of the node where original node's children would be replaced by children representing previous versions of the file.
  27. Debugger views are by default asynchronous because they often cannot provide data to GUI in real time. Therefore core debugger must cope with this internally and cannot require that extensions that plug into it all solve this issue. Extensions should be allowed to block for an unspecified amount of time in their methods.
  28. Need an easy way to add custom actions to existing Node (files) in filesystem tab. We would like to add "Share file" action to any node in the Project Tab (#56214).

What We Think Our Developers Are Searching For

The purpose of this section is to group and sort the developer opinions into fewer, bigger and more structured chunks. We shall agree that they sufficiently match the individual opionions and are really critical for success of this yet another reusable display architecture effort.

Guidelines

From the amount of gathered feedback and also from few individual items (namelly #19, #20, #26) it seems clear that there is a real need for a solution to these kind of problems. People are searching for guidelines how to write extensible UIs, how to correctly establish communication between their and other modules and how to achieve good enough performance.

Visualization In Standard Views

Obviously the most visible need for extensibility is in our current explorer views and as such it seems to be the most requested feature (#1, #2, #4, #12, #13, #16, #18, #21, #24). Developers call for possibility to extend actions, properties, names, children, icons of nodes in our current views.

Invite Participants

Certain comments (#3, #5, #22, #28) suggest that the mutual cooperation shall not be completely chaotic. Developers tend to want to have control over the places where the participation is going to happen and sometimes they even desire to select from multiple participants the most suitable one(s).

Extensible Contract

No matter how carefully we select the set of supported visualization aspects the list will not be complete as can be seen from some surprising requests (#6, #7, #15, #17, #18). If this effort is supposed to be useful for these developers as well, it has to provide easy extensibility for both side of the contract.

Lifecycle

The display architecture needs to present not only static data, but be ready for changes in them or even invoke certain operations on them (#8, #9, #14, #23). The views must react to changes in set of modules, in the objects itself and effectively update itself according to those changes. They must be able to invoke effective actions on (multi) selected elements.

What We Do Not Want This Project To Provide

View Content of File

Providing alternative visualization of content of a file has been requested few times (#10, #11, #25) and althrough it might easily fall into one or two categories in previous section, it is kept separate as it is more likely request for UI spec and reuse of navigator than something to be handled directly by this display architecture.

What We Want To Provide To Our Developers

This section provides list of requirements gathered on the base of previous section, with their priorites and ways to measure how well they are implemented in various solutions.

Guidelines

Id Description Priority How to Measure?
FindDoc The developers that will want to use the display technology need to be able to find the correct documentation quickly. The starting point is the NetBeans documentation page and it is expected that the user is familiar with its structure (in order to eliminate own problems of the documentation). Then the score is the amount of time needed for the developer to find out solution to a variation of one of the problems cited in What Our Developers Say section.
UnderstandDoc It shall be simple to understand what the documentation describes, what actions shall be done and how to tailor provided examples into own solution. We shall have an API usablility study that will ask the NetBeans 4.0 API experienced developers to expose contact like this and consume contract defined by this display framework. Their solution is going to be compared to sample one and the less differences the better.
DefineContract Offering other modules the visual extension point shall be easy and as that also forms an exported api it shall be easy to make such documentation visible to external developers. The amount of non-code documents that are needed to get description of the contract into javadoc and arch documents shall be low compared to the code that needs to be written.
PlugIn Enhancing new view of an existing module shall not be complicated (after finding in docs that it is possible). The amount of java and non-java code shall be of reasonable size. Size of the unrelated code - for example the one that needs to be written to change icon while not having anything to do with icons - shall be as small as possible. The amount of non-java code shall be small and error proof.
TypeSafe Given the possible dynamic nature of the extensible visualization framework it is desirable to minimize amount of type casting. This will catch more problems during compile time and thus prevent mistakes that otherwise might be found late or not at all. Minimize the amount of typecasting when querying a result, when extending new feature, listening on changes and defining new visual extension point.
Testability Applications written according to display architecture guidelines need to be easily testable in a reliable way. This means the behaviour shall be deterministic and setup of unit test environement (which is usually the biggest obsticle) shall be simple. The less of additional libraries needed to setup the environment the better. The more random test failure caused by the infrastructure, the worse.

Visualization In Standard Views

Id Description Priority How to Measure?
PlugInView The complexity of starting to use new display framework inside of existing (node based) view shall be low. It is unreasonable to expect that we manage to migrate all of our (and partner) modules to new display infrastructure. That is why it is more wise to provide incremental migration path - e.g. allow also local switch to new display framework that will work in existing views and end user will not notice difference. How much code is needed (if that is even possible) to accomodate new display architecture for one node (either node in runtime tab, favorites, projects or files view) into existing views. The less, the better.
CreateOwnView Creation of a visual component showing some objects using the display architecture is natural starting point for newly written modules and as such shall be easy. The amount of code to create a tree view that is fully integrated into the rest NetBeans framework. Actions has to work (like Save), global property sheet update itself and navigator content is updated as expected.
StrategyFirst The solution supports selection of first answer from many. This is needed for simple cooperation over selection of name, icon, behaviour of open action, etc. How much code is needed to write a view that will select one display name for an object if more is provided.
StrategyCompound The solution supports merging of answers together. This is usually useful for composition of multiple child objects for an element or for composition of popup menu. How easy is to write a view that composes actions or children or properties from all suggested ones.
StrategyReordering The solution supports reorder of merged answers. This is another level of StrategyCompound as it supports additional coopearation on order which may be desirable for achieving more pleasant end user experience (for example in case of order of actions in menu). Can the compound answers be reordered somehow? Is it possible to reorder them by groups only or one by one. Does the pieces providers need to know about each other or not?
StrategyCustom Support for own special strategy. Sometimes a producer of a contract would like to define its own way to create the final result from more provided. How much control a provider of the view can gain on the merge of the componoud results? Is the code simple?
StrategyBadging Special support for bagging. Bagging of icons and to certain extent names is currently used in many places in our explorer and as it is a complex example of merge strategy, it makes sence to ask whether the solution guides or even helps the modules writers to simply achieve what they need. How complex is the code to allow badging of images (or strings) between multiple providers? The simpler the better. Does it support any composition or just a fixed pattern? The more freedom, the better.

Invite Participants

Id Description Priority How to Measure?
MultiRegs More registration points for the same type of object. The same object often needs different visualization even it the same view - for example children of a class (e.g. methods and fields) can be different when one wants to see internal implementation details or just public interface. How complex is to define a registration point? The less code and the better. Any differences (performance, ease-of-use, etc.) between the first one and the next? Zero differences would be the best.
DeclarativeRegs Support for declarative registration. It is possible to imagine java api based on method calls to perform registation, but that would probably lead to a lot of code execution on startup as each module would need to run their initialization and increase the starupt time. On the other hand declarative registration can be processed once and then read only on demand. The amount of code needs to run on initialization of the system or of the view to register the display framework extensions. The less the better.
BestFit Possibliity to define own bestfit strategy. Sometimes the selection of the most suitable viewer cannot fit into any predefined rules (like in case of XML document - #23) and then the provider of the contract would welcome a chance to step in and select the best according to his computation. How much complex (if even possible) it is to define own best fit strategy?
Clasification Possibility to participate as a provider of a feature based on some object's clasification. Imagine someone willing to add an action to any element represeting file, someone else only to xml files, someone else only to files in project tab. Each of this represent different criteria of the element and based on its presence triggers actual contributors. Is clasification on more than one criteria supported? More than one criteria is better. How much lines takes to define such clasification? Has the clasification be anticipated by the creator of the view or can external modules add new clasifications? The later is better. What is the performance of the selection of applicable clasifications? The ratio of asked providers vs. finally used providers shall be close to one.
CompileTypeCheck Build time check that a registration is correct. Our experience shows that debugging wrong declarative registrations is pretty tedious task, which can be prevented by pre-runtime test of correctness of such declarations. How much mistakes in registrations (type problems, typos, etc.) ` can be caught during build time. The more the better. How much additional tools (over javac) is needed. Plain javac would be optimal.

Extensible Contract

Id Description Priority How to Measure?
NewContract Allow two end sides to define new contract. This is needed as from time to time people come up with new ideas how one side (view) can do more fancy things and if the other side (providers) suply some information. In these cases the display architecture should not stay in a way and should allow definition of new contract. How complex is it (if even possible) to add new contract (html display name, name abbrevations, scrollbar policy, etc.) between consumer (the view) and provider (the registered providers)? The less code the better. The less possiblity to break older contracts the better.
NewAsOld The nealy defined contract shall be similar to build-in ones. Certain existing solution provided the extensiblity, but the new defined contracts looked differently to API users and may not perform as well as the old ones. Can one see difference between new contract and build-in one? Does it behave differently in terms of API or performance? Bad if it is different even worse if it is not as good.
TypeSafeExt New contracts shall be well typed. As there will be more new contracts as build-in ones, they shall meet the criteria of type safety for the sakes of compile time error checks. How much casts is it needed to add and use new contract? Probably not less then in case of build-in one, but any additional casts are bad.
RuntimeExt Runtime discovery of extra capabilities. Certain parts of code need to find out contracts supported by an element during runtime - this is especially useful for apisupport bean browse tool which is very handy for any module writer trying to understand what a certain visual element provides. Can the code discover all the extra capabilities during runtime? The more the better.
APIvsSPI Separation of API and SPI. It has been experienced that as soon as the same api starts to be used for calls as well as implementation, its evolution gets pretty complicated and even possible it is unlikely to reach full compatibility. Is there an interface that would prevent or complicate future evolution and improvements to the framework? The more of such interfaces the worse.
MoreImpls More implementations of the providers. Requirements will change and one day the best approach to address them can be to leave to previous registration mechanisms and switch to completely new one, while preserving the extension points. For that support for multiple implementations fo the same api is going to be benefitial. Is the implementation closed or can external modules enhance registration, delegation, implementation of the same API? Openess is better. Can there by multiple ways to implement the same api contract? More ways, is better. Is this invisible from the client point of view? Invisibility is good.

Lifecycle

Id Description Priority How to Measure?
Listeners Solution provides listener support. Standard way of listening on changes in displayed objects is essential for most of usages. How easy is to listen on change of certain aspect of an object? The less code, the better. Can multichanges be delivered in groups, so repaints are optimized? Optimization of repaints is good thing. Do listeners register only when needed and unregister when no longer needed? The less wasted memory and listener storms, the better.
Memory Little overhead in memory. The architecture has to occupy some additional memory in order to observe the displayed elements, howeve this shall be optimized. The lower over head over the original object the better. This shall include the caches, listeners, in case of multiple providers of an aspect as well as objects with or without beans support.
MultiOps The support for multi selection operations. Sometimes in current NetBeans one cannot easily group multioperations which in turn results in bad UI perception (blinking display) and slower performance (repaint needed after every operation or more connections to server, etc.). Can an action be invoked on multi selection of objects? Good if it can. How complex is to write such action? The optimal is no difference in action for single and multiple objects (exception iteration). Is there support for group operations - e.g. the repaint happens only after the the whole operation is finished? Good if there is.
Threading Solution defines threading model. Knowing the model can simplify life of callers and well as implementators of registered extensions. Is the threading defined? Definition is a must. Is it enforced? Enforcing is good. Is it implementable? Well, it should be. Does it define listener firing model? Well it should. Is it deterministic and testable? Testability is a must.
SlowPlugins Support for slow plugins. It is clear that as soon as one allows others to plug-in, the performance gets compromised. Well defined architecture shall get ready for not optimally written plugins. Does it deal with "slow" plugin response times? Ability to satisfy percieved performance guidelines even if plugins do not comply is a plus. Are there multiple choices - e.g. slow and fast mode? If a fast model cannot be presented to user as really fast (for example the repaint gets done later than it could), then it is a huge minus. Can one invoke any API in fast (AWT) and slow (other code) mode? Better if possible, as it allows simpler code in some cases.

Send comments and patches to nbdev@netbeans.org.
Companion
Projects:
MySQL Database Server   Open JDK: an Open SourceJDK   GlassFish Community: an Open Source Application Server    Mobile & Embedded Community    Open Solaris   java.net - The Source for Java Technology Collaboration   Virtual Box - full virtualizer  Open ESB - The Open Enterprise Service Bus Powered by