Author: Lao Jiu – technology big millet

Core Java 8th Edition

Socializing: Zhihu

Public account: Lao Jiu School (Surprise for newcomers)

Special statement: the original is not easy, without authorization shall not be reproduced or copied, if you need to reproduce can contact the author authorized

preface

Don Box, author of Essential XML, joked that “XML has replaced Java, design patterns, and object technologies as the mainstream of the software industry today.” In fact, XML is a very useful technique for describing structured information. XML is not the answer to everything, but it works well with Java because, since the late 1990s, IBM, Apache, and other large companies have used high-quality Java libraries to process XML. After JDK 1.4, Sun incorporated a number of important Java library instances into the Java API.

Differences between XML and HTML

Although XML and HTML both have a root element, they differ as follows:

  • Unlike THE HTML language, XML is case sensitive; for example, H1 and H1 are different XML tags
  • In HTML you can omit closing tags, such as “

    “, but XML cannot omit closing tags

  • In XML, if the element is a single tag, you must use a “/” to indicate the result, such as “
  • In XML, attribute values must be quoted. In HTML, quotes are optional. For example, ”

    is an HTML tag, but not a valid XML tag.
  • Attributes can have no values in HTML, but attributes in XML must have values. For example,”

Structure of XML documents

An XML document usually has a header or then a document definition tag.

<! DOCTYPEweb-app PUBLIC"- / / SunMicrosystems.Inc.//DTD Web Application2.2 / / EN "and" http://java.sun.com/j2ee/dtds/web-app_2_2.dtd ">
Copy the code

The final BODY of the XML document must also include the root element, such as:

<configuration></configuration>
Copy the code

Elements and text are the “bread and butter” of XML documents. Here are some of the markers we might encounter:

1, the format of character references such as &# small number; Or &# hexadecimal;

   The & # 2333;
   &#xD9;
Copy the code

2. The entity reference format is as follows:

   &lt;
   &gt;
   &amp;
   &quot;
   &apos;
Copy the code

3, CDATA <! [CDTA[and]]>– these are character data in a special format. Are my favorite delimiters]]> this is < & > no longer keyword.

4. Processing instructions in XML documents. Such as

Each XML document has a processing instruction:

5. Comment tags

Parsing XML documents

To process an XML document, we need to parse it. A parser is a program that reads an XML document, determines its proper format, analyzes its constituent elements, and finally gives programmers access to those elements. Two XML parsers are available in the Java API:

  • Tree parsers, such as DOM parsers, read XML documents as a tree structure
  • A stream parser, such as a SAX parser, generates events when it reads XML

The DOM parser is a standard W2C organization standard that defines both Document and Element interfaces. Different vendors need to implement these interfaces, such as Apache and IBM both implement parsers. Let’s take a look at how Sun’s XML API is used.

The Document object is an in-memory tree structure of an XML Document that consists of classes that implement these interfaces, as shown in the figure above. When we use the XML API to read XML documents, we need the DocumentBuilder object to implement:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Copy the code

Then you can read it

The File File =... Or URL u =... Or InputStreamin=... Document doc = builder.parse(file);Copy the code

Then you can analyze the composition of the document

Element root = doc.getDocumentElement();
Copy the code

Let’s say we parse a document


      
<font></font>
Copy the code

Calling getDocumentElement returns the Font element, and the getTagName method returns the tag name of an element. Call the getChildNodes method to get the child element, which returns a collection or NodeList interface object that precedes the standard Java collection. The item method gets the corresponding item based on an index, and the getLength() method gets the total of all items. So, we can traverse the NodeList object as follows:

NodeList children = root.getChildNodes();
for(for i = 0; i < children.getLength(); i++){ Node child = children.item(i); ... }Copy the code

If you want only child elements and ignore whitespace, the code looks like this:

for(int i = 0; i < children.getLength(); i++){
    Mode child = children.item(i);
    if(child instanceofElement){ Element childElement = (Element)child; ... }}Copy the code

If you only want to deal with two elements, “name” and “size,” then if the document has a DTD, the parser can know which elements have no text, but are child elements, and can also exclude whitespace. The following code uses the getData method to get the characters stored in the Text node.

