now new entity is created in XML as well, not only as in-memory object

This commit is contained in:
2024-07-22 00:46:49 +07:00
parent d4afde065d
commit d39374d8bb
30 changed files with 102 additions and 60 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
bin/

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,13 @@
package exception;
public class DuplicateEntryException extends EntityListIntegrityException {
public DuplicateEntryException() {
super();
}
public DuplicateEntryException(String message) {
super(message);
}
}

View File

@ -0,0 +1,12 @@
package exception;
public class EntityListIntegrityException extends Exception {
public EntityListIntegrityException() {
super();
}
public EntityListIntegrityException(String message) {
super(message);
}
}

View File

@ -29,6 +29,7 @@ import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import exception.DuplicateEntryException;
import listeners.CreateFrameAddElementListener;
import listeners.RemoveListElementEntityListener;
import model.Drawbox;
@ -90,7 +91,7 @@ public class ListGUI extends JPanel {
return (String) list.getSelectedValue();
}
public void addListElement(String name,String solid) {
public void addListElement(String name,String solid) throws DuplicateEntryException {
// плейсхолдеры для новых хитбоксов и дроубоксов, иначе всё валится с NPE
List<Point> hitboxPoints = new LinkedList<Point>();
List<Point> drawboxPoints = new LinkedList<Point>();
@ -101,7 +102,7 @@ public class ListGUI extends JPanel {
Entity e = new Entity(name, hitbox, drawbox);
e.setType(solid);
logger.finer("Entity \""+name+"\" was created.");
Project.getInstance().addEntity(e);
Project.getInstance().addEntity(e);
updateList();
}

View File

@ -10,6 +10,7 @@ import javax.swing.JTextField;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import exception.DuplicateEntryException;
import gui.ListGUI;
import gui.PropertyFrameAddElement;
@ -24,7 +25,11 @@ public class AddListElementEntityListener implements ActionListener
@Override
public void actionPerformed(ActionEvent e) {
listGUI.addListElement(propertyFrame.getInputName(),propertyFrame.getInputType());
propertyFrame.dispose();
try {
listGUI.addListElement(propertyFrame.getInputName(),propertyFrame.getInputType());
propertyFrame.dispose();
} catch (DuplicateEntryException e1) {
JOptionPane.showMessageDialog(propertyFrame, e1.getMessage(), "Cannot create an entity.", JOptionPane.ERROR_MESSAGE);
}
}
}

View File

@ -14,6 +14,7 @@ import javax.imageio.ImageIO;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
@ -27,6 +28,7 @@ import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import exception.DuplicateEntryException;
import model.Entity;
@ -198,29 +200,49 @@ public class Project implements Iterable<Entity> {
}
return null;
}
/*
* Добавляется обьект как в список всех сущностей, так и в xml-метаданные дерева(element objecttype)
* Это лишь добавление в метаданные, а не парсинг в файл! не путать!
* Для парсинга будет сделана отдельная функция!
/**
* Adds a new Entity to in-editor list of all entities and it's in-memory XML-representiation.<br>
* Does not write anything to actual XML-file, use {@link #writeXML()} for it
* @throws DuplicateEntryException - thrown if an entity with such a name already exists
* @params e - entity to add
*/
public void addEntity(Entity e) {
listEntity.add(e);
Element objecttype = document.createElement("objecttype");
objecttype.setAttribute("name", e.getName());
objecttype.setAttribute("color", "000000");//color of entity, needed by Tiled editor
document.getElementsByTagName("objecttypes").item(0).appendChild(objecttype);
/*
* TODO: set "class" property too (code below)
Element property = document.createElement("property");
objecttype.appendChild(property);
document.appendChild(objecttype);
property.setAttribute("name", "class");
property.setAttribute("type", "string");
property.setAttribute("default", e.getType());
public void addEntity(Entity e) throws DuplicateEntryException {
* creating hitbox or drowbox attributes in advance is insufficient
* they will be added while saving
*/
if(getEntityByName(e.getName()) != null)
throw new DuplicateEntryException("The entity with the name '" + e.getName() + "' already exists!");
listEntity.add(e);
Element objecttypeElement = document.createElement("objecttype");
document.getElementsByTagName("objecttypes")// get document root element named "objecttypes"
.item(0)
.appendChild(objecttypeElement); // add new "objecttype" element as a child
objecttypeElement.setAttribute("name", e.getName());
objecttypeElement.setAttribute("color", "000000");//color of entity, needed by Tiled editor
// format: <property name="class" type="string" default="INSERT REAL TYPE HERE"/>
Element classProperty = document.createElement("property");
classProperty.setAttribute("name", "class");
classProperty.setAttribute("type", "string");
classProperty.setAttribute("default", e.getType());
objecttypeElement.appendChild(classProperty);
// format: <property name="drawbox" type="string" default="INSERT 3 POINTS COORDINTANTES HERE"/>
Element drawboxProperty = document.createElement("property");
drawboxProperty.setAttribute("name", "drawbox");
drawboxProperty.setAttribute("type", "string");
drawboxProperty.setAttribute("default", ""); // empty, because on creation there is no drawbox yet
objecttypeElement.appendChild(drawboxProperty);
// format: <property name="hitbox" type="string" default="HITBOX_TYPE OFFSET_X OFFSET_Y SIZE"/>
Element hitboxProperty = document.createElement("property");
hitboxProperty.setAttribute("name", "hitbox");
hitboxProperty.setAttribute("type", "string");
hitboxProperty.setAttribute("default", ""); // empty, no hitbox yet
objecttypeElement.appendChild(hitboxProperty);
//printXMlToConsole(); //DEBUG!
}
/*
@ -243,7 +265,7 @@ public class Project implements Iterable<Entity> {
/**
* Возвращает объект сущности с заданным именем, или вбрасывает исключение, если такой сущности не существует.
* */
public Entity getEntityByName(String name) throws Exception {
public Entity getEntityByName(String name) {
//debug print
//System.out.println("----- session started ------");
for(Entity e: listEntity) {
@ -252,45 +274,18 @@ public class Project implements Iterable<Entity> {
return e;
}
// можно было бы и просто null возвращать, но обращение за несуществующей сущностью само по себе нехороший прецедент
// так что исключение призвано обратить внимание пользователя, если такое действительно случится
throw new Exception("No entity with such name!");
return null;
}
public void save() {
/*
* thanks to addEntity() and removeEntity() our Document and listEntity
* are interchangeable - they content exactly the same set of objects.
* So we'll iterate over Document instead listEntity. It's more convient
* in this case.
* */
NodeList objecttypes = document.getElementsByTagName("objecttype");
for(int i = 0; i < objecttypes.getLength(); i++) {
Node objecttype = objecttypes.item(i);
NodeList propertiesList = objecttype.getChildNodes();
for(int j = 0; j < objecttypes.getLength(); j++) {
Element property = (Element) propertiesList.item(j);
NamedNodeMap attributes = property.getAttributes();
String name = attributes.getNamedItem("name").getNodeValue();
Entity entity = null;
try {
entity = getEntityByName(name);
} catch (Exception e) {
//if there is no entity with such name we'll skip further parsing
System.err.println("Entity "+name+" is not found");
}
}
}
// parsing complete, writing to file now
writeXML();
}
private void writeXML() {
try {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setAttribute("indent-number", 4);
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(new FileOutputStream(path));
transformer.transform(source, result);
@ -300,11 +295,26 @@ public class Project implements Iterable<Entity> {
}
public void PrintEntitys() {
// TODO Auto-generated method stub
for(Entity ent:listEntity) {
ent.PrintEntity();
}
}
public void printXMlToConsole() {
try {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setAttribute("indent-number", 4);
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
} catch (TransformerException e) {
System.err.println("Cannot print XML to console. "+e);
}
}
@Override