Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "GEF/GEF4/SwtFX"

< GEF‎ | GEF4
m
m
(45 intermediate revisions by one other user not shown)
Line 3: Line 3:
 
== Introduction ==
 
== Introduction ==
  
The GEF4 SwtFX component provides abstractions for the combined rendering of lightweight (shape and canvas figures) and non-lightweight (SWT widgets) objects. The API is inspired by concepts of JavaFX, such as the event system (event bubbling and capturing). It is intended to replace the core of Draw2d.
+
The GEF4 SwtFX component provides specific JavaFX Node implementations which embed SWT Controls in a JavaFX scene graph. The component is subdivided into different packages:
  
The component is subdivided into different packages:
+
* '''org.eclipse.gef4.swtfx'''<br />Contains SWT specific sub-classes of JavaFX framework classes to make embedding SWT Controls in a JavaFX scene graph possible.
 +
* '''org.eclipse.gef4.swtfx.controls'''<br />Contains JavaFX Node implementations for the individual SWT Controls, i.e. SwtFXButton, SwtFXLabel, etc.
  
* '''org.eclipse.gef4.swtfx''', partially implemented<br />Contains classes and interfaces for the combined rendering of ligthweight scene graph nodes and heavyweight SWT widgets.
+
== General ==
* '''org.eclipse.gef4.swtfx.events''', partially implemented<br />Contains the event system of the component. Implements event bubbling and capturing phases.
+
* '''org.eclipse.gef4.swtfx.gc''', implemented<br />Contains a GraphicsContext implementation similar to the JavaFX GraphicsContext2D using SWT under the hood. (Many lines of code from the old Graphics component found its way into this package.)
+
* '''org.eclipse.gef4.swtfx.layout''', planned<br />Contains default layout managers and corresponding functionality.
+
* '''org.eclipse.gef4.swtfx.animation''', planned<br />Provides timeline animation and transition animation support.
+
 
+
== Key abstractions ==
+
  
 
* '''package: org.eclipse.gef4.swtfx'''
 
* '''package: org.eclipse.gef4.swtfx'''
  
The SwtFX component provides a scene graph model which can be embedded into an SWT application. The scene graph model consists of leaf nodes and composite parent nodes (containing other parents/leaves). As you can see in the following diagram, the constellation reflects the standard composite design pattern:
+
In order to be able to embed SWT Controls in a JavaFX scene graph, we decided to sub-class two JavaFX framework classes: FXCanvas, and Scene. This is due to the API mismatch of SWT and JavaFX. To create an SWT Control, you need to know its parent (a Composite). But in JavaFX you can create all the nodes you need first, and then plug them together to the full scene graph. Therefore, a JavaFX Node for an SWT Control, which we will refer to as SwtFXControl, has to create the "peer" SWT Control not until it can acquire an SWT Composite. For the embedding of JavaFX in an SWT application, JavaFX provides the FXCanvas (which is a SWT Composite). Our SwtFXScene allows access to a corresponding SwtFXCanvas, so that a SwtFXControl can check for its Scene to determine if creating the peer is possible.
 
+
[[Image:GEF4SwtFX-key-abstractions.jpg|Key abstractions]]
+
 
+
The INode, IFigure, and IParent interfaces are the key abstractions used within the GEF4 SwtFX component. The INode interface describes the general behavior inherent to all nodes. The other two interfaces refine and extend that behavior: Leaf nodes implement the IFigure interface and composite nodes implement the IParent interface.
+
 
+
Parent nodes and figure nodes take different responsibilities. The figure nodes are responsible for drawing themselves (during rendering phases). That's why their interface allows the manipulation of several drawing attributes. Parent nodes are responsible for laying out their children, i.e. they can take control of their children's positions and sizes. All nodes can perform hit testing, i.e. they can tell if a screen location is incident to their visual representation. And all nodes are possible event targets, so that they can react to keyboard, mouse, or other events.
+
 
+
[[Image:GEF4SwtFX-abstract-realizations.jpg|Abstract realizations]]
+
 
+
SwtFX provides abstract implementations of these interfaces which serve as the basis for all nodes. The majority of methods specified in the INode interface is implemented by AbstractNode. The AbstractFigure class implements getters and setters for drawing attributes. Besides it does ensure that the GraphicsContext used to draw the figure is restored to its initial state after drawing. The AbstractParent class implements layout and rendering propagation.
+
 
+
If you wish to implement a custom parent or figure node, all you have to do is extend the corresponding abstract realization and override the appropriate methods. You can take a look at the provided parent and figure nodes as a source of inspiration.
+
 
+
[[Image:GEF4SwtFX-concrete-implementations.jpg|Concrete implementations]]
+
 