for(int i = 0; i < children.getLength(); i++){
   Node child = children.item(i);
   if(child instanceof Element){
       Element childElement = (Element)child;
       Text textNode = (Text)childElement.getFirstChild();
       String text = textNode.getData().trim();
       if(childElement. GetTagName (.) the equals (" name ")) {name = text; }else if(childElement. GetTagName (.) the equals (" size ")) {size = Integer. The parseInt (text); }}Copy the code

When parsing XML documents, our general API has the javax.xml.parsers package and the org.w3c. Dom package under the Document and Element and Node interfaces.

ShowDOMTree class

package com.jb.arklis.xml;
import static java.lang.System.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import javax.swing.tree.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;

/** Function: write a class to test the concept of a DOM tree
public class ShowDOMTree{
	
	public static void main(String[] args){
		EventQueue.invokeLater(new Runnable(){
			public void run(a){
				JFrame frame = newDOMTreeFrame(); }}); }}/** function: forms class */ used to demonstrate the DOM tree
class DOMTreeFrame extends JFrame{
	private DocumentBuilder builder;
	private static final int WIDTH = 650;
	private static final int HEIGHT = 450;
	
	
	public DOMTreeFrame(a){
		setTitle("Demo DOM tree formation");
		init();
		setSize(WIDTH,HEIGHT);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLocationRelativeTo(null);
		setVisible(true);
	}
	
	private void init(a){
		Container container = getContentPane();
		// Add menu
		JMenu fileMenu = new JMenu("File");
		JMenuItem openItem = new JMenuItem(" 打开 ");
		// Add open action handling event
		openItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent event){
				openFile(); // Call the method to open the file}}); fileMenu.add(openItem);// Add an exit menu
		JMenuItem exitItem = new JMenuItem("Quit");
		exitItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent event){
				exit(0); Exit the system correctly}}); fileMenu.add(exitItem); JMenuBar menuBar =new JMenuBar();
		menuBar.add(fileMenu);
		// Add menu bar
		setJMenuBar(menuBar);
	}
	
	protected void openFile(a){
		JFileChooser chooser = new JFileChooser();
		chooser.setCurrentDirectory(new File("."));
		// Read the file
		chooser.setFileFilter(new javax.swing.filechooser.FileFilter(){
			// Override the accept() method to select the file to read
			public boolean accept(File file){
				return file.isDirectory() || file.getName().toLowerCase().endsWith(".xml");
			}
			
			public String getDescription(a){
				return "The XML file"; }});// Returns the result from the file selector
		int returnInt = chooser.showOpenDialog(this);
		// If no XML file is found
		if(returnInt ! = JFileChooser.APPROVE_OPTION){// Then the result program
			return;
		}
		// Otherwise, process the XML document
		final File file = chooser.getSelectedFile();
		new SwingWorker<Document, Void>(){
			// Implement abstract class methods
			protected Document doInBackground(a)throws Exception{
				if(builder == null){
					DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
					builder = factory.newDocumentBuilder();
				}
				// Return the parsed DOM
				return builder.parse(file);
			}
			
			protected void done(a){
				try{
					Document doc = get();
					// Use JTree to display DOM objects
					JTree tree = new JTree(new DOMTreeModel(doc));
					tree.setCellRenderer(new DOMTreeCellRender());
					setContentPane(new JScrollPane(tree));
					validate();
				}catch(Exception e){
					e.printStackTrace();
					JOptionPane.showMessageDialog(DOMTreeFrame.this,e); } } }.execute(); }}/** function: write a class for processing XML documents as tree structures */
class DOMTreeModel implements TreeModel{
	private Document doc;
	
	public Object getChild(Object parent, int index){
		Node node = (Node)parent;
		NodeList list = node.getChildNodes();
		return list.item(index);
	}
	
	public DOMTreeModel(Document doc){
		this.doc = doc;
	}
	
	public Object getRoot(a){
		return doc.getDocumentElement();
	}
	
	public int getChildCount(Object parent){
		Node node = (Node)parent;
		NodeList list = node.getChildNodes();
		return list.getLength();
	}
	
