7 Commits

12 changed files with 75 additions and 26 deletions

1
.gitignore vendored
View File

@@ -34,6 +34,7 @@ hs_err_pid*
Thumbs.db Thumbs.db
.gradle .gradle
local.properties
**/build/ **/build/
!src/**/build/ !src/**/build/

View File

@@ -11,9 +11,11 @@ und diese Projekt folgt [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Caching-Mechanismen in Klasse `util.Cache` ausgelagert. - Caching-Mechanismen in Klasse `util.Cache` ausgelagert.
- `util.io.ImageLoader` und `util.io.FontLoader` verwenden `Cache`. - `util.io.ImageLoader` und `util.io.FontLoader` verwenden `Cache`.
- `mouseWheelMoved` Eventhandler für Mausrad. - `mouseWheelMoved` Eventhandler für Mausrad.
- `DrawingLayer.imageRotate(...)` Methoden, um Bilder um ihr Zentrum gedreht zu zeichnen.
## Changed ## Changed
- Die Methoden in `Validator` erwarten nun als zweiten Parameter den Namen des Parameters, der geprüft wird. - Die Methoden in `Validator` erwarten nun als zweiten Parameter den Namen des Parameters, der geprüft wird.
- `DrawingLayer.image(...)` mit Größenänderung umbenannt zu `imageScale(...)`.
## Fixed ## Fixed
- `Constants.choice(int...)` und `Constants.choice(double...)` wiederhergestellt. - `Constants.choice(int...)` und `Constants.choice(double...)` wiederhergestellt.

View File

@@ -30,9 +30,9 @@ leichter nutzbar machen.
## Dokumentation ## Dokumentation
* [Schnellstart](quickstart.md) * [Schnellstart](schnellstart.md)
* [Installation](installation.md) * [Installation](installation.md)
* {{ javadoc_link() }} * [Javadoc]({{ javadoc() }})
## Über die Zeichenmaschine ## Über die Zeichenmaschine
@@ -68,3 +68,4 @@ Alternativen, von deren Nutzung gar nicht abgeraten werden soll.
Klassen, Methoden und Variablen verwendet. Ausnahme sind einzelne Klassen, Klassen, Methoden und Variablen verwendet. Ausnahme sind einzelne Klassen,
die im Zusammnehang mit dem Namen der Bibliothek stehen, wie die die im Zusammnehang mit dem Namen der Bibliothek stehen, wie die
Hauptklasse `Zeichenmaschine`. Hauptklasse `Zeichenmaschine`.

View File

@@ -2,10 +2,9 @@
Um ein einfaches Projekt mit der **Zeichenmaschine** aufzusetzen ist nicht mehr Um ein einfaches Projekt mit der **Zeichenmaschine** aufzusetzen ist nicht mehr
nötig, als nötig, als
die [JAR-Datei der aktuellen Version](https://github.com/jneug/zeichenmaschine/release/latest) die [JAR-Datei der aktuellen Version](https://github.com/jneug/zeichenmaschine/releases/latest)
herunterzuladen und dem *Classpath* des Projekts hinzuzufügen. Beschreibungen herunterzuladen und dem *Classpath* des Projekts hinzuzufügen. Beschreibungen
für für verschiedene Entwicklungsumgebungen sind hier aufgelistet.
verschiedene Entwicklungsumgebungen sind hier aufgelistet.
## Integration in Entwicklungsumgebungen ## Integration in Entwicklungsumgebungen

View File

@@ -8,7 +8,7 @@ site_dir: build/docs/site
theme: theme:
name: material name: material
custom_dir: docs/home_override/ # custom_dir: docs/home_override/
language: de language: de
logo: assets/icon_64.png logo: assets/icon_64.png
favicon: assets/icon_32.png favicon: assets/icon_32.png
@@ -37,7 +37,7 @@ extra_css:
- assets/zmstyles.css - assets/zmstyles.css
nav: nav:
- Einführung: einfuehrung.md - Einführung: index.md
- Schnellstart: schnellstart.md - Schnellstart: schnellstart.md
- Installation: installation.md - Installation: installation.md
- Tutorials: - Tutorials:

View File

@@ -1,6 +1,7 @@
package schule.ngb.zm.layers; package schule.ngb.zm.layers;
import schule.ngb.zm.Layer; import schule.ngb.zm.Layer;
import schule.ngb.zm.Updatable;
import schule.ngb.zm.anim.Animation; import schule.ngb.zm.anim.Animation;
import schule.ngb.zm.anim.AnimationFacade; import schule.ngb.zm.anim.AnimationFacade;
import schule.ngb.zm.anim.Easing; import schule.ngb.zm.anim.Easing;
@@ -24,20 +25,26 @@ public class ShapesLayer extends Layer {
*/ */
protected boolean clearBeforeDraw = true; protected boolean clearBeforeDraw = true;
private final List<Shape> shapes; protected boolean updateShapes = true;
protected final List<Shape> shapes;
private final List<Animation<? extends Shape>> animations; private final List<Animation<? extends Shape>> animations;
private final List<Updatable> updatables;
public ShapesLayer() { public ShapesLayer() {
super(); super();
shapes = new LinkedList<>(); shapes = new LinkedList<>();
animations = new LinkedList<>(); animations = new LinkedList<>();
updatables = new LinkedList<>();
} }
public ShapesLayer( int width, int height ) { public ShapesLayer( int width, int height ) {
super(width, height); super(width, height);
shapes = new LinkedList<>(); shapes = new LinkedList<>();
animations = new LinkedList<>(); animations = new LinkedList<>();
updatables = new LinkedList<>();
} }
public Shape getShape( int index ) { public Shape getShape( int index ) {
@@ -70,12 +77,24 @@ public class ShapesLayer extends Layer {
public void add( Shape... shapes ) { public void add( Shape... shapes ) {
synchronized( this.shapes ) { synchronized( this.shapes ) {
Collections.addAll(this.shapes, shapes); Collections.addAll(this.shapes, shapes);
for( Shape s : shapes ) {
if( Updatable.class.isInstance(s) ) {
updatables.add((Updatable) s);
}
}
} }
} }
public void add( Collection<Shape> shapes ) { public void add( Collection<Shape> shapes ) {
synchronized( this.shapes ) { synchronized( this.shapes ) {
this.shapes.addAll(shapes); this.shapes.addAll(shapes);
for( Shape s : shapes ) {
if( Updatable.class.isInstance(s) ) {
updatables.add((Updatable) s);
}
}
} }
} }
@@ -139,6 +158,16 @@ public class ShapesLayer extends Layer {
@Override @Override
public void update( double delta ) { public void update( double delta ) {
if( updateShapes ) {
Iterator<Updatable> uit = updatables.iterator();
while( uit.hasNext() ) {
Updatable u = uit.next();
if( u.isActive() ) {
u.update(delta);
}
}
}
Iterator<Animation<? extends Shape>> it = animations.iterator(); Iterator<Animation<? extends Shape>> it = animations.iterator();
while( it.hasNext() ) { while( it.hasNext() ) {
Animation<? extends Shape> anim = it.next(); Animation<? extends Shape> anim = it.next();

View File

@@ -19,7 +19,7 @@ public class Validator {
public static final <T> T requireNotNull( T obj, Supplier<String> msg ) { public static final <T> T requireNotNull( T obj, Supplier<String> msg ) {
if( obj == null ) { if( obj == null ) {
throw new NullPointerException(msg == null ? "Parameter may nut be null." : msg.get()); throw new NullPointerException(msg == null ? "Parameter may not be null." : msg.get());
} }
return obj; return obj;
} }

View File

@@ -1,9 +1,11 @@
package schule.ngb.zm.util.io; package schule.ngb.zm.util.io;
import schule.ngb.zm.util.Log; import schule.ngb.zm.util.Log;
import schule.ngb.zm.util.Validator;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
@@ -11,6 +13,7 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.function.Function; import java.util.function.Function;
import java.util.logging.Level;
/** /**
* Hilfsklasse, um Textdateien in verschiedenen Formaten einzulesen. * Hilfsklasse, um Textdateien in verschiedenen Formaten einzulesen.
@@ -63,6 +66,9 @@ public final class FileLoader {
* @return Eine Liste mit den Zeilen der Textdatei. * @return Eine Liste mit den Zeilen der Textdatei.
*/ */
public static List<String> loadLines( String source, Charset charset ) { public static List<String> loadLines( String source, Charset charset ) {
Validator.requireNotNull(source, "source");
Validator.requireNotNull(charset, "charset");
try( BufferedReader reader = ResourceStreamProvider.getReader(source, charset) ) { try( BufferedReader reader = ResourceStreamProvider.getReader(source, charset) ) {
List<String> result = new ArrayList<>(); List<String> result = new ArrayList<>();
@@ -72,8 +78,11 @@ public final class FileLoader {
} }
return result; return result;
} catch( MalformedURLException muex ) {
LOG.warn("Could not find resource for <%s>", source);
return Collections.emptyList();
} catch( IOException ex ) { } catch( IOException ex ) {
LOG.error(ex, "Error while loading lines from source <%s>", source); LOG.warn(ex, "Error while loading lines from source <%s>", source);
return Collections.emptyList(); return Collections.emptyList();
} }
} }
@@ -101,6 +110,9 @@ public final class FileLoader {
* @return Der Inhalt der Textdatei. * @return Der Inhalt der Textdatei.
*/ */
public static String loadText( String source, Charset charset ) { public static String loadText( String source, Charset charset ) {
Validator.requireNotNull(source, "source");
Validator.requireNotNull(charset, "charset");
try( BufferedReader reader = ResourceStreamProvider.getReader(source, charset) ) { try( BufferedReader reader = ResourceStreamProvider.getReader(source, charset) ) {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
@@ -110,8 +122,11 @@ public final class FileLoader {
} }
return result.toString(); return result.toString();
} catch( MalformedURLException muex ) {
LOG.warn("Could not find resource for <%s>", source);
return "";
} catch( IOException ex ) { } catch( IOException ex ) {
LOG.error(ex, "Error while loading string from source <%s>", source); LOG.warn(ex, "Error while loading string from source <%s>", source);
return ""; return "";
} }
} }

View File

@@ -10,6 +10,7 @@ import java.awt.Image;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@@ -62,8 +63,8 @@ public class FontLoader {
} }
public static Font loadFont( String name, String source ) { public static Font loadFont( String name, String source ) {
Validator.requireNotNull(source, "Font source may not be null"); Validator.requireNotNull(source, "source");
Validator.requireNotEmpty(source, "Font source may not be empty."); Validator.requireNotEmpty(source, "source");
if( fontCache.containsKey(name) ) { if( fontCache.containsKey(name) ) {
LOG.trace("Retrieved font <%s> from font cache.", name); LOG.trace("Retrieved font <%s> from font cache.", name);
@@ -91,10 +92,12 @@ public class FontLoader {
//ge.registerFont(font); //ge.registerFont(font);
} }
LOG.debug("Loaded custom font from source <%s>.", source); LOG.debug("Loaded custom font from source <%s>.", source);
} catch( MalformedURLException muex ) {
LOG.warn("Could not find font resource for <%s>", source);
} catch( IOException ioex ) { } catch( IOException ioex ) {
LOG.error(ioex, "Error loading custom font file from source <%s>.", source); LOG.warn(ioex, "Error loading custom font file from source <%s>.", source);
} catch( FontFormatException ffex ) { } catch( FontFormatException ffex ) {
LOG.error(ffex, "Error creating custom font from source <%s>.", source); LOG.warn(ffex, "Error creating custom font from source <%s>.", source);
} }
return font; return font;

View File

@@ -16,6 +16,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.ref.SoftReference; import java.lang.ref.SoftReference;
import java.net.MalformedURLException;
/** /**
* Eine Hilfsklasse mit Klassenmethoden, um Bilder zu laden. * Eine Hilfsklasse mit Klassenmethoden, um Bilder zu laden.
@@ -67,8 +68,8 @@ public final class ImageLoader {
* @return * @return
*/ */
public static BufferedImage loadImage( String source, boolean caching ) { public static BufferedImage loadImage( String source, boolean caching ) {
Validator.requireNotNull(source, "Image source may not be null"); Validator.requireNotNull(source, "source");
Validator.requireNotEmpty(source, "Image source may not be empty."); Validator.requireNotEmpty(source, "source");
if( caching && imageCache.containsKey(source) ) { if( caching && imageCache.containsKey(source) ) {
return imageCache.get(source); return imageCache.get(source);
@@ -84,8 +85,10 @@ public final class ImageLoader {
if( caching && img != null ) { if( caching && img != null ) {
imageCache.put(source, img); imageCache.put(source, img);
} }
} catch( MalformedURLException muex ) {
LOG.warn("Could not find image resource for <%s>", source);
} catch( IOException ioex ) { } catch( IOException ioex ) {
LOG.error(ioex, "Error loading image file from source <%s>.", source); LOG.warn(ioex, "Error loading image file from source <%s>.", source);
} }
return img; return img;
} }
@@ -318,12 +321,8 @@ public final class ImageLoader {
* @throws IOException Falls es einen Fehler beim Speichern gab. * @throws IOException Falls es einen Fehler beim Speichern gab.
*/ */
public static void saveImage( BufferedImage image, File file, boolean overwriteIfExists ) throws IOException { public static void saveImage( BufferedImage image, File file, boolean overwriteIfExists ) throws IOException {
if( image == null ) { Validator.requireNotNull(image, "image");
throw new NullPointerException("Image may not be <null>."); Validator.requireNotNull(file, "file");
}
if( file == null ) {
throw new NullPointerException("File may not be <null>.");
}
if( file.isFile() ) { if( file.isFile() ) {
// Datei existiert schon // Datei existiert schon

View File

@@ -47,8 +47,8 @@ public class ResourceStreamProvider {
* einer bestehenden Ressource. * einer bestehenden Ressource.
*/ */
public static URL getResourceURL( String source ) throws NullPointerException, IllegalArgumentException, IOException { public static URL getResourceURL( String source ) throws NullPointerException, IllegalArgumentException, IOException {
Validator.requireNotNull(source, "Resource source may not be null"); Validator.requireNotNull(source, "source");
Validator.requireNotEmpty(source, "Resource source may not be empty."); Validator.requireNotEmpty(source, "source");
// Ist source ein valider Dateipfad? // Ist source ein valider Dateipfad?
File file = new File(source); File file = new File(source);