Uni-HH / CS. / TAMS / Java / jfig
 
spacer jfig
spacer News
spacer Gallery

spacer Editor
spacer Custom editors
spacer Viewer / Bean
spacer Applet
spacer Presentations
spacer Plotting

spacer Webstart
spacer Download
spacer Documentation
 

While the jfig editor provides all basic diagram editing functions, you might miss your favorite edit operations or expect better support for tedious repeated tasks. Don't despair; modifying and extending the jfig editor is possible, and not at all difficult.

The dynamic class loading provided by the Java virtual machine means that you can add new functions to the jfig editor, or replace existing editing functions with better variants. Here are some reasons to build your own custom editor:

  • provide new editing functions to the editor
  • automate functions to avoid tedious repeated operations
  • use jfig as a frontend for your own applications or databases
  • define your own graphics primitives and objects
  • ...

The following sections present three different examples on how to extend jfig to your needs:

Example: six transistor SRAM cell

Using a simple trick, you can easily add animation to your FIG files. For a live demonstration, see our six transistor SRAM-cell demonstration. Each SRAM (or static random-access memory) cell stores one bit of information.

Only one Java source file SramApplet.java and one FIG figure file sram.fig are used for the demonstration. The trick is to use FIG object comments to identify the individual transistors and wires in the figure file, so that the simulation can later modify the corresponding objects. The findObjectByComment() method traverses the object tree and returns the first object with a matching name. The mousePressed() method intercepts the user mouse-clicks, asks the current transformation for the world-coordinates corresponding to the current mouse position, and decides which (if any) of the input switches was clicked by the user. The remaining methods are use to calculate the new state of the several transistors and signals in the SRAM cell, and a redraw is performed.

Note that the demo is based on an older version of jfig, before the jfig bean was available. While it demonstrates the source code required to initialize the object list, object canvas, and file parsing, a re-written version should use the jfig bean instead. To reduce the download size of the applet, a custom JAR archive that only includes the required classes is used.

Example: scripting

The most flexible way to extend jfig is to run the editor from your favorite scripting shell. That is, you don't start jfig as the main standalone application, but create the editor from within your scripting environment. Using the several accessor method you can then control the user interface, load and save figure files, and directly access and traverse the editor object list. Once you have the references to your figure objects, you can perform custom operations on them:

For example, download and install the Jython scripting environment. To run jfig from the Jython interpreter, put both the Jython and the jfig JAR archives into your CLASSPATH. For example:

  set CLASSPATH=c:\temp\jython.jar;c:\temp\jfig3-itext.jar;
  jython                              # starts the interpreter
  ...

  import jfig.gui                     # user-interface stuff
  import jfig.objects                 # figure objects and geometry
  import jfig.utils                   # utilities

  jfig.utils.SetupManager.loadGlobalProperties( 'jfig/jfig.cnf' )
  jfig.utils.SetupManager.loadUserProperties( '.jfigrc' )

  editor = jfig.gui.JModularEditor()  # new jfig editor
  editor.doOpenFile( 'foo.fig' )      # load figure file
 
  objects = editor.getObjects() 
  for (singleObject in objects):
    if (singleObject instanceof jfig.objects.FigPolyline):
      print 'found a polyline: ' 
      print singleObject
      singleObject.mirrorX( 0.0, 0.0 )
      singleObject.getAttributes().parse( 'color=blue' )
  ...

Example: model-railroad track editor

As an example for a custom editor, this section presents a simple model-railroad track-editor. It provides easy access to the several different track pieces (straight and curved tracks, points, crossings, turntables) from the H0-scale ProfiGleis system by the German manufacturer Fleischmann.

The main new editing function is a smart place operation which automatically joins the selected piece of track to the nearest existing piece of track. It also allows you to rotate a track in multiples of 18 degrees, the basic angle used for the geometry of points and curves in the ProfiGleis system.

