created location placer factory

made debugger changeable from outside the code
made possible to add more converters
Made changeable FPS in window
This commit is contained in:
Macocian Adrian Radu
2020-07-08 20:11:08 +03:00
parent 4428e45ddd
commit 0d6716e528
18 changed files with 243 additions and 117 deletions

View File

@@ -1,24 +1,6 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<Window <Window Visible="True" Size="1024, 576">
Name="Window" <Button BackgroundColor="#ff0000" Label="Button 1" Icon="circle" Location="top_left" Size="0.3f, 0.1f"/>
Visible="True" <ToggleButton BackgroundColor="#00ff00" Label="Button 2" Icon="arrow_up_white" Location="top_right" Size="0.3f, 0.3f"/>
Title="GUI DEMO" <Panel BackgroundColor="#555555" Size="0.5f, 0.5f" Location="0f, 0.5f"/>
Size="1024, 576">
<Button
BackgroundColor="#ff0000"
Label="Button 1"
Icon="circle"
Location="top_left"
Size="0.3f, 0.1f"/>
<ToggleButton
BackgroundColor="#00ff00"
Label="Button 2"
Icon="arrow_up_white"
Location="top_right"
Size="0.3f, 0.3f"/>
<Panel
BackgroundColor="#555555"
Size="0.5f, 0.5f"
Location="0f, 0.5f"
/>
</Window> </Window>

View File

