Code Organization Best Practices

We recommend that you follow the following guidelines when implement your own plugin:

Naming

After naming a module and deciding a package name for that module, Netbeans makes it very difficult to change these settings. Choose those names carefully. While Netbeans provides refactoring options, they don't always work. When they don't, you might have to change multiple files in the "nbproject" folder that is visible only in the "Files" window (as opposed to the "Projects" window).

Module Suite vs Modules

For complex projects, split your code into modules, and combine them in a module suite. To decide what each module should contain, consider these guidelines:

  • one module per window or top component
  • separate data access and windows (model vs view)
  • separate custom modules provided by INT from your own modules
  • use events to communicate between modules, not listeners
  • use dependency injection when necessary (see "Pluggable Architecture" section below)

When you create a module suite, make sure to copy the arguments "default_options" in the INTViewer/etc/intviewer.conf file to your platform.properties file.

Example:

The following options in the INTViewer/etc/intviewer.conf file

default_options="--branding intviewer -J-Dnetbeans.indexing.noFileRefresh=true -J-da -J-Xms600M -J-Xmx1G -J-Dcom.interactive.jcarnac.jogl.debug=true -J-Dsun.java2d.noddraw=true -J-Duser.language=en -J-Duser.country=US" 

should appear as follow in the platform.properties file of your module suite:

run.args.extra=-J-Djogl.disable.opengles=true -J-Dnb.winsys.sliding.effects=true -J-Dsun.java2d.noddraw=true -J-Dnetbeans.indexing.noFileRefresh=true -J-da -J-Djava.util.logging.config.file=${progdir}/../intlogging.properties -J-Xms600M -J-Xmx3G -J-Duser.language=en -J-Duser.country=US

Packages

(root): the main classes, such as the main top component of the module

  • actions: stores all menu items (extends SystemAction, AbstractAction, ActionListener, etc.)
  • analysis: mathematical routines
  • data: stores all "data access/file" "reading/writing" classes
  • docs: stores all help files
  • startup: actions that are executed right after the INTViewer desktop is loaded
  • editors: stores all gui components such as panels (extends JPanel, IObjectEditorNode)
  • editors.shortcut: all window and attribute shortcut (extends AbstractViewerWindowShortcutPanel)
  • exit: actions that are executed right before INTViewer exits
  • events: stores all events (extends EventObject)
  • importers: stores all drag and drop adapters (extends IDataImporter)
  • internals: stores all classes that need access to non-public api classes
  • longtasks: stores all long tasks (extends AbstractLongTask)
  • resources: stores all resource files (xml files, zip files, etc)
  • trees: stores all NetBeans node objects. root contains the BeanTreeView
  • trees.nodes: stores all NetBeans node objects
  • trees.childrenkeys: stores all NetBeans children keys objects or node factories
  • utils: anything that is purely static class
  • utils.icons: all icon files
  • wizards: stores all Netbeans wizard objects
  • layers: stores all layer classes (extends AbstractLayer2D)
  • layers.factories: stores all layer factory classes (implements ILayerFactory)
  • windows : stores all windows classes (extends AbstractViewerWindow) if you have several (otherwise use the root package)

Pluggable Architecture

For large projects, there are benefits making service providers pluggable.

For example, if your module suite relies on a set of Unix script files installed locally, make the discovery and use of these files pluggable so that a Windows developer who cannot run these script files can execute most of the code without errors.

NetBeans has a built-in "lookup" mechanism that makes pluggable services easy to implement.