Mega Code Archive

 
Categories / Java / XML
 

How to write an XML file It saves a file describing a modern drawing in SVG format

/*    This program is a part of the companion code for Core Java 8th ed.    (http://horstmann.com/corejava)    This program is free software: you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation, either version 3 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program.  If not, see <http://www.gnu.org/licenses/>. */ import java.awt.Color; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.geom.Rectangle2D; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Random; import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; /**  * This program shows how to write an XML file. It saves a file describing a modern drawing in SVG  * format.  * @version 1.10 2004-09-04  * @author Cay Horstmann  */ public class XMLWriteTest {    public static void main(String[] args)    {       EventQueue.invokeLater(new Runnable()          {             public void run()             {                XMLWriteFrame frame = new XMLWriteFrame();                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);                frame.setVisible(true);             }          });    } } /**  * A frame with a component for showing a modern drawing.  */ class XMLWriteFrame extends JFrame {    public XMLWriteFrame()    {       setTitle("XMLWriteTest");       setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);       chooser = new JFileChooser();       // add component to frame       comp = new RectangleComponent();       add(comp);       // set up menu bar       JMenuBar menuBar = new JMenuBar();       setJMenuBar(menuBar);       JMenu menu = new JMenu("File");       menuBar.add(menu);       JMenuItem newItem = new JMenuItem("New");       menu.add(newItem);       newItem.addActionListener(new ActionListener()          {             public void actionPerformed(ActionEvent event)             {                comp.newDrawing();             }          });       JMenuItem saveItem = new JMenuItem("Save with DOM/XSLT");       menu.add(saveItem);       saveItem.addActionListener(new ActionListener()          {             public void actionPerformed(ActionEvent event)             {                try                {                   saveDocument();                }                catch (Exception e)                {                   JOptionPane.showMessageDialog(XMLWriteFrame.this, e.toString());                }             }          });       JMenuItem saveStAXItem = new JMenuItem("Save with StAX");       menu.add(saveStAXItem);       saveStAXItem.addActionListener(new ActionListener()          {             public void actionPerformed(ActionEvent event)             {                try                {                   saveStAX();                }                catch (Exception e)                {                   JOptionPane.showMessageDialog(XMLWriteFrame.this, e.toString());                }             }          });       JMenuItem exitItem = new JMenuItem("Exit");       menu.add(exitItem);       exitItem.addActionListener(new ActionListener()          {             public void actionPerformed(ActionEvent event)             {                System.exit(0);             }          });    }    /**     * Saves the drawing in SVG format, using DOM/XSLT     */    public void saveDocument() throws TransformerException, IOException    {       if (chooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION) return;       File f = chooser.getSelectedFile();       Document doc = comp.buildDocument();       Transformer t = TransformerFactory.newInstance().newTransformer();       t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,             "http://www.w3.org/TR/2000/CR-SVG-20000802/DTD/svg-20000802.dtd");       t.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "-//W3C//DTD SVG 20000802//EN");       t.setOutputProperty(OutputKeys.INDENT, "yes");       t.setOutputProperty(OutputKeys.METHOD, "xml");       t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");       t.transform(new DOMSource(doc), new StreamResult(new FileOutputStream(f)));    }        /**     * Saves the drawing in SVG format, using StAX     */    public void saveStAX() throws FileNotFoundException, XMLStreamException    {       if (chooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION) return;       File f = chooser.getSelectedFile();       XMLOutputFactory factory = XMLOutputFactory.newInstance();       XMLStreamWriter writer = factory.createXMLStreamWriter(new FileOutputStream(f));       comp.writeDocument(writer);       writer.close();    }    public static final int DEFAULT_WIDTH = 300;    public static final int DEFAULT_HEIGHT = 200;    private RectangleComponent comp;    private JFileChooser chooser; } /**  * A component that shows a set of colored rectangles  */ class RectangleComponent extends JComponent {    public RectangleComponent()    {       rects = new ArrayList<Rectangle2D>();       colors = new ArrayList<Color>();       generator = new Random();       DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();       try       {          builder = factory.newDocumentBuilder();       }       catch (ParserConfigurationException e)       {          e.printStackTrace();       }    }    /**     * Create a new random drawing.     */    public void newDrawing()    {       int n = 10 + generator.nextInt(20);       rects.clear();       colors.clear();       for (int i = 1; i <= n; i++)       {          int x = generator.nextInt(getWidth());          int y = generator.nextInt(getHeight());          int width = generator.nextInt(getWidth() - x);          int height = generator.nextInt(getHeight() - y);          rects.add(new Rectangle(x, y, width, height));          int r = generator.nextInt(256);          int g = generator.nextInt(256);          int b = generator.nextInt(256);          colors.add(new Color(r, g, b));       }       repaint();    }    public void paintComponent(Graphics g)    {       if (rects.size() == 0) newDrawing();       Graphics2D g2 = (Graphics2D) g;       // draw all rectangles       for (int i = 0; i < rects.size(); i++)       {          g2.setPaint(colors.get(i));          g2.fill(rects.get(i));       }    }    /**     * Creates an SVG document of the current drawing.     * @return the DOM tree of the SVG document     */    public Document buildDocument()    {       Document doc = builder.newDocument();       Element svgElement = doc.createElement("svg");       doc.appendChild(svgElement);       svgElement.setAttribute("width", "" + getWidth());       svgElement.setAttribute("height", "" + getHeight());       for (int i = 0; i < rects.size(); i++)       {          Color c = colors.get(i);          Rectangle2D r = rects.get(i);          Element rectElement = doc.createElement("rect");          rectElement.setAttribute("x", "" + r.getX());          rectElement.setAttribute("y", "" + r.getY());          rectElement.setAttribute("width", "" + r.getWidth());          rectElement.setAttribute("height", "" + r.getHeight());          rectElement.setAttribute("fill", colorToString(c));          svgElement.appendChild(rectElement);       }       return doc;    }    /**     * Writers an SVG document of the current drawing.     * @param writer the document destination     */    public void writeDocument(XMLStreamWriter writer) throws XMLStreamException    {       writer.writeStartDocument();       writer.writeDTD("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20000802//EN\" "              + "\"http://www.w3.org/TR/2000/CR-SVG-20000802/DTD/svg-20000802.dtd\">");       writer.writeStartElement("svg");       writer.writeAttribute("width", "" + getWidth());       writer.writeAttribute("height", "" + getHeight());       for (int i = 0; i < rects.size(); i++)       {          Color c = colors.get(i);          Rectangle2D r = rects.get(i);          writer.writeEmptyElement("rect");          writer.writeAttribute("x", "" + r.getX());          writer.writeAttribute("y", "" + r.getY());          writer.writeAttribute("width", "" + r.getWidth());          writer.writeAttribute("height", "" + r.getHeight());          writer.writeAttribute("fill", colorToString(c));                }       writer.writeEndDocument(); // closes svg element    }          /**     * Converts a color to a hex value.     * @param c a color     * @return a string of the form #rrggbb     */    private static String colorToString(Color c)    {       StringBuffer buffer = new StringBuffer();       buffer.append(Integer.toHexString(c.getRGB() & 0xFFFFFF));       while (buffer.length() < 6)          buffer.insert(0, '0');       buffer.insert(0, '#');       return buffer.toString();    }    private ArrayList<Rectangle2D> rects;    private ArrayList<Color> colors;    private Random generator;    private DocumentBuilder builder; }