+
The SwtFX component ships with two IFigure implementations and several IParent implementations. The provided figure nodes are called CanvasFigure and ShapeFigure. A CanvasFigure displays a rectangular area in which you can draw using a GraphicsContext. A ShapeFigure displays a geometric shape - an object of the GEF4 Geometry component - on the screen. The shape is filled and stroked by default. The provided parent nodes implement different layout procedures. HBox and VBox, for example, are laying out their children horizontally and vertically, respectively.
+
 
+
Moreover, there is one INode implementation which is neither a figure nor a parent. This is the ControlNode class. A ControlNode is used to embed SWT controls into the scene graph. The ControlNode class consists of glueing both systems together, i.e. redirecting events, manipulating SWT bounds, and computing a local transformation matrix for the ControlNode, so that the wrapped SWT control's bounds are always axis aligned.
+
 
+
=== Scene ===
+
 
+
As scene graph hierarchy and SWT widget hierarchy are not shared, a special SWT widget is used to embed a scene graph. This widget is provided by SwtFX and is called Scene. A Scene stores the root node of a scene graph (always an IParent) and propagates SWT events through that scene graph. A Scene does also schedule update, layout, and render phases.
+
 
+
[[Image:GEF4SwtFX-Scene-class.png|Scene class diagram]]
+
 
+
=== INode ===
+
 
+
=== IFigure ===
+
 
+
An IFigure represents a visual on the screen. There are two IFigure implementations available per default:
+
 
+
* A ShapeFigure consists of a geometric object such as Rectangle, Ellipse, or Line. It is used to display that shape.
+
* A CanvasFigure consists of a raster image to draw into using a GraphicsContext.
+
 
+
=== IParent ===
+
 
+
...
+
 
+
=== Group ===
+
 
+
The Group is a special parent node which will not layout its children. It is only used to group scene graph nodes together in oder to be able to control some of their attributes simultanously.
+
 
+
== Event system ==
+
 
+
The provided event system is similar to JavaFX's event system:
+
  
    [TODO: class diagram of our event system]
+
This is how you create the context for SwtFX:
    [MAYBE: comparison to JavaFX]
+
<source lang="Java">
 +
import org.eclipse.gef4.swtfx.SwtFXCanvas;
 +
import org.eclipse.gef4.swtfx.SwtFXScene;
 +
import org.eclipse.swt.SWT;
 +
import org.eclipse.swt.layout.FillLayout;
 +
import org.eclipse.swt.widgets.Display;
 +
import org.eclipse.swt.widgets.Shell;
  
In comparison to SWT, the event system uses typed event objects, exclusively. The event object classes are organized hierarchical, so that you can define event listeners for "superordinate" event types.
+
public abstract class SwtFXApplication {
 +
public SwtFXApplication() {
 +
Display display = new Display();
 +
Shell shell = new Shell(display);
 +
shell.setLayout(new FillLayout());
 +
SwtFXCanvas canvas = new SwtFXCanvas(shell, SWT.NONE);
  
    [Event] <|--- [InputEvent] <|--- [MouseEvent]
+
SwtFXScene scene = createScene();
                              <|--- [KeyEvent]
+
canvas.setScene(scene);
  
    (fig: InputEvent is a superordinate event type.)
+
shell.setSize((int) scene.getWidth(), (int) scene.getHeight());
 +
shell.open();
  
If several event listeners can react to an occured event, the one with the most special event type will be called first. Assuming you would define an event listener for InputEvents and a listener for MouseEvents, the MouseEvent listener would be called before the InputEvent listener, when a MouseEvent occurs.
+
while (!shell.isDisposed()) {
 +
if (!display.readAndDispatch()) {
 +
display.sleep();
 +
}
 +
}
 +
display.dispose();
 +
}
  
To be able to react to events, you have to implement the IEventTarget interface. An IEventTarget is responsible for building an EventDispatchChain. In general, all the parent nodes (up to the root) are prepended to the EventDispatchChain. INode extends the IEventTarget interface, therefore Group and IFigure are already able to react to events.
+
public abstract SwtFXScene createScene();
 +
}
 +
</source>
  
Every INode manages an IEventDispatcher to add and remove event listeners to the node and to dispatch incoming events to the correct listeners. The IEventDispatcher differentiates between event handlers and event filters. Both are implementations of the IEventHandler interface, but they are executed during different phases of event propagation.
+
=== SwtFXScene ===
  
1. Target Selection
+
=== SwtFXCanvas ===
    When an event occurs, the event target is determined at
+
    first. Several rules exist to select the target:
+
    * keyboard events => focus target
+
    * mouse events => mouse target
+
    * other => cursor target
