save functiton completed, unnecessary comments in Project removed

This commit is contained in:
2024-09-17 20:11:12 +07:00
parent 7d125b5931
commit b6c61cc958
10 changed files with 106 additions and 56 deletions

View File

@ -1,23 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<objecttypes> <objecttypes>
<objecttype name="misato" color="#a0a0a4"> <objecttype color="#a0a0a4" name="misato">
<property name="class" type="string" default="Solid"/> <property default="Solid" name="class" type="string"/>
<property name="drawbox" type="string" default="2 1 254 1 254 338 2 336"/> <property default="2 38 157 2 196 183 74 191 " name="drawbox" type="string"/>
<property name="hitbox" type="string" default="Circle 4 6 24"/> <property default="Circle 4 6 24" name="hitbox" type="string"/>
</objecttype> </objecttype>
<objecttype name="starlight" color="#a0a0a4"> <objecttype color="#a0a0a4" name="starlight">
<property name="class" type="string" default="Solid"/> <property default="Solid" name="class" type="string"/>
<property name="drawbox" type="string" default="2 1 253 1 254 468 2 490"/> <property default="6 2 224 14 206 170 34 176 " name="drawbox" type="string"/>
<property name="hitbox" type="string" default="Rectangle 0 0 76 119"/> <property default="Rectangle 0 0 76 119" name="hitbox" type="string"/>
</objecttype> </objecttype>
<objecttype name="tavern" color="#a0a0a4"> <objecttype color="#a0a0a4" name="tavern">
<property name="class" type="string" default="Solid"/> <property default="Solid" name="class" type="string"/>
<property name="drawbox" type="string" default="3 2 252 1 253 605 6 608"/> <property default="3 2 252 1 253 605 6 608" name="drawbox" type="string"/>
<property name="hitbox" type="string" default="Rectangle 0 0 96 98"/> <property default="Rectangle 0 0 96 98" name="hitbox" type="string"/>
</objecttype> </objecttype>
<objecttype name="TopHome" color="#a0a0a4"> <objecttype color="#a0a0a4" name="TopHome">
<property name="class" type="string" default="Solid"/> <property default="Solid" name="class" type="string"/>
<property name="drawbox" type="string" default="3 2 252 1 253 605 6 608"/> <property default="3 2 252 1 253 605 6 608" name="drawbox" type="string"/>
<property name="hitbox" type="string" default="Rectangle 0 0 96 98"/> <property default="Rectangle 0 0 96 98" name="hitbox" type="string"/>
</objecttype> </objecttype>
</objecttypes> </objecttypes>

BIN
res/success.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -1,11 +1,18 @@
package events; package events;
import model.Drawbox; import model.Drawbox;
import model.Entity;
/*
* Structure-like class no getters
* */
public class EntityDrawboxChangedEvent { public class EntityDrawboxChangedEvent {
Drawbox drawbox; public Drawbox drawbox;
public EntityDrawboxChangedEvent(Drawbox drawbox) { //storing entity object instead of just entity name will allow to get entity data without extra calls
// TODO Auto-generated constructor stub public Entity owner;
public EntityDrawboxChangedEvent(Drawbox drawbox, Entity owner) {
this.drawbox = drawbox; this.drawbox = drawbox;
this.owner = owner;
} }
} }

View File

@ -2,6 +2,6 @@ package events;
public interface EntityDrawboxChangedListener { public interface EntityDrawboxChangedListener {
void getEvent(EntityDrawboxChangedEvent event); void drawboxChanged(EntityDrawboxChangedEvent event);
} }

View File

