Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
Scout/Tutorial/5.0/SVG Field
The Scout documentation has been moved to https://eclipsescout.github.io/.
Contents
Introduction
Scout offers support to handle Scalable Vector Graphics (SVG). For this, a new SVG field is introduced as an additional UI component. This field enhances Eclipse Scout with the ability to display interactive diagrams and graphics that work on desktop as well as on web environment.
This tutorial demonstrates
- Displaying a static SVG field (view only)
- Displaying an interactive SVG field using embedded hyperlinks.
Getting started
Create a Scout Application with SVG Fields
Create a new Scout application
As a first step create a new Scout application in the Scout perspective. For this, choose one of the following options
- Use menu File, New, Project ..., Scout Project
- In the Scout Explorer on the top levle node use context menu New Scout Project ...
In the New Scout Project dialog
- Enter org.eclipse.scout.svgtest into field Project Name
- Click Finish
More details can be found here.
Add SVG support to the application
For this, do the following
- Go to the project's top level node in the Scout Explorer
- Go to the Scout Property View and tick the check box Scalable Vector Graphics (SVG).
Add the static SVG field to the DesktopForm
To add a SVG field to the DesktopForm do the following
- Go to the Scout Explorer
- Open the node Client and the folder Forms
- Expand the DesktopForm and click on node MainBox as indicated by the red arrow
- Use context menu New Form Field ... on node MainBox
- Select SvgField as shown below, click Next > and enter StaticSvg as name for the field, complete the Wizard for a new text and leave the Class Name StaticSvgField as proposed.
Add an SVG Image
- In the Scout Explorer expand the MainBox and click on the newly created node StaticSvgField
- Go to the Scout Object Properties
- Enter 3 in field Grid H to provide a decent height for the SVG field
- Click on the green cross next to operation ExecInitField to add the init method
- Add the following implementation for to method execInitField()
@Override protected void execInitField() throws ProcessingException { String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" + "<svg width=\"400\" height=\"400\" viewBox=\"0 0 400 400\" \n" + " xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" \n" + " contentScriptType=\"text/ecmascript\" zoomAndPan=\"magnify\" \n" + " contentStyleType=\"text/css\" version=\"1.1\" xml:space=\"preserve\" \n" + " preserveAspectRatio=\"xMidYMid meet\"\n" + ">\n" + " <a xlink:href=\"http://local/polygon\">\n" + " <polygon id=\"poly\" points=\"220,100 300,210 170,250 123,234\" \n" + " style=\"fill:#f5950d;stroke:red;stroke-width:3\" />\n" + " </a>\n" + " <a xlink:href=\"http://local/circle\">\n" + " <circle id=\"circle\" cx=\"200\" cy=\"100\" r=\"40\" \n" + " stroke=\"blue\" stroke-width=\"2\" fill=\"#00678c\" />\n" + " </a>\n" + "</svg>"; SVGDocument doc = SVGUtility.readSVGDocument(new ByteArrayInputStream(xml.getBytes())); setSvgDocument(doc); }
Handling SVG Hyperlink Clicks
A hyperlink event is fired when the user clicks on a SVG element containing an hyperlink. The URL may also contain GET parameters. A hyperlink event handler could then parse this URL and these parameters and open a new form for this entity. E.g. the hyperlink could be http://local/person_nr?1234. The event handler could open the PersonForm for the person with the ID 1234 when the hyperlink event is fired.
In our example document hyperlinks are declared for the polygon and the circle, using http://local/polygon and http://local/circle respectively.
<a xlink:href="http://local/polygon"> ... <a xlink:href="http://local/circle"> ...
Whenever the user clicks on a hyperlink in the SVG field the corresponding execHyperlink event handler routine is called. Processing of user clicks on hyperlinks embedded in the SVG can be implemented by overriding method execHyperlink for the SVG field. For this, follow the steps below.
- In the Scout Explorer click on node StaticSvgField
- Open Advanced Operations in the SVG field's Scout Object Properties
- Click on the green cross next to operation ExecHyperlink to add the method
- The implementation below will show a message box when the user clicks on the circle
@Override protected void execHyperlink(SvgFieldEvent e) throws ProcessingException { String url = e.getURL().toExternalForm(); // checking for a match with 'http://local/circle' if (url.contains("circle")) { MessageBox.showOkMessage("Hyperlink Event", "You have clicked the circle", "URL: " + url); } }
Verify the result
To verify the resulting SVG field server and client can be started
- In the Scout Explorer go to the projects top level node
- Go to the Scout Object Properties to section Product Launchers
- Start the server (lower green arrow)
- Start the client (upper green arrow)
Adding the interactive SVG diagram field
Now we're looking at more realistic scenario where we load the SVG file "SampleGraphic.svg" from the client bundle.
First, we add a second SVG field to the DesktopForm
- Go to the Scout Explorer
- Open the node Client and the folder Forms
- Expand the DesktopForm and click on node MainBox as indicated by the red arrow
- Use context menu New Form Field ... on node MainBox
- Select SvgField as shown below, click Next > and enter Dynamic SVG as name for the new field
- In the Scout Object Properties set Grid H to 3 as well for the newly created field
Create a SVG file in the client bundle
For this, you first have to switch to the Package Explorer
- Open the bundle org.eclipse.scout.svgtest.client
- Create folder (New->Other..) svg below folder resources and add a new empty file "SampleGraphic.svg"
Now, Open this file in the text editor and copy the following content into it
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <svg width="400" height="400" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="text/ecmascript" zoomAndPan="magnify" contentStyleType="text/css" version="1.1" xml:space="preserve" preserveAspectRatio="xMidYMid meet"> <a xlink:href="http://local/polygon"> <polygon id="poly" points="220,100 300,210 170,250 123,234" style="fill:#cccccc;stroke:#000000;stroke-width:1"/> </a> <a xlink:href="http://local/circle"> <circle id="circle" cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="grey" /> </a> </svg>
Load the SVG file from the client bundle resources
As in the case for the static SVG field add an implementation for method execInitField. Below is the code to load the previously created SVG into the SVG field from the client bundle:
@Override protected void execInitField() throws ProcessingException { try { URL url = Activator.getDefault().getBundle().getResource("/resources/svg/SampleGraphic.svg"); InputStream is = url.openStream(); SVGDocument svgDoc = SVGUtility.readSVGDocument(is); setSvgDocument(svgDoc); } catch (IOException e) { e.printStackTrace(); throw new ProcessingException("Exception occured while reading svg file", e); } }
Modify the SVG dynamically
For the case of this dynamic SVG field we will directly modify the shown SVG document based on the clicks the user makes on the circle or the polygon.
- In the Scout Explorer expand the MainBox and click on the previous created node DynamicSvgField
- Go to the Scout Object Properties to Advanced Operations
- Click on the green cross next to operation Exec Hyperlink to add the method
Add the implementation for to method execHyperlink() as shown below. In this implementation we first get a copy of the currently shown SVG document, and then update individual SVG elements depending on the shape that the user clicked. If the polygon was clicked, one of its corner will be shifted to the right. If the circle was clicked, it will be moved to the left.
@Override protected void execHyperlink(SvgFieldEvent e) throws ProcessingException { if (e.getURL() == null) return; // create a copy... SVGDocument doc = (SVGDocument) getSvgDocument().cloneNode(true); String url = e.getURL().toExternalForm(); if ("http://local/polygon".equals(url)) { // ... move a corner of the polygon to the right SVGPolygonElement poly = (SVGPolygonElement) doc.getElementById("poly"); SVGPointList pointList = poly.getPoints(); SVGPoint p = pointList.getItem(2); p.setX(p.getX() + 10); } else if ("http://local/circle".equals(url)) { // ... move circle to the left SVGCircleElement circle = (SVGCircleElement) doc.getElementById("circle"); SVGLength cx = circle.getCx().getBaseVal(); cx.setValue(cx.getValue() - 10); } else { throw new ProcessingException("Unsupported Link: " + url); } setSvgDocument(doc); }