@@ -1,20 +1,9 @@
import guiTree.Components.Button; import parser.XMLParser;
import guiTree.Components.Panel;
import guiTree.Components.Picture;
import guiTree.Visual;
import guiTree.Window;
import guiTree.events.MouseAdapter;
import parser.XAMLParser;
import java.awt.event.MouseEvent;
import java.io.File;
public class Main { public class Main {
public static void main(String[] args) { public static void main(String[] args) {
Window window = null;
Visual.setEnableGPU(true);
try { try {
window = XAMLParser.parse("otherui.xml"); XMLParser.parse("otherui.xml");
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@@ -82,8 +82,7 @@ public class Button extends MenuItem {
} }
@Override @Override
public void paint(Image imageBuffer) public void paint(Image imageBuffer) {
{
//Get Graphics //Get Graphics
Graphics2D g = (Graphics2D)imageBuffer.getGraphics(); Graphics2D g = (Graphics2D)imageBuffer.getGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
@@ -109,7 +108,13 @@ public class Button extends MenuItem {
//Draw Icon //Draw Icon
if(icon != null) { if(icon != null) {
int iconX = (getWidth() - iconWidth - textWidth - 10) / 2; int iconX;
if(textWidth != 0) {
iconX = (getWidth() - iconWidth - textWidth - 10) / 2;
}
else {
iconX = (getWidth() - iconWidth) / 2;
}
int iconY = (getHeight() - iconHeight)/2; int iconY = (getHeight() - iconHeight)/2;
Graphics2D g2 = (Graphics2D)imageBuffer.getGraphics(); Graphics2D g2 = (Graphics2D)imageBuffer.getGraphics();
g2.drawImage(icon, iconX, iconY, null); g2.drawImage(icon, iconX, iconY, null);

View File

@@ -0,0 +1,38 @@
package guiTree.Components.Decorations.Placers;
import java.util.HashMap;
import java.util.Map;
public class LocationPlacerFactory {
private static Map<String, Placer> placerMap;
private static boolean initialized = false;
public static Placer getPlacer(String name) {
if(!initialized) {
initialize();
}
if(placerMap.containsKey(name)) {
return placerMap.get(name);
}
return null;
}
public static void addPlacer(String name, Placer placer) {
placerMap.put(name, placer);
}
private static void initialize() {
initialized = true;
placerMap = new HashMap<>();
placerMap.put("top_left", new TopLeftPlacer());
placerMap.put("top_right", new TopRightPlacer());
placerMap.put("top_center", new TopCenterPlacer());
placerMap.put("middle_left", new MiddleLeftPlacer());
placerMap.put("middle_right", new MiddleRightPlacer());
placerMap.put("middle_center", new MiddleCenterPlacer());
placerMap.put("bottom_left", new BottomLeftPlacer());
placerMap.put("bottom_right", new BottomRightPlacer());
placerMap.put("bottom_center", new BottomCenterPlacer());
placerMap.put("general", new GeneralPlacer());
}
}

View File

@@ -2,7 +2,7 @@ package guiTree.Helper;
public class Debugger { public class Debugger {
public enum Tag { public enum Tag {
LISTENER(true), LISTENER(false),
PAINTING(false), PAINTING(false),
FPS(false), FPS(false),
ANIMATIONS(false), ANIMATIONS(false),
@@ -10,6 +10,10 @@ public class Debugger {
public boolean value; public boolean value;
private void setValue(Boolean value) {
this.value = value;
}
Tag(boolean value) { Tag(boolean value) {
this.value = value; this.value = value;
} }
@@ -22,4 +26,8 @@ public class Debugger {
System.out.println("[" + tag.toString() + "] " + message); System.out.println("[" + tag.toString() + "] " + message);
} }
} }
public void enableTag(Tag tag, Boolean value) {
tag.setValue(value);
}
} }

View File

@@ -12,13 +12,11 @@ import guiTree.events.MouseListener;
import guiTree.events.MouseWheelListener; import guiTree.events.MouseWheelListener;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelEvent;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.*; import java.util.*;
@@ -237,48 +235,17 @@ public class Visual {
public void setLocation(String location) { public void setLocation(String location) {
location = location.toLowerCase(); location = location.toLowerCase();
Point4<Integer> margins = locationPlacer.getMargins(); Point4<Integer> margins = locationPlacer.getMargins();
switch (location) { Point2<Integer> absLocation = locationPlacer.getLocation();
case "top_left": { Point2<Float> relativeLocation = locationPlacer.getRelativeLocation();
locationPlacer = new TopLeftPlacer();
break; Placer placer = LocationPlacerFactory.getPlacer(location);
} if(placer == null) {
case "top_right": { System.out.println("Not a valid placer " + location);
locationPlacer = new TopRightPlacer(); return;
break;
}
case "top_center": {
locationPlacer = new TopCenterPlacer();
break;
}
case "middle_left": {
locationPlacer = new MiddleLeftPlacer();
break;
}
case "middle_center": {
locationPlacer = new MiddleCenterPlacer();
break;
}
case "middle_right": {
locationPlacer = new MiddleRightPlacer();
break;
}
case "bottom_left": {
locationPlacer = new BottomLeftPlacer();
break;
}
case "bottom_center": {
locationPlacer = new BottomCenterPlacer();
break;
}
case "bottom_right": {
locationPlacer = new BottomRightPlacer();
break;
}
default: {
System.err.println("Not a valid location");
return;
}
} }
locationPlacer = placer;
locationPlacer.setLocation(absLocation.x, absLocation.y);
locationPlacer.setRelativeLocation(relativeLocation.x, relativeLocation.y);
locationPlacer.setElementSize(width, height); locationPlacer.setElementSize(width, height);
locationPlacer.setMargins(margins.a, margins.b, margins.c, margins.d); locationPlacer.setMargins(margins.a, margins.b, margins.c, margins.d);
if(parent != null) { if(parent != null) {
@@ -337,14 +304,14 @@ public class Visual {
update(); update();
} }
public void setHardwareAccelerated(Boolean hardwareAccelerated) { public void setHardwareAcceleratedOnElement(Boolean hardwareAccelerated) {
this.hardwareAccelerated = hardwareAccelerated; this.hardwareAccelerated = hardwareAccelerated;
children.forEach(f -> f.setHardwareAccelerated(hardwareAccelerated)); children.forEach(f -> f.setHardwareAcceleratedOnElement(hardwareAccelerated));
initializeImageBuffer(); initializeImageBuffer();
update(); update();
} }
public static void setEnableGPU(Boolean gpu) { public static void setHardwareAcceleration(Boolean gpu) {
useGPU = gpu; useGPU = gpu;
System.setProperty("sun.java2d.opengl", "true"); System.setProperty("sun.java2d.opengl", "true");
System.setProperty("sun.java2d.accthreshold", "0"); System.setProperty("sun.java2d.accthreshold", "0");
@@ -377,6 +344,10 @@ public class Visual {
return height; return height;
} }
public Point2<Integer> getSize(){
return new Point2<>(width, height);
}
public Point2<Float> getRelativeSize() { public Point2<Float> getRelativeSize() {
return new Point2<>(relativeWidth, relativeHeight); return new Point2<>(relativeWidth, relativeHeight);
} }
@@ -439,11 +410,11 @@ public class Visual {
return paintColor; return paintColor;
} }
public boolean isHardwareAccelerated() { public boolean isElementHardwareAccelerated() {
return hardwareAccelerated; return hardwareAccelerated;
} }
public boolean isGpuEnabled() { public boolean isHardwareAccelerationEnabled() {
return useGPU; return useGPU;
} }
@@ -510,6 +481,16 @@ public class Visual {
update(); update();
} }
public void removeAllVisuals() {
children.forEach(f -> {
f.parent = null;
f.imageBuffer = null;
f.deactivate();
});
children.clear();
}
private void setParent(Visual parent) { private void setParent(Visual parent) {
locationPlacer.setParentSize(parent.width, parent.height); locationPlacer.setParentSize(parent.width, parent.height);
this.parent = parent; this.parent = parent;
@@ -549,14 +530,11 @@ public class Visual {
i--; i--;
} }
} }
validating.lock();
if(dirty && active) { if(dirty && active) {
validating.lock(); revalidate();
try {
revalidate();
} finally {
validating.unlock();
}
} }
validating.unlock();
} }
private void revalidate() { private void revalidate() {
@@ -567,6 +545,7 @@ public class Visual {
clearImageBuffer(); clearImageBuffer();
paint(imageBuffer); paint(imageBuffer);
for (int i = 0; i < children.size(); i++) { for (int i = 0; i < children.size(); i++) {
Visual v = children.get(i); Visual v = children.get(i);
if (v.dirty && v.active) { if (v.dirty && v.active) {
@@ -897,11 +876,11 @@ public class Visual {
} }
public void update() { public void update() {
validating.lock();
if(!dirty) { if(!dirty) {
validating.lock();
dirty = true; dirty = true;
validating.unlock();
} }
validating.unlock();
if(parent != null) { if(parent != null) {
parent.update(); parent.update();

View File

@@ -16,11 +16,12 @@ import java.awt.event.MouseEvent;
import java.awt.event.WindowListener; import java.awt.event.WindowListener;
import java.awt.event.WindowStateListener; import java.awt.event.WindowStateListener;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
public class Window extends Visual implements Runnable{ public class Window extends Visual implements Runnable{
public CustomFrame frame; public CustomFrame frame;
private int FPS;
private TitleBar titleBar; private TitleBar titleBar;
private Panel mainPanel; private Panel mainPanel;
private Panel contentPanel; private Panel contentPanel;
@@ -46,12 +47,15 @@ public class Window extends Visual implements Runnable{
BufferedImage icon = null; BufferedImage icon = null;
try { try {
icon = ImageIO.read(new File("resources\\icons\\square_white.png")); InputStream iconStream = getClass().getClassLoader().getResourceAsStream("icons/square_white.png");
assert iconStream != null;
icon = ImageIO.read(iconStream);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
TitleBar bar = new TitleBar(title, icon); TitleBar bar = new TitleBar(title, icon);
bar.setName("TitleBar"); bar.setName("TitleBar");
FPS = 60;
bar.setBackgroundColor(Color.GRAY); bar.setBackgroundColor(Color.GRAY);
this.setTitleBar(bar); this.setTitleBar(bar);
close = false; close = false;
@@ -158,6 +162,10 @@ public class Window extends Visual implements Runnable{
frame.setLocationRelativeTo(null); frame.setLocationRelativeTo(null);
} }
public void setFPS(int FPS) {
this.FPS = FPS;
}
public void setUndecorated(Boolean undecorated){frame.setUndecorated(undecorated);} public void setUndecorated(Boolean undecorated){frame.setUndecorated(undecorated);}
public void setState(int state) { public void setState(int state) {
@@ -258,7 +266,7 @@ public class Window extends Visual implements Runnable{
frameTimer.startTiming(); frameTimer.startTiming();
secondTimer.startTiming(); secondTimer.startTiming();
while(!close) { while(!close) {
if(frameTimer.getTime() >= 1000/60) { if(frameTimer.getTime() >= 1000/FPS) {
repaint(); repaint();
frameTimer.startTiming(); frameTimer.startTiming();
frames ++; frames ++;

View File

@@ -6,18 +6,19 @@ import guiTree.Helper.Debugger;
import guiTree.Visual; import guiTree.Visual;
import guiTree.Window; import guiTree.Window;
import org.w3c.dom.*; import org.w3c.dom.*;
import parser.converters.ConverterInterface;
import javax.xml.parsers.*; import javax.xml.parsers.*;
import java.io.*; import java.io.*;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.net.URL;
import java.util.List; import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class XAMLParser { public class XMLParser {
private final static String packageGuiTree = "guiTree."; private static Map<String, Class<?>> classMap;
private final static String packageComponents = "guiTree.Components.";
private final static String packageDecorations = "guiTree.Components.Decorations.";
private static Converter valueConverter = new Converter(); private static Converter valueConverter = new Converter();
private static void setAttributes(Object object, NamedNodeMap attributeList){ private static void setAttributes(Object object, NamedNodeMap attributeList){
@@ -68,9 +69,12 @@ public class XAMLParser {
public static Window parse(String filepath) throws Exception { public static Window parse(String filepath) throws Exception {
Object rootObject; Object rootObject;
Debugger.log("Started", Debugger.Tag.PARSING); Debugger.log("Started", Debugger.Tag.PARSING);
FileInputStream fileIS = new FileInputStream(new File("resources/" + filepath)); InputStream fileIS = XMLParser.class.getClassLoader().getResourceAsStream(filepath);
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder(); DocumentBuilder builder = builderFactory.newDocumentBuilder();
Class<?>[] classes = getClasses();
classMap = createClassTable(classes);
Document xmlDocument = builder.parse(fileIS); Document xmlDocument = builder.parse(fileIS);
xmlDocument.normalize(); xmlDocument.normalize();
@@ -117,18 +121,8 @@ public class XAMLParser {
} }
private static Object parseNode(Node parentNode)throws Exception{ private static Object parseNode(Node parentNode)throws Exception{
Class<?> parentClass; Class<?> parentClass = classMap.get(parentNode.getNodeName());
try {
parentClass = Class.forName(packageComponents.concat(parentNode.getNodeName()));
}
catch (ClassNotFoundException e) {
try {
parentClass = Class.forName(packageGuiTree.concat(parentNode.getNodeName()));
}
catch (ClassNotFoundException f) {
parentClass = Class.forName(packageDecorations.concat(parentNode.getNodeName()));
}
}
Debugger.log("Parsing " + parentClass, Debugger.Tag.PARSING); Debugger.log("Parsing " + parentClass, Debugger.Tag.PARSING);
Object parentObject = parentClass.getDeclaredConstructor().newInstance(); Object parentObject = parentClass.getDeclaredConstructor().newInstance();
Debugger.log("Constructor called successfully for " + parentObject, Debugger.Tag.PARSING); Debugger.log("Constructor called successfully for " + parentObject, Debugger.Tag.PARSING);
@@ -161,6 +155,89 @@ public class XAMLParser {
return parentObject; return parentObject;
} }
private static Class<?>[] getClasses()
throws ClassNotFoundException, IOException {
URL classRoot = XMLParser.class.getProtectionDomain().getCodeSource().getLocation();
URL projectRoot = ClassLoader.getSystemResource("");
File dir;
ClassLoader classLoader = XMLParser.class.getClassLoader();
ArrayList<Class<?>> classes = new ArrayList<>();
String path = classRoot.getPath();
if(path.indexOf('.') > 0) {
if (path.substring(path.lastIndexOf('.')).equals(".jar")) {
JarFile jarFile = new JarFile(classRoot.getPath());
Enumeration<JarEntry> jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
String filePath = jarEntry.getName();
if (filePath.indexOf('.') < 0) {
continue;
}
if (filePath.substring(filePath.lastIndexOf('.')).equals(".class")) {
filePath = filePath.replaceAll("/", ".");
classes.add(Class.forName(filePath.substring(0, filePath.lastIndexOf('.'))));
}
}
}
}
else {
dir = new File(classRoot.getFile());
classes.addAll(findClasses(dir, ""));
}
if(!projectRoot.getPath().equals(classRoot.getPath())){
dir = new File(projectRoot.getFile());
classes.addAll(findClasses(dir, ""));
}
return classes.toArray(new Class[0]);
}
private static List<Class<?>> findClasses(File directory, String packageName) throws ClassNotFoundException {
Debugger.log("Getting Classes from Directory: " + directory.getName(), Debugger.Tag.PARSING);
List<Class<?>> classes = new ArrayList<>();
if (!directory.exists()) {
return classes;
}
File[] files = directory.listFiles();
if(files == null) {
return classes;
}
for (File file : files) {
if (file.isDirectory()) {
assert !file.getName().contains(".");
classes.addAll(findClasses(file, packageName + "." + file.getName()));
} else if (file.getName().endsWith(".class")) {
if(packageName.length() == 0) {
classes.add(Class.forName(file.getName().substring(0, file.getName().length() - 6)));
}
else {
classes.add(Class.forName(packageName.substring(1) + '.' + file.getName().substring(0, file.getName().length() - 6)));
}
}
}
return classes;
}
private static Map<String, Class<?>> createClassTable(Class<?>[] classes) {
Map<String, Class<?>> map = new HashMap<>();
for(Class<?> c: classes) {
if(c.getName().indexOf('.') >= 0) {
map.put(c.getName().substring(c.getName().lastIndexOf('.') + 1), c);
}
else {
map.put(c.getName(), c);
}
}
return map;
}
public static void addConverter(ConverterInterface<?> converterInterface) {
valueConverter.addConverter(converterInterface);
}
private static void addVisual(Visual parentObject, Visual childObject){ private static void addVisual(Visual parentObject, Visual childObject){
parentObject.addVisual(childObject); parentObject.addVisual(childObject);
} }

View File

@@ -7,4 +7,9 @@ public class BooleanConverter implements ConverterInterface<Boolean> {
content = content.replaceAll(" ", ""); content = content.replaceAll(" ", "");
return Boolean.valueOf(content); return Boolean.valueOf(content);
} }
@Override
public Class<?> getConversionClass() {
return Boolean.class;
}
} }

View File

@@ -8,4 +8,9 @@ public class ColorConverter implements ConverterInterface<Color> {
content = content.replaceAll(" ", ""); content = content.replaceAll(" ", "");
return Color.decode(content); return Color.decode(content);
} }
@Override
public Class<?> getConversionClass() {
return Color.class;
}
} }

View File

@@ -30,4 +30,8 @@ public class Converter {
} }
throw new InvalidClassException(type.getName()); throw new InvalidClassException(type.getName());
} }
public void addConverter(ConverterInterface<?> converterInterface) {
converterTable.put(converterInterface.getConversionClass(), converterInterface);
}
} }

View File

@@ -4,4 +4,5 @@ import java.io.InvalidClassException;
public interface ConverterInterface<T> { public interface ConverterInterface<T> {
T convert(String content) throws InvalidClassException; T convert(String content) throws InvalidClassException;
Class<?> getConversionClass();
} }

View File

@@ -16,4 +16,9 @@ public class DirectionConverter implements ConverterInterface<Slider.Direction>
} }
throw new InvalidClassException(Slider.Direction.class.getName()); throw new InvalidClassException(Slider.Direction.class.getName());
} }
@Override
public Class<?> getConversionClass() {
return Slider.Direction.class;
}
} }

View File

@@ -7,4 +7,9 @@ public class DoubleConverter implements ConverterInterface<Double>{
content = content.replaceAll(" ", ""); content = content.replaceAll(" ", "");
return Double.parseDouble(content); return Double.parseDouble(content);
} }
@Override
public Class<?> getConversionClass() {
return Double.class;
}
} }

View File

@@ -15,4 +15,9 @@ public class FloatConverter implements ConverterInterface<Float> {
return Float.parseFloat(content); return Float.parseFloat(content);
} }
@Override
public Class<?> getConversionClass() {
return Float.class;
}
} }

View File

@@ -7,4 +7,9 @@ public class IntegerConverter implements ConverterInterface<Integer> {
content = content.replaceAll(" ", ""); content = content.replaceAll(" ", "");
return Integer.parseInt(content); return Integer.parseInt(content);
} }
@Override
public Class<?> getConversionClass() {
return Integer.class;
}
} }

View File

@@ -6,4 +6,9 @@ public class StringConverter implements ConverterInterface<String> {
public String convert(String content) { public String convert(String content) {
return content; return content;
} }
@Override
public Class<?> getConversionClass() {
return String.class;
}
} }