Overview | Package | Class | Use | Tree | Deprecated | Index | Help
| http://www.jpicedt.org
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES

## Package jpicedt.graphic

jPicEdt library core classes and packages.

See:
Description

Interface Summary
ContentType | Specifies a content-type (aka mime-type) for a Drawing document created by an editor-kit.
SelectionHandler | a SelectionHandler allows to manage selection-related behaviours for a given instance of `Drawing`.

Class Summary
AbstractSelectionHandler | Provides some basic implementation of the SelectionHandler interface.
DefaultContentType | Default implementation of the ContentType interface suited for the JPIC-XML language.
PageFormat | Size and margins data for a `PECanvas`.
PageFormat.Customizer | a dialog box used to change a PageFormat
PECanvas | This is a JComponent on which graphic elements are drawn.
PEScrollPane | A scrollpane that is able to host a `PECanvas`.
PEScrollPane.CenterViewportAction | Move the view so that (0,0) is at the center of the viewport
PEToolKit | A collection of static -utilities- methods targetting number formatting, Swing's widget creation, computation of geometrical properties,...
PicPoint | Enhancement of Point2D.Double with convenient formatting methods and constructors.
PicPoint.XComparator | a comparator b/w PicPoint for X-axis ordering
PicPoint.YComparator | a comparator b/w PicPoint for Y-axis ordering
PicVector | This class encapsulates a geometrical vector (ie it has absolutely no relation with java.util.Vector !).

## Package jpicedt.graphic Description

jPicEdt library core classes and packages. Package structure follows the model-view-controler paradigm. See documentation below for details about the VMC implementation in jPicEdt.