Click the thumbnail image below for a screenshot of the editor to see the modified user-interface. The main part of the editor is unmodified (except for a new 'user' menu). However, the layer manager on the right has been replaced with a button panel. The buttons allow the user to directly select each of the several pieces of track of the Fleischman ProfiGleis set. Standard Swing JButtons labeled with the track identification number have been used, but more fancy buttons with icons could have been used as well:

custom jfig editor screenshot

The custom editor consists of just three additional Java files (click the links to view the source code):

The main decision when writing your own editor is whether to define new custom graphics objects (as subclasses of FigObject) or not. Note that you will also need to define a new file format and to write new read and write functions to support your new object types. Naturally, this means the greatest freedom, but probably also a lot of coding.

However, it is often possible to just use standard FIG compound objects instead of custom new graphics objects. Object comments or special combinations of FIG object type and attributes (layers, colors, etc.) can be used to distinguish the custom compound objects from 'standard' compound objects. This is the approach taken here. The smart-place function looks for polylines on layers 250 and 251 to find the coordinates where the track pieces should be joined.

The ProfiGleisFactory class provides a set of factory methods that construct a FigCompound object for each of the several pieces of track from the ProfiGleis system. A few utility and helper methods are provided for common tasks. The makeTrack() method constructs a piece of straight or curved track from the given parameters (length, radius, angle) and attributes (background color). The points and crossings are built as compound objects from multiple pieces of track, e.g. one straight track and one curved track overlaid for the basic points.

The ProfiGleisEditor is written as a subclass of the main jfig editor (JModularEditor). Note that the source code for JModularEditor (and other jfig files) is not required for this, because Java class-loading is based on the class files. The user-interface adds the custom button panel with one button and callback for each of the predefined types of track. The button panel is then added onto the 'East' position of the main editor window layout, in place of the layout-manager (for technical reasons, we remove the layer manager from the layout first).

The callbacks for each of the 'track buttons' call the create() method, which first asks the ProfiGleisFactory to create the corresponding piece of track and then initializes a new CreateTrackCommand editor operation.

The most interesting part of CreateTrackCommand is the smartPlaceToNearestMarker() method, called when you click the middle-mouse button. It first calls findMarkerPositions() to find all possible join-positions for the current piece of track. It then traverses the editor object list and searches all compound (=track) objects within a distance of 10.000 FIG units (four inches) for their marker positions in turn. Next, the minimum distance of all markers positions thus found and the markers on the current track object is calculated. When a match with distance of less than 4800 units is found, the current track object is moved to the corresponding marker position, which effectively joins the current track to the existing track.

The ProfiGleisEditor class also overrides the keyPressed() and keyTyped() methods. This is required because we want to use our own bindkeys (namely 'r' and 's' for rotate left and right, and 'z' for zooming) during the track editing operation. As Swing automatically transfers the keyboard focus to a JButton when it is clicked, we also add a new MouseAdapter that transfers the keyboard focus back to the main drawing canvas (objectCanvas) on a mouseEntered() event.

If you want to test-drive the track editor, put the jfig3 JAR archive into your CLASSPATH and run class jfig.demo.ProfiGleisEditor:

  set CLASSPATH=c:\temp\jfig3-itext.jar
  java jfig.demo.ProfiGleisEditor
Then, click any of the track-buttons on the right to initialize the corresponding CreateTrackCommand. Click the left mouse button to place the current track at the raw mouse position (do this for the first piece of track). The editor will now automatically start a new create track operation. Move the mouse so that the current track approximately abuts with an existing piece of track and click the middle mouse button to automatically place and join the current track. Type the r and s keys (or shift+r or shift+s) to rotate the current track by +/- 18 degrees (36 degrees). Type the ESC key to cancel the CreateTrackCommand and to use any of the standard jfig edit operations.

(Note: the geometry of the ProfiGleis curved points is a compromise between the R1 and R2 curved tracks. A slight offset of about 3 millimeters is introduced whenever you use a curved point. This is harmless when actually building your model-railroad, but clearly shows up in the drawings.)

 
  29.01.2006   Impressum