diff --git a/res/objecttypes - Copy.xml b/res/objecttypes - Copy.xml
index 93b9ada..c2554d3 100644
--- a/res/objecttypes - Copy.xml
+++ b/res/objecttypes - Copy.xml
@@ -1,23 +1,23 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/success.png b/res/success.png
new file mode 100644
index 0000000..f6505c0
Binary files /dev/null and b/res/success.png differ
diff --git a/src/events/EntityDrawboxChangedEvent.java b/src/events/EntityDrawboxChangedEvent.java
index 38da3d9..0ab8d7c 100644
--- a/src/events/EntityDrawboxChangedEvent.java
+++ b/src/events/EntityDrawboxChangedEvent.java
@@ -1,11 +1,18 @@
package events;
import model.Drawbox;
+import model.Entity;
+/*
+ * Structure-like class no getters
+ * */
public class EntityDrawboxChangedEvent {
- Drawbox drawbox;
- public EntityDrawboxChangedEvent(Drawbox drawbox) {
- // TODO Auto-generated constructor stub
+ public Drawbox drawbox;
+ //storing entity object instead of just entity name will allow to get entity data without extra calls
+ public Entity owner;
+
+ public EntityDrawboxChangedEvent(Drawbox drawbox, Entity owner) {
this.drawbox = drawbox;
+ this.owner = owner;
}
}
diff --git a/src/events/EntityDrawboxChangedListener.java b/src/events/EntityDrawboxChangedListener.java
index 5e6b90b..5440118 100644
--- a/src/events/EntityDrawboxChangedListener.java
+++ b/src/events/EntityDrawboxChangedListener.java
@@ -2,6 +2,6 @@ package events;
public interface EntityDrawboxChangedListener {
- void getEvent(EntityDrawboxChangedEvent event);
+ void drawboxChanged(EntityDrawboxChangedEvent event);
}
diff --git a/src/gui/DrawboxEditor.java b/src/gui/DrawboxEditor.java
index b39ab46..ba85cf3 100644
--- a/src/gui/DrawboxEditor.java
+++ b/src/gui/DrawboxEditor.java
@@ -144,7 +144,9 @@ public class DrawboxEditor extends Editable {
private void notifySubscribers() {
for (EntityDrawboxChangedListener listener : listeners) {
- listener.getEvent(new EntityDrawboxChangedEvent(entity.getDrawbox()));
+ listener.drawboxChanged(
+ new EntityDrawboxChangedEvent(entity.getDrawbox(), entity)
+ );
}
}
diff --git a/src/gui/MainGUI.java b/src/gui/MainGUI.java
index b71aedb..63a6288 100644
--- a/src/gui/MainGUI.java
+++ b/src/gui/MainGUI.java
@@ -68,7 +68,7 @@ public class MainGUI extends JFrame{
OpenXMLFileButtonListener = new OpenXMLFileButtonListener(list);
openXMLJButton = createButton("XML",5,5, OpenXMLFileButtonListener,"res/xml.png");
- saveXMLJButton = createButton("Save",80,5,(e)-> Project.getInstance().printXMlToConsole(),"res/download.png");
+ saveXMLJButton = createButton("Save",80,5,(e)-> Project.getInstance().writeXML(),"res/download.png");
clearLinesJButton = createButton("Clear lines",155,5,null,"res/destroy.png");
clearLinesJButton.addActionListener(drawBoxPanel);
diff --git a/src/model/Drawbox.java b/src/model/Drawbox.java
index 3fd6474..b02235b 100644
--- a/src/model/Drawbox.java
+++ b/src/model/Drawbox.java
@@ -49,7 +49,7 @@ public class Drawbox {
public String toString() {
String stringDrawbox="";
for (Point point : drawboxlistPoints) {
- stringDrawbox+=point.x+" "+point.y+" ";
+ stringDrawbox+=((int)point.x)+" "+((int)point.y)+" "; //(int) because it is for XML
}
return stringDrawbox;
}
@@ -61,7 +61,9 @@ public class Drawbox {
public List getbaseListPoints() {
return baseListPoints;
}
- public void Print() {
+
+ //not the same as toString()! the latter is for XML while printToConsole() is for console
+ public void printToConsole() {
System.out.println("|||Drawbox:");
if(baseListPoints!=null&&drawboxlistPoints!=null) {
System.out.println("drawboxlistPoints:");
diff --git a/src/model/Entity.java b/src/model/Entity.java
index c7fbb0a..82786ec 100644
--- a/src/model/Entity.java
+++ b/src/model/Entity.java
@@ -53,8 +53,8 @@ public class Entity {
public void PrintEntity() {
System.out.println("---------------------");
System.out.println("Name: "+thisName);
- this.thisDrawbox.Print();
- this.thisHitbox.Print();
+ this.thisDrawbox.printToConsole();
+ this.thisHitbox.printToConsole();
System.out.println("---------------------");
}
}
diff --git a/src/model/Hitbox.java b/src/model/Hitbox.java
index 0beebc3..de3aa36 100644
--- a/src/model/Hitbox.java
+++ b/src/model/Hitbox.java
@@ -65,7 +65,9 @@ public class Hitbox {
public List getListPoints() {
return listPoints;
}
- public void Print() {
+
+ //not the same as toString()! the latter is for XML while printToConsole() is for console
+ public void printToConsole() {
System.out.println();
System.out.println("|||Hitbox:");
if(shape!=null&&listPoints!=null) {
diff --git a/src/repository/Project.java b/src/repository/Project.java
index 76127fb..3223def 100644
--- a/src/repository/Project.java
+++ b/src/repository/Project.java
@@ -11,6 +11,8 @@ import java.util.List;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
+import javax.swing.ImageIcon;
+import javax.swing.JOptionPane;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
@@ -46,23 +48,19 @@ public class Project implements Iterable, EntityDrawboxChangedListener {
* Просто заглушка, обычно заменяется актуальным путём в ходе изменения программы.
* Cм. {@link #setXMLPath(String)} и {@link #getXMLPath()}
* */
- public static final String DEFAULT_XML_PATH = "res/";
+ public static final String DEFAULT_XML_PATH = "res/"; //TODO: make an actual path to example objecttypes in the root of the project
public static final String DEFAULT_XML_FILENAME = "objecttypes.xml";
static Project thisProject;
private List listEntity = new ArrayList();
private String path = DEFAULT_XML_PATH;
private String fileName = DEFAULT_XML_FILENAME;
- // Получение фабрики, чтобы после получить билдер документов.
private DocumentBuilderFactory factory;
- // Получили из фабрики билдер, который парсит XML, создает структуру Document в виде иерархического дерева.
private DocumentBuilder builder;
- // Запарсили XML, создав структуру Document. Теперь у нас есть доступ ко всем элементам, каким нам нужно.
private Document document;
private static Logger logger = Logger.getLogger("repository.Project");
- //!!!РЕАЛИЗАЦИЯ СИНГЛИТОНА!НАЧАЛО!!!
private Project(){};
public static Project getInstance() {
@@ -71,7 +69,6 @@ public class Project implements Iterable, EntityDrawboxChangedListener {
}
return thisProject;
};
- //!!!РЕАЛИЗАЦИЯ СИНГЛИТОНА!ОКОНЧАНИЕ!!!
/**
* Устанавливает значение пути к XML. Все операции загрузки и сохранения будут работать с этой директорией.
@@ -80,12 +77,14 @@ public class Project implements Iterable, EntityDrawboxChangedListener {
*
например: "C:/User/map/" или "/home/username/map/" или "res/map" (относительный путь рассчитывается от корня проекта)
* */
public void setXMLPath(String newPath) {
- path = newPath;
+ if(newPath != null && !newPath.isEmpty()) {
+ path = newPath.trim();
+ } else System.err.println("Trying to submit empty path! Project.setXMLPath()");
}
/**
* Возвращает актуальный путь к директории, в которой лежит XML-файл с типами объектов, а так же папки с ресурсами.
- * ps. считается, что ресурсы находятся в той же папке что XML-файл
+ * Считается, что ресурсы находятся в той же папке что XML-файл. Должен включать / в конце
* */
public String getXMLPath() {
return path;
@@ -108,12 +107,12 @@ public class Project implements Iterable, EntityDrawboxChangedListener {
}
/**
- * Перегрузка {@link #load()}.
* Использует {@link #setXMLFileName(String)} и {@link #setXMLPath(String)} для того, чтобы сохранить новый путь к XML-файлу и его имя.
* Повторно вызывать их вручную не обязательно.
*
* @param directory - папка где хранится XML-файл и ресурсы (см. {@link #getXMLPath()})
* @param name - имя XML-файла с определениями типов сущностей
+ * @see #load()
* */
public void load(String directory, String name) {
setXMLPath(directory);
@@ -138,13 +137,10 @@ public class Project implements Iterable, EntityDrawboxChangedListener {
// Получение списка всех элементов objecttype внутри корневого элемента (getDocumentElement возвращает ROOT элемент XML файла).
NodeList objecttypeElements = document.getDocumentElement().getElementsByTagName("objecttype");
for(int i = 0; i < objecttypeElements.getLength(); i++) {
- //System.out.println("---------------------");
Node objecttype = objecttypeElements.item(i);
NamedNodeMap attributesObject = objecttype.getAttributes();
String entityName = new String(attributesObject.getNamedItem("name").getNodeValue());
- //System.out.println("Name: "+entityName);
parsingElementXMLtoElementList(entityName,objecttype);
- //System.out.println("---------------------");
}
}
@@ -247,7 +243,7 @@ public class Project implements Iterable, EntityDrawboxChangedListener {
//printXMlToConsole(); //DEBUG!
}
- /*
+ /**
* Удаляется обьект из списка всех сущностей, и из xml-дерева
*/
public void removeEntity(Entity e) {
@@ -280,7 +276,9 @@ public class Project implements Iterable, EntityDrawboxChangedListener {
}
- private void writeXML() {
+ public void writeXML() {
+ stripEmptyElements(document);
+
try {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setAttribute("indent-number", 4);
@@ -289,10 +287,11 @@ public class Project implements Iterable, EntityDrawboxChangedListener {
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(document);
- StreamResult result = new StreamResult(new FileOutputStream(path));
+ StreamResult result = new StreamResult(new FileOutputStream(getXMLPath() + getXMLFileName()));
transformer.transform(source, result);
+ JOptionPane.showMessageDialog(null, "Бугага, сохранилось!", "Success", JOptionPane.INFORMATION_MESSAGE);
} catch (TransformerException | FileNotFoundException e) {
- System.err.println("Saving project is unsuccsessfull! Erorr is: "+e);
+ JOptionPane.showMessageDialog(null, "Saving project is unsuccsessfull! Erorr is: "+e, "Project save unsuccsesfull", JOptionPane.ERROR_MESSAGE);
}
}
@@ -304,6 +303,8 @@ public class Project implements Iterable, EntityDrawboxChangedListener {
public void printXMlToConsole() {
+ stripEmptyElements(document);
+
try {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setAttribute("indent-number", 4);
@@ -333,15 +334,51 @@ public class Project implements Iterable, EntityDrawboxChangedListener {
public List getListEntity() {
return listEntity;
}
-/*
- * Получение события при отрисовке нового Drawbox, для изменения XML-дерева.
- * Объект event хранит в себе ссылку на новый объект drawbox и объект entity, для которой он был создан.
- * Необходимо из Entity получить имя сущности и в XML-дереве изменить данные drawbox-а, используя функцию toString.
- * */
+ /**
+ * Получение события при отрисовке нового Drawbox, для изменения XML-дерева.
+ * Объект event хранит в себе ссылку на новый объект drawbox и объект entity, для которой он был создан.
+ * */
@Override
- public void getEvent(EntityDrawboxChangedEvent event) {
- // TODO Auto-generated method stub
-
+ public void drawboxChanged(EntityDrawboxChangedEvent event) {
+ String entityName = event.owner.getName();
+ Node entityToUpdate = getEntityXMLNodeByName(entityName);
+ NodeList properties = entityToUpdate.getChildNodes();
+ for(int i = 0; i < properties.getLength(); i++) {
+ if(properties.item(i) instanceof Element) { // ignoring #text nodes
+ //we have hitbox, drawbox and class, gotta set the right one
+ Element propertyElement = ((Element)properties.item(i));
+ if (propertyElement.getAttribute("name").equals("drawbox")) {
+ propertyElement.setAttribute("default", event.owner.getDrawbox().toString());
+ }
+ }
+ }
+ }
+
+ private Node getEntityXMLNodeByName(String name) { //returns entitie's objecttype node
+ NodeList nl = document.getElementsByTagName("objecttype");
+ for(int i = 0; i < nl.getLength(); i++) {
+ Node objecttype = nl.item(i);
+ if(objecttype.getAttributes().getNamedItem("name").getNodeValue().equals(name)) {
+ return objecttype;
+ }
+ }
+ return null;
+ }
+
+ //https://stackoverflow.com/a/64659614/6929164
+ public static void stripEmptyElements(Node node)
+ {
+ NodeList children = node.getChildNodes();
+ for(int i = 0; i < children.getLength(); ++i) {
+ Node child = children.item(i);
+ if(child.getNodeType() == Node.TEXT_NODE) {
+ if (child.getTextContent().trim().length() == 0) {
+ child.getParentNode().removeChild(child);
+ i--;
+ }
+ }
+ stripEmptyElements(child);
+ }
}
}
//в момент окончания рисования, в зависимости в какой мы рисуем вкладке хитбокса,