Sun, 21 Jun
Creer et afficher un graphe SVG
Nous savons importer un fichier locale SVG et l'afficher dans une zone canvas avec
les librairies Batik.
Nous allons dans ce petit tutoriel, creer un simple SVG en utilisant le Java2D et l'afficher directement
dans notre "frame".
Un document Svg s'appuie sur sa structure Xml et peut être manipuler grâce à l'arbre
DOM.
Pour générer un tel document à partir de code Java, Batik implémente la classe
abstraite java.awt.Graphics2D à travers la classe SVGGraphics2D.
Les étapes nécessaires
Elles sont simples et évidentes : le dessin (draw) et le rendu (render).
Notre SVGGraphics2D hérite de la classe AbstractGraphics2D qui elle-même hérite de
java.awt.Graphics2D.
Nous pouvons donc utiliser toutes les méthodes définies dans ces classes et plus particulièrement
de celle de Graphics2D.
Dans notre exemple nous utiliserons fill et draw avec comme argument une forme (shape).
Le rendu se fait dans notre canvas JSVGCanvas , composant de notre fenêtre (frame) d'application.
Cette classe comme vu dans un précédent article est un composant Swing permettant d'afficher un
document Svg.
Le lien entre les deux , dessin et rendu, et le noeud racine (root) obtenu à l'aide de la méthode getRoot(Element root) et passé à notre canvas de rendu via la méthode setSvgDocument.
Il suffit d'organiser notre code autour de ces différentes étapes.
Organisation de notre code
Nous devons donc créer un objet SVGGraphic2D.
Pour cela nous avons besoin d'implémenter un document SVG. Notre méthode main se
chargera de créer ce nouvel objet.
Ensuite nous dessinerons une simple forme (shape) avec notre instance SVGGraphics2D.
Nous utiliserons les méthodes héritées de Graphics2D.
Nous récupererons le noeud racine (root) que nous passerons à notre document.
Pour le rendu nous ajouterons notre canvas svg à l'objet Frame en n'oubliant pas de lui
passer le document.
Notre Document SVG se retrouve donc dans toute les étapes de notre application; c'est celui que
nous allons commencer par initialiser.
Construction de la référence document SVG
Pour construire notre document SVG, nous allons utiliser la classe SVGDOMImplementation qui implémente
l'interface DOMImplementation de org.w3c.dom.
Cet objet nous permet de créer directement un Document Svg à l'aide de la méthode
createDocument.
Cette méthode prend 3 arguments : l'espace de nom, le nom qualifié,doctype.
L'espace de nom est une constante de SVGDOMIplementation , le nom est bien sûr svg, et le doctype
est non spécifié soit null ( nous n'avons pas besoin de vérifier le document).
DOMImplementation impl = SVGDOMImplementation.getDOMImplementation(); doc = (SVGDocument) impl.createDocument(SVGDOMImplementation.SVG_NAMESPACE_URI, "svg", null);
Passage de référence à l'objet SVGGraphics2D
Il faut que notre objet connaisse le document sur lequel on va travailler.
On le passe en argument de notre constructeur SVGGraphics2D.
SVG2D = new SVGGraphics2D(doc);
Ce code est ajouté à la suite du précédent et est appellé depuis notre main
public class SVGGraphicApp {
// nos variable de classe
SVGDocument doc = null;
SVGGraphics2D SVG2D = null;
....
public SVGGraphicApp() {
DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
doc = (SVGDocument) impl.createDocument(SVGDOMImplementation.SVG_NAMESPACE_URI,
"svg",
null);
SVG2D = new SVGGraphics2D(doc);
}
// autres methodes
...
public static void main(String[]args) {
SVGGraphicApp app = new SVGGraphicApp();
...
}
Dessiner une forme
Maintenant que nous avons une instance de l'objet Graphics2D à travers notre objet SVGGraphics2D nous pouvons y appliquer les méthodes de cette API java.
Chaque fois que nous voulons modifier notre dessin, nous pouvons le faire ici.
Nous nous plaçons ici dans le cas d'une simple application statique,
où nous codons en dur.
Notre objet (SVG)Graphics2D agit comme une rendering engine ou bien encore
comme notre espace de dessin.
Remaque : Une fois le dessin achevé celui-ci ne sera pas encore afficher
Pour notre simple exemple nous allons dessiner du texte, un cercle et quelques lignes générées pour faire
joli.
Mais ici c'est votre imagination qui doit prendre le pas.
// on attribue une couleur
SVG2D.setPaint(Color.black);
// drawString(String,x,y)
SVG2D.drawString("un cercle",20,20)
// on change la couleur
SVG2D.setPaint(Color.red);
// une forme elliptique
Shape cercle = new Ellipse2D.Double(80,80,50,50);
SVG2D.fill(cercle);
// quelques lignes pour faire joli
// la taille de notre canvas
Dimension d = SVG2D.getSVGCanvasSize();
int nbreLigne = 25;
for(int i = 0; i < nbreLigne; i++){
double ratio = (double)i / (double)nbreLigne;
Line2D line = new Line2D.Double(0,
ratio * d.height,
ratio * d.width,
d.height);
SVG2D.draw(line);
}
Mais ce n'est pas suffisant.
C'est ici que nous associons notre document SVG avec nos formes dessinées.
Element root = doc.getDocumentElement(); SVG2D.getRoot(root);
Nous n'avons pas à nous occuper de la façon dont cela fonctionne pour l'instant.
A partir de maintenant il nous suffit d'envoyer notre document SVG à notre canvas.
Le rôle de l'objet SVG2D est terminé pour notre example et
il a créé la structure Dom nécessaire.
Afficher le SVG
Nous sommes en pays connu pour ceux qui ont lu mon premier article sur Batik et Svg et pour tout ceux
qui connaissent Graphics2D.
Nous avons toujours besoin d'un cadre d'affichage (notre fenetre Frame) et un espace pour notre Svg (canvas).
Nous allons nous passer du Panel et implémenter notre canvas directement à la frame en utilisant la méthode getContentPanel(). Nous rendons la fenêtre visible (c'est mieux) et un comportement de fermeture de celle-ci par defaut.
Le plus important dans cette partie est l'association du document SVG et de notre zone d'affichage canvas.
Batik fournit la méthode setSVGDocument() qui failite bien la tâche.
public void renderingSVG() {
canvas = new JSVGCanvas();
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPanel().add(canvas);
// on associe le document SVG au canvas
canvas.setSVGDocument(doc);
frame.pack();
frame.setVisible();
}
Le code est terminé ; ous avez tout ce qu'il faut pour le réaliser.
Je vous conseille d'utiliser un IDE tel Eclipse ou Netbeans et d'en profiter pour lire les
aide de la javadoc qui s'affiche sur le différentes méthodes et propriétés.
Petites astuces pour cela
Survoler ou faites un clic gauche sur la méthode pour afficher l'aide javadoc.
F2 (focus) pour "geler la fenetre d'aide.
Echap (Escape) pour fermer la fenetre d'aide.
Cliquer sur la méthode ou propriété et appuye + ou - longuement sur CTRL pour ouvrir un lien
vers celle-ci.
Tester également Ctrl + o
Le code complet
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import javax.swing.JFrame;
import org.apache.batik.swing.*;
import org.apache.batik.svggen.*;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.w3c.dom.*;
import org.w3c.dom.svg.*;
public class SvgGraphicApp {
SVGDocument doc = null;
SVGGraphics2D SVG2d = null;
/**
*
*/
JFrame frame = null;
JSVGCanvas canvas = null;
public SvgGraphicApp(){
DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
String svgns = SVGDOMImplementation.SVG_NAMESPACE_URI;
doc = (SVGDocument) impl.createDocument(svgns, "svg", null);
SVG2d = new SVGGraphics2D(doc);
}
public void renderingSVG(){
canvas = new JSVGCanvas();
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(canvas);
canvas.setSVGDocument(doc);
frame.pack();
frame.setVisible(true);
}
public void drawSvg(){
SVG2d.setPaint(Color.black);
SVG2d.drawString("un cercle",20, 20);
SVG2d.setPaint(Color.red);
Shape cercle = new Ellipse2D.Double(80,80,50,50);
SVG2d.fill(cercle);
SVG2d.setSVGCanvasSize(new Dimension(200,200));
Dimension d = SVG2d.getSVGCanvasSize();
for(int i = 0 ; i <25 ; i++){
double ratio = (double)i / (double)25;
Line2D line = new Line2D.Double(0,ratio * d.height,ratio * d.width,d.height);
SVG2d.draw(line);
}
Element root = doc.getDocumentElement();
SVG2d.getRoot(root);
}
public static void main(String[]args){
SvgGraphicApp svgApp = new SvgGraphicApp();
svgApp.drawSvg();
svgApp.renderingSVG();
}
}