	public int getIndexOfChild(Object parent, Object child){
		Node node = (Node)parent;
		NodeList list = node.getChildNodes();
		for(int i = 0; i < list.getLength(); i++){
			if(getChild(node,i) == child){
				returni; }}return -1;
	}
	
	public boolean isLeaf(Object node){
		return getChildCount(node) == 0;
	}
	
	public void valueForPathChanged(TreePath path, Object newValue){}public void addTreeModelListener(TreeModelListener listener){}public void removeTreeModelListener(TreeModelListener listener){}}/** function: Write a class to handle XML nodes */
class DOMTreeCellRender extends DefaultTreeCellRenderer{
	public Component getTreeCellRendererComponent(JTree tree, Object value,
		boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus){
		Node node = (Node)value;
		if(node instanceof Element){
			return elementPanel((Element)node);
		}
		super.getTreeCellRendererComponent(tree,value,selected,expanded,leaf,row,hasFocus);
		if(node instanceof CharacterData){
			setText(characterString((CharacterData)node));
		}else{
			setText(node.getClass() + ":" + node.toString());
		}
		return this;
	}
	
	public static JPanel elementPanel(Element element){
		JPanel panel = new JPanel();
		panel.add(new JLabel("Element:" + element.getTagName()));
		final NamedNodeMap map = element.getAttributes();
		panel.add(new JTable(new AbstractTableModel(){
			public int getRowCount(a){
				return map.getLength();
			}
			
			public int getColumnCount(a){
				return 2;
			}
			
			public Object getValueAt(int row, int count){
				return count == 0? map.item(row).getNodeName() : map.item(row).getNodeValue(); }}));return panel;
	}
	
	public static String characterString(CharacterData node){
		StringBuilder builder = new StringBuilder(node.getData());
		for(int i = 0; i < builder.length(); i++){
			if(builder.charAt(i) == '\r'){
				builder.replace(i, i + 1."\\r");
				i++;
			}else if(builder.charAt(i) == '\n'){
				builder.replace(i, i + 1."\\n");
				i++;
			}else if(builder.charAt(i) == '\t'){
				builder.replace(i, i + 1."\\t"); i++; }}if(node instanceof CDATASection){
			builder.insert(0."CDATASection: ");
		}else if(node instanceof Text){
			builder.insert(0."Text:");
		}else if(node instanceof Comment){
			builder.insert(0."Note:");
		}
		returnbuilder.toString(); }}Copy the code

Running effect

Validating XML documents

In the previous reading of the XML document as a DOM tree, we saw that we had to deal with blank and whether the node was the content of the node we needed. To address these issues, we use a feature of the XML parser that automatically verifies that an XML document is a valid document. If we wanted to specify the required documents, we would use a DTD or XML Schema to specify the customer’s requirements and ask the parser to validate them. For example, we use a DTD to specify content

This rule states that a font must have two child elements, one named name and one named size. We can also use Schema to describe:

Document Type Definition (DTD)

DTDS can be written in or outside XML documents in the following format:


      
<! DOCTYPEconfiguration[
   <! ELEMENTconfiguration... >More rules... ] >
<configuration></configuration>
Copy the code

Or:

The ELEMENT rule can specify that an ELEMENT has child elements. We can use regular expressions like this:

PCDATA represents any character.

When we use a DTD, we need to tell Factory to turn on validation: factory.setValidating(true); In this way, the parser validates the XML document against the DTD. Its most common function is to ignore whitespace in element content. Such as:

<font>
    <name>Helvetica</name>
    <size>26</size>
</font>
Copy the code

XML Schema validation

Schema is a more complex validation format than DTDS, so we will only discuss basic Schema validation here. For example, specify an XML document format as follows:


      
<configuration xmls:sli=http://www.w3.org/2001/XMLSchema-instance xsi:noNapespceSchemaLocation="Config. XSD"></configuration>
Copy the code

The above document declares config.xsd as a validation document.

A schema defines a “type” for each element, which can be a simple type – a string that uses a format constraint – or a complex type. Simple types are as follows:

  • xsd:string
  • xsd:int:
  • xsd:boolean

We use XSD to represent an XML Schema namespace, and some use XS to represent the namespace.

