org.nuiton.widget.XMLGridParseConstraints Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nuiton-widgets Show documentation
Show all versions of nuiton-widgets Show documentation
Widgets graphiques utiles pour tous les développements.
/**
* *##% Graphical Widget
* Copyright (C) 2004 - 2008 CodeLutin
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser 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 Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* . ##%*
*/
package org.nuiton.widget;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.Point;
import java.io.ByteArrayInputStream;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.xml.sax.Attributes;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
/**
* Parses a XML input (a string, for the time being) into a Map of pairs (name,
* constraint)
*
* This class uses Apache Crimsom as the SaxParser
*
* @author Rafael Alvarez
*/
class XMLGridParseConstraints extends DefaultHandler {
XMLReader xr;
private int td;
private int tr;
private Map constraints;
private Map styles;
private GridBagConstraints constraint;
private int cellpadding;
private int cellspacing;
int anchor;
private static final int TOP = 0x0001;
private static final int BOTTOM = 0x0010;
private static final int LEFT = 0x0100;
private static final int RIGHT = 0x1000;
private static final int CENTER = 0x11111;
private boolean styleMode = false;
private String id;
/**
* permet de genere precisement la place de chaque td et de faire des
* decalage si necessaire
*/
private Map table;
public XMLGridParseConstraints() throws SAXException {
xr = XMLReaderFactory.createXMLReader();
xr.setContentHandler(this);
xr.setErrorHandler(new MyErrorHandler());
}
public Map parse(String s) throws SAXException {
constraints = new HashMap();
styles = new HashMap();
try {
xr.parse(new InputSource(new ByteArrayInputStream(s.getBytes())));
} catch (IOException e) {
e.printStackTrace();
}
return constraints;
}
private CharArrayWriter contents = new CharArrayWriter();
public void characters(char[] ch, int start, int length)
throws SAXException {
contents.write(ch, start, length);
}
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (localName.equals("td")) {
handleOpenTD(attributes);
} else if (localName.equals("table")) {
handleOpenTable(attributes);
} else if (localName.equals("style")) {
handleOpenStyle(attributes);
} else if (localName.equals("styles")) {
handleOpenStyles();
}
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (localName.equals("td")) {
handleCloseTD();
} else if (localName.equals("tr")) {
this.td = 0;
this.tr++;
} else if (localName.equals("table")) {
handleCloseTable();
} else if (localName.equals("style")) {
handleCloseTD();
} else if (localName.equals("styles")) {
handleCloseStyles();
}
}
private void handleOpenStyles() {
this.styleMode = true;
}
private void handleCloseStyles() {
this.styleMode = false;
}
private void handleOpenTable(Attributes attributes) {
table = new HashMap();
for (int i = 0; i < attributes.getLength(); i++) {
String name = attributes.getLocalName(i);
String value = attributes.getValue(i);
if (name.equals("cellpadding")) {
cellpadding = Integer.parseInt(value); // CHECK for parse
// exception
} else if (name.equals("cellspacing")) {
cellspacing = Integer.parseInt(value); // CHECK for parse
// exception
}
}
}
private void handleCloseTable() {
cellpadding = -1;
cellspacing = -1;
}
private void handleOpenStyle(Attributes attributes) {
constraint = new GridBagConstraints();
fillConstraint(attributes);
}
private void handleOpenTD(Attributes attributes) {
String tdStyle = attributes.getValue("", "class");
GridBagConstraints constraintStyle = null;
if (tdStyle != null) {
constraintStyle = styles.get(tdStyle);
}
if (constraintStyle != null) {
constraint = (GridBagConstraints) constraintStyle.clone();
} else {
constraint = new GridBagConstraints();
}
fillConstraint(attributes);
// this.td += constraint.gridwidth;
}
private void fillConstraint(Attributes attributes) {
constraint.gridx = this.td;
constraint.gridy = this.tr;
constraint.ipadx = cellpadding;
constraint.ipady = cellpadding;
constraint.insets = new Insets(cellspacing, cellspacing, cellspacing,
cellspacing);
contents.reset();
int colspan = constraint.gridwidth;
int rowspan = constraint.gridheight;
for (int i = 0; i < attributes.getLength(); i++) {
String name = attributes.getLocalName(i);
String value = attributes.getValue(i);
if (name.equals("colspan")) {
colspan = Integer.parseInt(value); // CHECK for parse exception
} else if (name.equals("rowspan")) {
rowspan = Integer.parseInt(value); // CHECK for parse exception
} else if (name.equals("fill")) {
if (value.equalsIgnoreCase("BOTH")) {
constraint.fill = GridBagConstraints.BOTH;
} else if (value.equalsIgnoreCase("HORIZONTAL")) {
constraint.fill = GridBagConstraints.HORIZONTAL;
} else if (value.equalsIgnoreCase("VERTICAL")) {
constraint.fill = GridBagConstraints.VERTICAL;
} else if (value.equalsIgnoreCase("NONE")) {
constraint.fill = GridBagConstraints.NONE;
}
} else if (name.equals("valign")) {
if (value.equalsIgnoreCase("TOP")) {
anchor = anchor | TOP;
} else if (value.equalsIgnoreCase("BOTTOM")) {
anchor = anchor | BOTTOM;
} else if (value.equalsIgnoreCase("MIDDLE")) {
anchor = anchor | CENTER;
}
} else if (name.equals("align")) {
if (value.equalsIgnoreCase("LEFT")) {
anchor = anchor | LEFT;
} else if (value.equalsIgnoreCase("RIGHT")) {
anchor = anchor | RIGHT;
} else if (value.equalsIgnoreCase("CENTER")) {
anchor = anchor | CENTER;
}
} else if (name.equals("width")) {
constraint.weightx = Double.parseDouble(value.substring(0,
value.length() - 1)) / 100;
} else if (name.equals("height")) {
constraint.weighty = Double.parseDouble(value.substring(0,
value.length() - 1)) / 100;
} else if (name.equals("id")) {
this.id = value;
}
}
constraint.gridwidth = colspan;
constraint.gridheight = rowspan;
if (!this.styleMode) {
// looking for first empty slot in table
Point p = new Point(constraint.gridx, constraint.gridy);
GridBagConstraints old = table.get(p);
while (old != null) {
p.translate(1, 0);
old = table.get(p);
}
constraint.gridx = (int) p.getX();
constraint.gridy = (int) p.getY();
// mark all used slot by this contrains in table map
for (int x = 0; x < colspan; x++) {
for (int y = 0; y < rowspan; y++) {
Point newPoint = p.getLocation();
newPoint.translate(x, y);
table.put(newPoint, constraint);
}
}
}
}
private void handleCloseTD() {
switch (anchor) {
case LEFT:
constraint.anchor = GridBagConstraints.WEST;
break;
case RIGHT:
constraint.anchor = GridBagConstraints.EAST;
break;
case CENTER:
constraint.anchor = GridBagConstraints.CENTER;
break;
case TOP:
constraint.anchor = GridBagConstraints.NORTH;
break;
case BOTTOM:
constraint.anchor = GridBagConstraints.SOUTH;
break;
case TOP | LEFT:
constraint.anchor = GridBagConstraints.NORTHWEST;
break;
case TOP | RIGHT:
constraint.anchor = GridBagConstraints.NORTHEAST;
break;
case BOTTOM | LEFT:
constraint.anchor = GridBagConstraints.SOUTHWEST;
break;
case BOTTOM | RIGHT:
constraint.anchor = GridBagConstraints.SOUTHEAST;
break;
}
if (this.styleMode) {
styles.put(this.id, constraint);
} else {
constraints.put(contents.toString().trim(), constraint);
}
contents.reset();
anchor = 0;
}
public String getErrors() {
MyErrorHandler errorHandler = (MyErrorHandler) xr.getErrorHandler();
return errorHandler.getErrors();
}
public Map getStyles() {
return Collections.unmodifiableMap(this.styles);
}
class MyErrorHandler implements ErrorHandler {
StringBuffer errors = new StringBuffer();
public void error(SAXParseException e) throws SAXException {
errors.append(e.getMessage()).append("\n");
}
public void fatalError(SAXParseException e) throws SAXException {
errors.append(e.getMessage()).append("\n");
}
public void warning(SAXParseException e) throws SAXException {
errors.append(e.getMessage()).append(Character.LINE_SEPARATOR);
}
public String getErrors() {
return errors.toString();
}
}
}