http://www.jpicedt.org

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.
ConvexZoneSelectionHandler Interface pour manipuler une sélection de ConvexZone.
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 !).
 

Enum Summary
PECanvas.SelectionBehavior  
 

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

[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:

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:

(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:

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

This mechanism is illustrated in the figure below:

Event dispatching mechanism

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:

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

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

Last-upd: January 20th 2003


http://www.jpicedt.org

Submit a bug : syd@jpicedt.org