When we need a parser for schema validation, we need to perform the following steps:

  • factory.setNamespaceAware(true);
  • Final String JAXP_SHEMA_LANGUAGE=java.sun.com/xml/javxp/p… ;
  • Final String W3C_XML_SCHEMA=www.w3.org/2001/XMLSch… ;
  • factory.setAttribute(JAXP_SHEMA_LANGUAGE, W3C_XML_SCHEMA);

Use XPath to load information

If you want to specify a piece of information in an XML document, you can do so by navigating the DOM tree nodes, and the XPath language makes it very easy to access the tree nodes. Suppose you have the following XML document:

<configuration><database>
         <username>dbuser</username>
         <password>secret</password></database>
</configuration>
Copy the code

The steps to use DOM are as follows:

  • Get the document node
  • Enumerates all children
  • Locate the Database element
  • You get the first child element, the username element
  • We get the first child, which is a Text node
  • Get it data

With XPath, we only need to use one sentence:

/configuration/database/username
Copy the code

An XPath can describe a set of nodes in an XML document, such as /gridbag/row, or specify a specific element /gridbag/row[1]

XPath uses the “[]” operator to select specific elements; Use the “@” operator to get the attribute value /gridbag/row[1]/cell[1]/@anchor uses the function to count the number of elements repeated count(/gridbag/row) returns the number of row child elements. Apis for executing XPath expressions have been added since JDK 1.5, for example

XPathFactory xpFactory = XPathFactory.newInstance(); XPath path = xpFactory.newXPath(); String userName = path. The evaluate ("/configuration/database/userName, "doc);Copy the code

ShowXPath class

package com.jb.arklis.xml;
import static java.lang.System.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.xml.namespace.*;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
import org.w3c.dom.*;
import org.xml.sax.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;

/** Function: Write a class to test the XPath API
public class ShowXPath{
	
	public static void main(String[] args){
		EventQueue.invokeLater(new Runnable(){
			public void run(a){
				newXPathFrame(); }}); }}/** function: Displays the demo application's class */
class XPathFrame extends JFrame{
	private DocumentBuilder builder;
	private Document doc;
	private XPath path;
	private JTextField expression;
	private JTextField result;
	private JTextArea docText;
	private JComboBox typeCombo;
	
	
	public XPathFrame(a){
		setTitle("Demonstrate the use of the XPath API");
		setSize(450.300);
		init();
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLocationRelativeTo(null);
		setVisible(true);
	}
	
