/*
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 .
*/
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();
colors = new ArrayList();
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(" + "\"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 rects;
private ArrayList colors;
private Random generator;
private DocumentBuilder builder;
}