Since:
  PicEdt 1.0

  ## Table of contents

  - The Model-View-Controler paradigm as implemented in jPicEdt
  - The Drawing class and Element interface : a document model for vector-graphics
  - The View interface : rendering the model
  - The DrawingEvent's dispatching scheme : keeping things in touch
  - The EditorKit class : processing UI events
  - The FormaterFactory class : exporting documents to LaTeX format
  - The ContentType interface : lumping things together

  # The Model-View-Controler paradigm as implemented in jPicEdt

  [todo] a short introduction...

  # The Drawing class and Element interface : a document model for vector-graphics

  The document model mostly comprises classes in the `jpicedt.graphic.model package`. It is built on top of :
  - an `Element` interface : this specifies the general contract for graphics primitives (see e.g. DefaultLeafElement and its subclasses) or composite elements (see e.g. BranchElement and PicGroup) which may be added to the model ;
  - a `Drawing` class : this is the document's model, designed as a tree-like container for `Element`'s, the tree structure being inforced by the capability of `Element`'s to have a parent and -possibly- children.
  - an event-dispatching scheme based on the `jpicedt.graphic.event.DrawingEvent` class : this allows `Element`'s to communicate with their hosting `Drawing`, and the latter to post events to registered listeners interested in change in the document's content (e.g. views, selection-handlers, UI components,...).

  The root-element of the document is actually an instance of `Drawing.RootElement` which inherits from `BranchElement` : each `Element` that is directly added to the `Drawing` is actually added as a child of `Drawing.RootElement` ; yet this is rather internal machinery, and developpers may not have to bother with `RootElement`'s methods, and might better use the `Drawing`'s API to alter the document's content. In a way, the Drawing class may be simultaneously considered as the hosting document AND the document's root-element.

  Adding an `Element` to the `Drawing` thus effectively makes it a node a tree, where each node is able to communicate with its parent or -as it is- with its children. This makes it possible for any `Element` belonging to the model to post `DrawingEvent`'s to the entire tree, so that e.g. the hosting `Drawing` gets eventually informed of changes that may have occured in the document's content. It is then up to the the `Drawing` to decide whether to post these event or not to registered listeners.

  # The View interface : rendering the model

  The document's view is aimed at rendering a `Drawing` ; most classes related to the rendering of the model are located in the `jpicedt.graphic.view` package ; besides, some other classes of interest may be found in the various format-specific packages under `jpicedt.format`.

  Each `Drawing` may or may not have a view attached to it. Attaching a view to a model is required only as soon as the model has to be rendered on screen. For instance, parsers create and populate a `Drawing` without ever having to render it on screen. If a drawing has an associated view, then synchronization between the view and the model is based on an event-dispatching mechanism similar to the AWT's event-dispatching scheme (see DrawingEvent's documentation below).

  The view has a pseudo tree-like structure which mimics that of the associated Drawing, and is based on a cross-reference mechanism : every an `Element` may have a `jpicedt.graphic.view.View` directly associated with it, in which case the View also holds a reference to the `Element` it is associated with. Hence this is a pseudo tree-like structure, in that an `Element`'s View doesn't hold any direct reference to its parent's view ; instead, by holding a cross-reference to the `Element` it is associated with, it indirectly knows of its parent's view by relying on the `Drawing` tree structure. To sum up : let X and Y be two `Element`'s of a `Drawing`, where Y denotes X's child, and Xv, Yv the view attached to them ; then for Yv to reach its parent's view, it must rely on the following mechanism :

  Model |  | View
  --- | --- | ---
  X | -> : `getView()` | Xv
  ^ : `getParent()` |  |
  Y | <- : `getElement()` | Yv

  ## ViewFactory's

  The view-tree is basically populated by calling `Drawing.setViewTree(ViewFactory f)`, as soon as one wants the model to be rendered. The given `jpicedt.graphic.view.ViewFactory` knows how to produce `View`'s that are appropriate for each `Element` ; hence, there may be (and there are in effect) different `ViewFactory`'s depending on the kind of content-type to be rendered (e.g. PsTricks, eepic/epic, SVG-XML,...). This approach allows `ViewFactory`'s to be plugged on-the-fly by `EditorKit`'s when the content-type of the model to be rendered changes.

  For the sake of clarity, the view-tree populating during `PECanvas`'s initialization is illustrated hereafter in sketchy outlines :

  - at some early point in `PECanvas`'s contructor, `setContentType()` is called with the kind of content-type given as argument to the constructor ;
  - this in turn calls `setEditorKitForContentType()` : a new `EditorKit` approriate for the given content-type is created, then linked to the hosting canvas (through a call to `EditorKit.install(canvas)`, which allows `MouseEvent`'s to be properly dispatched to the editor-kit) ;
  - then a new `Drawing` is created (usually by asking the editor-kit to create one that is appropriate for the given content-type, although jpicedt currently models all content-types with the same Drawing class)
  - the editor-kit is asked to create a `ViewFactory` appropriate for the given content-type (see documentation : EditorKit.ViewFactoryWrapper)
  - the view-tree associated with the model is then populated by this factory through a call to `Drawing.setViewTree(view-factory).` : this actually calls `setViewFromFactory(view-factory)` on `Drawing.RootElement`, which populates the rest of the tree by calling `setViewFromFactory(view-factory) on all of its children.`

  ## (Re)painting things

  Whenever the content of an Element changes, the View associated with the Element is asked to update itself by means of the changedUpdate() method : this usually means (as implemented in DefaultViewFactory) synchronizing some cached data with the Element (a Shape, a Stroke, ...). This however is not enough for the *real* screen to reflect the change : for that to happen, the hosting JComponent must be asked to repaint itself through the asynchronous AWT's repaint mechanism.
  Now because any View belonging to the view-tree knows of its hosting container (= the Swing component that *really* paints things, usually an instance of PECanvas), it can easily - by means of the repaint() method in the View interface - ask the container to repaint itself (or a part of itself, see documentation in graphic.view.AbstractView.repaint()). This indirectly invokes, through the asynchronous AWT painting mechanism, paintComponent() on PECanvas, the latter being implemented so as to invoke the following paint() methods :

  - on the `Grid` object attached to the PECanvas;
  - on the `root-view` associated with Drawing.RootElement (this view is implemented as an inner class of EditorKit, see documentation about EditorKit.RootView below) : this in turn invokes the paint() method on every child of this view ;
  - on the `EditorKit` in which this PECanvas is installed : this will first invoke paint() on EditorKit.SelectionHandler, i.e. paint the highligher (small green/red squares for Element's control-points, tangents for Bezier curves, etc...), and then invoke paint() on the MouseTool that is currently active in EditorKit (this allows this MouseTool to do some specific rendering that makes sense with the operation being currently carried out, e.g. painting a selection rectangle, ...).

  # The DrawingEvent's dispatching scheme : keeping things in touch

  A `Drawing` has the capability of posting `DrawingEvent`'s to registered listeners to signal a change in the content of the model it holds. This may be used e.g. by `View`'s, selection-handlers, or by any part of the UI to keep their state synchronized with the content of the model. Besides, `DrawingEvent`'s contain enough information regarding the change in the document's content to allow receivers to efficiently optimize their re-synchronization with the model.

  As implemented in the `AbstractElement` abstract class, any change in the content of an Element, e.g. by calling the `setPoint` method, eventually calls `fireChangedUpdate` : this in turn

  - forces the associated view (if any) to keep its state synchronized with the model by calling `view.changedUpdate` (hence in this abstract implementation of the `Element` interface, the view/model synchronization is based on a direct peer-to-peer messaging, rather than by registering the entire view tree as a DrawingListener, and waiting for the event to reach the top of the Drawing's tree-model until the View can update ifself ; this is probably faster, yet this scheme doesn't make use of all the capacilities of the event-dispatching scheme).
  - forward the event to the parent of the element, by calling `parent.forwardChangedUpdate` :
    1. first, this give a chance to the parent to update some of its geometrical properties immediately (see e.g. PicGroup : there, the group's bounding-box must be kept up-to-date with the bounding-box of the group's children, and the group's view be updated immediately) ;
    2. then, this allows the event to propagate upward until it eventually reached `Drawing.RootElement`, which then enables its hosting Drawing to dispatch the event to registered listeners.

  This mechanism is illustrated in the figure below :

  # The EditorKit class : processing UI events

  [todo]

  ## How EditorKit creates ViewFactory's ...

  There are two important inner classes in EditorKit for that matter : ViewFactoryWrapper and RootView. These classes currently have package access, hence documentation about them is mainly aimed at helping developpers to get some grasp of the machinery behind the EditorKit class.

  An instance of `EditorKit` is usually instanciated by a `ContentType`, which thereby provides it with an approriate `ViewFactory`. However, this ViewFactory may to all probabilities inherit from `DefaultViewFactory`, since it is by far the easiest way for developpers to implement their own content-type classes. Yet if DefaultViewFactory can create View's for every Element in the graphic.model package, it doesn't provide any "root-view" to be associated with `Drawing.RootElement` : basically, such a view has to :

  - react to `DrawingEvent`'s posted by `Drawing.RootElement` (this is the case e.g. when a new Element is added to the drawing), by forcing the hosting Swing container (probably a `PECanvas`) to repaint itself ;
  - implement the mouse-event-related `hitTest()` method specified in the View interface so as to dispatch to all the Element's in the Drawing successively.
  - maintain a reference to the hosting container (=PECanvas), so that any view in the tree may retrieve its container by asking its root-element. Since RootView is an inner class of EditorKit, and EditorKit has a reference on the PECanvas it is installed in (see the install() method), this was pretty easy to implement.

  Hence we have defined an inner class of EditorKit for that purpose : when asked to create a View for a Drawing.RootElement, `ViewFactoryWrapper` returns a specific `RootView` (also implemented as an inner class of EditorKit) ; otherwise it delegates to the ViewFactory provided as a constructor to EditorKit ; actually, ViewFactoryWrapper may even do better, since it first checks if the `Element` to create the View for does implement the `ViewFactory` interface itself, in which case the given Element is asked FIRST to create a View for ... itself (this allows developpers to -lasily- design new Element's without having to extend the whole DefaultViewFactory machinery : they'd just have to make their new Element implement the `createView()` method ; of course this approach is valid as long as the rendering of the new Element doesn't depend on the current content-type being installed in PECanvas).

  ## SelectionHandler : selecting, copying, pasting.

  [todo]

  ## MouseTool's : pluggable behaviour for mouse-event handlers

  [todo]

  ## PEAction's : sharing action-handlers across jPicEdt

  [todo]

  # The FormaterFactory class : exporting documents to LaTeX format

  [todo]

  # The ContentType interface : lumping things together

  The `jpicedt.graphic.ContentType` class "lumps" the three components of the VMC paradigm together, since it is able to create components appropriate for the kind of content-type it represents. In particular, this class knows how to create an `EditorKit`, which is enough to create the two remaining components by calling `kit.createDefaultDrawing` and `kit.createDefaultViewFactory`.

  Besides, `ContentType` is able to create a `jpicedt.graphic.io.FormaterFactory` which knows how to format a Drawing to ASCII text.

  Concrete implementation of `ContentType`'s, together with there associated factories, are located in subpackages of `jpicedt.format`. There currently exists content-types for PsTricks, LaTeX's picture environment, and the eepic package.

  Contributing a new content-type (e.g. PostScript, metapost, ...) therefore imposes :

  - To write a new implementation of the `ContentType` interface ;
  - Possibly subclass `DefaultViewFactory` if specialized rendering behaviour is needed (e.g. no colour rendering)
  - Write a new `FormatterFactory` ;
  - Possibly write a new parser if one want jpicedt to be able to import files based on this content-type. The easiest way to plug a new parser to the main parser tree is to add it to the `DefaultParser` by calling the `addGrammar` method. [todo:more documentation about implementing parsers].

  Last-upd : January 20th 2003

Overview | Package | Class | Use | Tree | Deprecated | Index | Help
| http://www.jpicedt.org
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES

Submit a bug : syd@jpicedt.org