	private void init(a){
		Container container = getContentPane();
		// Set the menu
		JMenu fileMenu = new JMenu("Document");
		JMenuItem openItem = new JMenuItem("Open");
		// Add an event handler to the open item
		openItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent event){ openFile(); }}); fileMenu.add(openItem); JMenuItem exitItem =new JMenuItem("Quit");
		exitItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent event){
				exit(0); }}); fileMenu.add(exitItem);// Add the menu to the menu toolbar
		JMenuBar menuBar = new JMenuBar();
		menuBar.add(fileMenu);
		setJMenuBar(menuBar);// Sets the menu bar for the form
			
		ActionListener listener = new ActionListener(){
			public void actionPerformed(ActionEvent event){ evaluate(); }}; expression =new JTextField(20);
		expression.addActionListener(listener);
		JButton evaluateButton = new JButton("Execute XPath expressions");
		evaluateButton.addActionListener(listener);
		
		typeCombo = new JComboBox(new Object[]{
			"STRING"."NODE"."NODESET"."NUMBER"."BOOLEAN"
		});
		typeCombo.setSelectedItem("STRING");
		
		JPanel panel = new JPanel();
		panel.add(expression);
		panel.add(typeCombo);
		panel.add(evaluateButton);
		docText = new JTextArea(10.40);
		result = new JTextField();
		result.setBorder(new TitledBorder("XPath query result:"));
		
		container.add(panel,BorderLayout.NORTH);
		container.add(new JScrollPane(docText),BorderLayout.CENTER);
		container.add(result,BorderLayout.SOUTH);
		
		try{
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			builder = factory.newDocumentBuilder();
		}catch(Exception e){
			e.printStackTrace();
			JOptionPane.showMessageDialog(this,e);
		}
		
		XPathFactory xpFactory = XPathFactory.newInstance();
		path = xpFactory.newXPath();
		pack();
	}
	
	/* Processes the */ of XML files
	public void openFile(a){
		JFileChooser chooser = new JFileChooser();
		chooser.setCurrentDirectory(new File("."));
		
		chooser.setFileFilter(new javax.swing.filechooser.FileFilter(){
			public boolean accept(File file){
				return file.isDirectory() || file.getName().toLowerCase().endsWith(".xml");
			}
			public String getDescription(a){
				return "XML document"; }});int row = chooser.showOpenDialog(this);
		if(row ! = JFileChooser.APPROVE_OPTION){return;
		}
		File file = chooser.getSelectedFile();
		// Here is the key code
		try{
			byte[] bytes = new byte[(int)file.length()];
			new FileInputStream(file).read(bytes);
			docText.setText(new String(bytes));
			doc = builder.parse(file);
		}catch(Exception e){
			JOptionPane.showMessageDialog(this,e); }}public void evaluate(a){
		try{
			String typeName = (String)typeCombo.getSelectedItem();
			// Get the namespace, etc
			QName returnType = (QName)XPathConstants.class.getField(typeName).get(null);
			// Key code
			Object evalResult = path.evaluate(expression.getText(),doc,returnType);
			// If it is a set of nodes
			if(typeName.equals("NODESET")){
				NodeList list = (NodeList)evalResult;
				StringBuilder message = new StringBuilder();
				message.append("{");
				for(int i = 0; i < list.getLength(); i++){
					if(i > 0){
						message.append(",");
					}
					message.append("" + list.item(i));
				}
				message.append("}");
				result.setText(message.toString());
			}else{
				result.setText(""+ evalResult); }}catch(Exception e){
			JOptionPane.showMessageDialog(null,e); }}}Copy the code

Running effect

Use namespaces and XML streams

The Java language uses packages to avoid repeating class names, and XML uses something similar called namespaces to avoid repeating elements and attributes. A namespace is identified using a URI, such as www.w3.org/2001/XMLSch…

HTTP urls are used to locate a document, so we use urls to identify namespaces. JDK 1.6 integrates SAX into the API, and we can use SAX to stream parsing XML documents. We use XML apis to generate XML documents.

ShowXMLWriter class

package com.jb.arklis.xml;
import static java.lang.System.*;
import java.io.*;
import java.net.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import javax.xml.stream.*;
import java.util.*;
import org.w3c.dom.*;

/** Function: Use the SAX API to parse XML documents
public class ShowXMLWriter{
	public static void main(String[] args){
		EventQueue.invokeLater(new Runnable(){
			public void run(a){
				XMLWriterFrame frame = newXMLWriterFrame(); }}); }}/** function: write an example to display XML stream output author: Arklis Zeng Time: 2009-06-29 Location: Academic Department of Peking University Jade Bird Jinjiang Center version: ver 1.0.0 Note: */
class XMLWriterFrame extends JFrame{
	private static final int DEFAULT_WIDTH = 450;
	private static final int DEFAULT_HEIGHT = 300;
	private RectangleComponent rectangleComponent;
	private JFileChooser chooser;
	
	public XMLWriterFrame(a){
		setTitle("Demonstrate the use of XML output stream objects");
		setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
		init();
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLocationRelativeTo(null);
		setVisible(true);
	}
	