@ -144,7 +144,9 @@ public class DrawboxEditor extends Editable {
private void notifySubscribers() { private void notifySubscribers() {
for (EntityDrawboxChangedListener listener : listeners) { for (EntityDrawboxChangedListener listener : listeners) {
listener.getEvent(new EntityDrawboxChangedEvent(entity.getDrawbox())); listener.drawboxChanged(
new EntityDrawboxChangedEvent(entity.getDrawbox(), entity)
);
} }
} }

View File

@ -68,7 +68,7 @@ public class MainGUI extends JFrame{
OpenXMLFileButtonListener = new OpenXMLFileButtonListener(list); OpenXMLFileButtonListener = new OpenXMLFileButtonListener(list);
openXMLJButton = createButton("XML",5,5, OpenXMLFileButtonListener,"res/xml.png"); 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 = createButton("Clear lines",155,5,null,"res/destroy.png");
clearLinesJButton.addActionListener(drawBoxPanel); clearLinesJButton.addActionListener(drawBoxPanel);

View File

@ -49,7 +49,7 @@ public class Drawbox {
public String toString() { public String toString() {
String stringDrawbox=""; String stringDrawbox="";
for (Point point : drawboxlistPoints) { for (Point point : drawboxlistPoints) {
stringDrawbox+=point.x+" "+point.y+" "; stringDrawbox+=((int)point.x)+" "+((int)point.y)+" "; //(int) because it is for XML
} }
return stringDrawbox; return stringDrawbox;
} }
@ -61,7 +61,9 @@ public class Drawbox {
public List<Point> getbaseListPoints() { public List<Point> getbaseListPoints() {
return baseListPoints; 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:"); System.out.println("|||Drawbox:");
if(baseListPoints!=null&&drawboxlistPoints!=null) { if(baseListPoints!=null&&drawboxlistPoints!=null) {
System.out.println("drawboxlistPoints:"); System.out.println("drawboxlistPoints:");

View File

@ -53,8 +53,8 @@ public class Entity {
public void PrintEntity() { public void PrintEntity() {
System.out.println("---------------------"); System.out.println("---------------------");
System.out.println("Name: "+thisName); System.out.println("Name: "+thisName);
this.thisDrawbox.Print(); this.thisDrawbox.printToConsole();
this.thisHitbox.Print(); this.thisHitbox.printToConsole();
System.out.println("---------------------"); System.out.println("---------------------");
} }
} }

View File

@ -65,7 +65,9 @@ public class Hitbox {
public List<Point> getListPoints() { public List<Point> getListPoints() {
return listPoints; 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();
System.out.println("|||Hitbox:"); System.out.println("|||Hitbox:");
if(shape!=null&&listPoints!=null) { if(shape!=null&&listPoints!=null) {

View File

@ -11,6 +11,8 @@ import java.util.List;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
@ -46,23 +48,19 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
* Просто заглушка, обычно заменяется актуальным путём в ходе изменения программы. <br> * Просто заглушка, обычно заменяется актуальным путём в ходе изменения программы. <br>
* Cм. {@link #setXMLPath(String)} и {@link #getXMLPath()} * 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"; public static final String DEFAULT_XML_FILENAME = "objecttypes.xml";
static Project thisProject; static Project thisProject;
private List <Entity> listEntity = new ArrayList<Entity>(); private List <Entity> listEntity = new ArrayList<Entity>();
private String path = DEFAULT_XML_PATH; private String path = DEFAULT_XML_PATH;
private String fileName = DEFAULT_XML_FILENAME; private String fileName = DEFAULT_XML_FILENAME;
// Получение фабрики, чтобы после получить билдер документов.
private DocumentBuilderFactory factory; private DocumentBuilderFactory factory;
// Получили из фабрики билдер, который парсит XML, создает структуру Document в виде иерархического дерева.
private DocumentBuilder builder; private DocumentBuilder builder;
// Запарсили XML, создав структуру Document. Теперь у нас есть доступ ко всем элементам, каким нам нужно.
private Document document; private Document document;
private static Logger logger = Logger.getLogger("repository.Project"); private static Logger logger = Logger.getLogger("repository.Project");
//!!!РЕАЛИЗАЦИЯ СИНГЛИТОНА!НАЧАЛО!!!
private Project(){}; private Project(){};
public static Project getInstance() { public static Project getInstance() {
@ -71,7 +69,6 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
} }
return thisProject; return thisProject;
}; };
//!!!РЕАЛИЗАЦИЯ СИНГЛИТОНА!ОКОНЧАНИЕ!!!
/** /**
* Устанавливает значение пути к XML. Все операции загрузки и сохранения будут работать с этой директорией.<br> * Устанавливает значение пути к XML. Все операции загрузки и сохранения будут работать с этой директорией.<br>
@ -80,12 +77,14 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
* <br><i>например: "C:/User/map/" или "/home/username/map/" или "res/map" (относительный путь рассчитывается от корня проекта)</i> * <br><i>например: "C:/User/map/" или "/home/username/map/" или "res/map" (относительный путь рассчитывается от корня проекта)</i>
* */ * */
public void setXMLPath(String newPath) { 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-файл с типами объектов, а так же папки с ресурсами. <br> * Возвращает актуальный путь к директории, в которой лежит XML-файл с типами объектов, а так же папки с ресурсами. <br>
* ps. считается, что ресурсы находятся в той же папке что XML-файл * Считается, что ресурсы находятся в той же папке что XML-файл. Должен включать / в конце
* */ * */
public String getXMLPath() { public String getXMLPath() {
return path; return path;
@ -108,12 +107,12 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
} }
/** /**
* Перегрузка {@link #load()}.<br>
* Использует {@link #setXMLFileName(String)} и {@link #setXMLPath(String)} для того, чтобы сохранить новый путь к XML-файлу и его имя. * Использует {@link #setXMLFileName(String)} и {@link #setXMLPath(String)} для того, чтобы сохранить новый путь к XML-файлу и его имя.
* Повторно вызывать их вручную не обязательно. * Повторно вызывать их вручную не обязательно.
* *
* @param directory - папка где хранится XML-файл и ресурсы (см. {@link #getXMLPath()}) * @param directory - папка где хранится XML-файл и ресурсы (см. {@link #getXMLPath()})
* @param name - имя XML-файла с определениями типов сущностей * @param name - имя XML-файла с определениями типов сущностей
* @see #load()
* */ * */
public void load(String directory, String name) { public void load(String directory, String name) {
setXMLPath(directory); setXMLPath(directory);
@ -138,13 +137,10 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
// Получение списка всех элементов objecttype внутри корневого элемента (getDocumentElement возвращает ROOT элемент XML файла). // Получение списка всех элементов objecttype внутри корневого элемента (getDocumentElement возвращает ROOT элемент XML файла).
NodeList objecttypeElements = document.getDocumentElement().getElementsByTagName("objecttype"); NodeList objecttypeElements = document.getDocumentElement().getElementsByTagName("objecttype");
for(int i = 0; i < objecttypeElements.getLength(); i++) { for(int i = 0; i < objecttypeElements.getLength(); i++) {
//System.out.println("---------------------");
Node objecttype = objecttypeElements.item(i); Node objecttype = objecttypeElements.item(i);
NamedNodeMap attributesObject = objecttype.getAttributes(); NamedNodeMap attributesObject = objecttype.getAttributes();
String entityName = new String(attributesObject.getNamedItem("name").getNodeValue()); String entityName = new String(attributesObject.getNamedItem("name").getNodeValue());
//System.out.println("Name: "+entityName);
parsingElementXMLtoElementList(entityName,objecttype); parsingElementXMLtoElementList(entityName,objecttype);
//System.out.println("---------------------");
} }
} }
@ -247,7 +243,7 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
//printXMlToConsole(); //DEBUG! //printXMlToConsole(); //DEBUG!
} }
/* /**
* Удаляется обьект из списка всех сущностей, и из xml-дерева * Удаляется обьект из списка всех сущностей, и из xml-дерева
*/ */
public void removeEntity(Entity e) { public void removeEntity(Entity e) {
@ -280,7 +276,9 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
} }
private void writeXML() { public void writeXML() {
stripEmptyElements(document);
try { try {
TransformerFactory transformerFactory = TransformerFactory.newInstance(); TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setAttribute("indent-number", 4); transformerFactory.setAttribute("indent-number", 4);
@ -289,10 +287,11 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(document); DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(new FileOutputStream(path)); StreamResult result = new StreamResult(new FileOutputStream(getXMLPath() + getXMLFileName()));
transformer.transform(source, result); transformer.transform(source, result);
JOptionPane.showMessageDialog(null, "Бугага, сохранилось!", "Success", JOptionPane.INFORMATION_MESSAGE);
} catch (TransformerException | FileNotFoundException e) { } 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<Entity>, EntityDrawboxChangedListener {
public void printXMlToConsole() { public void printXMlToConsole() {
stripEmptyElements(document);
try { try {
TransformerFactory transformerFactory = TransformerFactory.newInstance(); TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setAttribute("indent-number", 4); transformerFactory.setAttribute("indent-number", 4);
@ -333,15 +334,51 @@ public class Project implements Iterable<Entity>, EntityDrawboxChangedListener {
public List<Entity> getListEntity() { public List<Entity> getListEntity() {
return listEntity; return listEntity;
} }
/* /**
* Получение события при отрисовке нового Drawbox, для изменения XML-дерева. * Получение события при отрисовке нового Drawbox, для изменения XML-дерева.
* Объект event хранит в себе ссылку на новый объект drawbox и объект entity, для которой он был создан. * Объект event хранит в себе ссылку на новый объект drawbox и объект entity, для которой он был создан.
* Необходимо из Entity получить имя сущности и в XML-дереве изменить данные drawbox-а, используя функцию toString. * */
* */
@Override @Override
public void getEvent(EntityDrawboxChangedEvent event) { public void drawboxChanged(EntityDrawboxChangedEvent event) {
// TODO Auto-generated method stub 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);
}
} }
} }
//в момент окончания рисования, в зависимости в какой мы рисуем вкладке хитбокса, //в момент окончания рисования, в зависимости в какой мы рисуем вкладке хитбокса,