+
  
2. Route Construction
+
=== AbstractSwtFXControl ===
    The selected IEventTarget is utilized to get the EventDispatchChain for
+
    further event processing.
+
  
3. Event Capturing
+
== Controls ==
    The event object travels along the EventDispatchChain -- usually starting at
+
    the root -- up to the event target. On its way, all registered event filters
+
    can process, and eventually consume, the event. Event processing terminates,
+
    if an event is consumed.
+
  
4. Event Bubbling
+
* '''package: org.eclipse.gef4.swtfx.controls'''
    If the event reaches the selected IEventTarget, it will travel down the
+
    EventDispatchChain down to the root. On its way, all registered event
+
    handlers can process, and eventually consume, the event.
+
  
== Layout Panes ==
+
Although you are able to create specific SwtFXControls yourself by sub-classing AbstractSwtFXControl, we provide implementations for a set of SWT Controls, already.
  
=== Pane ===
+
=== SwtFXButton ===
  
=== HBox ===
+
The SwtFXButton is used to embed SWT Button controls in a JavaFX scene graph.
  
=== VBox ===
+
In order to be able to correctly embed multiple radio button groups, you have to group the buttons together by using the SwtFXButton#groupRadios() method. The standard SWT way does not work, because you would have to create all radio buttons of one group in one Composite. But as we only have access to one single Composite, which serves as the parent for all SWT peers, we cannot use the standard behavior.
  
=== BorderPane ===
+
=== SwtFXStyledText ===
  
=== AnchorPane ===
+
The SwtFXStyledText is used to embed SWT StyledText controls in a JavaFX scene graph.

Revision as of 18:59, 20 November 2013

Note to non-wiki readers: This documentation is generated from the Eclipse wiki - if you have corrections or additions it would be awesome if you added them in the original wiki page.

Introduction

The GEF4 SwtFX component provides specific JavaFX Node implementations which embed SWT Controls in a JavaFX scene graph. The component is subdivided into different packages:

  • org.eclipse.gef4.swtfx
    Contains SWT specific sub-classes of JavaFX framework classes to make embedding SWT Controls in a JavaFX scene graph possible.
  • org.eclipse.gef4.swtfx.controls
    Contains JavaFX Node implementations for the individual SWT Controls, i.e. SwtFXButton, SwtFXLabel, etc.

General

  • package: org.eclipse.gef4.swtfx

In order to be able to embed SWT Controls in a JavaFX scene graph, we decided to sub-class two JavaFX framework classes: FXCanvas, and Scene. This is due to the API mismatch of SWT and JavaFX. To create an SWT Control, you need to know its parent (a Composite). But in JavaFX you can create all the nodes you need first, and then plug them together to the full scene graph. Therefore, a JavaFX Node for an SWT Control, which we will refer to as SwtFXControl, has to create the "peer" SWT Control not until it can acquire an SWT Composite. For the embedding of JavaFX in an SWT application, JavaFX provides the FXCanvas (which is a SWT Composite). Our SwtFXScene allows access to a corresponding SwtFXCanvas, so that a SwtFXControl can check for its Scene to determine if creating the peer is possible.

This is how you create the context for SwtFX:

import org.eclipse.gef4.swtfx.SwtFXCanvas;
import org.eclipse.gef4.swtfx.SwtFXScene;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
 
public abstract class SwtFXApplication {
	public SwtFXApplication() {
		Display display = new Display();
		Shell shell = new Shell(display);
		shell.setLayout(new FillLayout());
		SwtFXCanvas canvas = new SwtFXCanvas(shell, SWT.NONE);
 
		SwtFXScene scene = createScene();
		canvas.setScene(scene);
 
		shell.setSize((int) scene.getWidth(), (int) scene.getHeight());
		shell.open();
 
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		display.dispose();
	}
 
	public abstract SwtFXScene createScene();
}

SwtFXScene

SwtFXCanvas

AbstractSwtFXControl

Controls

  • package: org.eclipse.gef4.swtfx.controls

Although you are able to create specific SwtFXControls yourself by sub-classing AbstractSwtFXControl, we provide implementations for a set of SWT Controls, already.

SwtFXButton

The SwtFXButton is used to embed SWT Button controls in a JavaFX scene graph.

In order to be able to correctly embed multiple radio button groups, you have to group the buttons together by using the SwtFXButton#groupRadios() method. The standard SWT way does not work, because you would have to create all radio buttons of one group in one Composite. But as we only have access to one single Composite, which serves as the parent for all SWT peers, we cannot use the standard behavior.

SwtFXStyledText

The SwtFXStyledText is used to embed SWT StyledText controls in a JavaFX scene graph.

Back to the top