	private void init(a){
		Container container = getContentPane();
		chooser = new JFileChooser();
		rectangleComponent = new RectangleComponent();
		container.add(rectangleComponent);// Add a custom component
		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);
		// Here are the Settings menu items
		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){ rectangleComponent.newDrawing(); }}); JMenuItem saveItem =new JMenuItem("Save as DOM/XSLT");
		menu.add(saveItem);
		saveItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent evnet){
				try{
					saveDocument();
				}catch(Exception e){ e.printStackTrace(); }}}); JMenuItem saveStAxItem =new JMenuItem("Save as standard XML");
		menu.add(saveStAxItem);
		saveStAxItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent event){
				try{
					saveStAX();
				}catch(Exception e){ e.printStackTrace(); }}}); JMenuItem exitItem =new JMenuItem("Quit");
		menu.add(exitItem);
		exitItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent event){
				exit(0); }}); }public void saveDocument(a)throws TransformerException, IOException{
		
		if(chooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION){
			return;
		}
		
		File file = chooser.getSelectedFile();
		Document doc = rectangleComponent.buildDocument();
		Transformer transformer = TransformerFactory.newInstance().newTransformer();
		transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
			"http://www.w3.org/TR/2000/CR-SVG-20000802/DTD/svg-20000802.dtd");
		transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,"-//W3C//DTD SVG 20000802//EN");
		transformer.setOutputProperty(OutputKeys.INDENT,"yes");
		transformer.setOutputProperty(OutputKeys.METHOD,"xml");
		transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount"."2");
		transformer.transform(new DOMSource(doc),new StreamResult(new FileOutputStream(file)));
	}
	
	public void saveStAX(a)throws FileNotFoundException,XMLStreamException{
		if(chooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION){
			return;
		}
		File file = chooser.getSelectedFile();
		XMLOutputFactory factory = XMLOutputFactory.newInstance();
		XMLStreamWriter writer = factory.createXMLStreamWriter(newFileOutputStream(file)); rectangleComponent.writeDocument(writer); writer.close(); }}/** Function: component class for processing graphics */
class RectangleComponent extends JComponent{
	private ArrayList<Rectangle2D> rects;
	private ArrayList<Color>  colors;
	private Random generator;
	private DocumentBuilder builder;
	
	public RectangleComponent(a){
		rects = new java.util.ArrayList<Rectangle2D>();
		colors = new java.util.ArrayList<Color>();
		generator = new Random();
		
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		try{
			builder = factory.newDocumentBuilder();
		}catch(Exception e){ e.printStackTrace(); }}/** generates the drawing method */
	public void newDrawing(a){
		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(); / / redraw
	}
	
	// Perform the specific action of redrawing
	public void paintComponent(Graphics g){
		if(rects.size() == 0){
			newDrawing();
		}
		
		// Draw rect below
		Graphics2D g2 = (Graphics2D)g;
		for(int i = 0; i < rects.size(); i++){ g2.setPaint(colors.get(i)); g2.fill(rects.get(i)); }}/** Build document */
	public Document buildDocument(a){
		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 color = colors.get(i);
			Rectangle2D rect = rects.get(i);
			Element rectElement = doc.createElement("rect");
			rectElement.setAttribute("x"."" + rect.getX());
			rectElement.setAttribute("y"."" + rect.getY());
			rectElement.setAttribute("width"."" + rect.getWidth());
			rectElement.setAttribute("height"."" + rect.getHeight());
			rectElement.setAttribute("fill"."" + colorToString(color));
			svgElement.appendChild(rectElement);
		}
		return doc;
	}
	
	/** Save the current graphic as an SVG document */
	public void writeDocument(XMLStreamWriter writer){
		try{
			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 color = colors.get(i);
				Rectangle2D rect = rects.get(i);
				writer.writeEmptyElement("rect");
				writer.writeAttribute("x"."" + rect.getX());
				writer.writeAttribute("y"."" + rect.getY());
				writer.writeAttribute("width"."" + rect.getWidth());
				writer.writeAttribute("height"."" + rect.getHeight());
				writer.writeAttribute("fill"."" + colorToString(color));
			}
			writer.writeEndDocument();
		}catch(Exception e){ e.printStackTrace(); }}private static String colorToString(Color color){
		StringBuffer buffer = new StringBuffer();
		buffer.append(Integer.toHexString(color.getRGB() & 0xFFFFFF));
		while(buffer.length() < 6){
			buffer.insert(0.'0');
		}
		buffer.insert(0.The '#');
		returnbuffer.toString(); }}Copy the code

Running effect

We saved the Java2D graphics as an SVG document. Use XML for graphics techniques see Apache’s Batik Group website

The last

Remember to give dashu ❤️ attention + like + collect + comment + forward ❤️

Author: Lao Jiu School – technology big millet

Copyright belongs to the author. Commercial reprint please contact the author for authorization, non-commercial reprint please indicate the source.