diff --git a/res/logging.properties b/res/logging.properties new file mode 100644 index 0000000..69c1c9a --- /dev/null +++ b/res/logging.properties @@ -0,0 +1,4 @@ +handlers=java.util.logging.ConsoleHandler +.level=WARNING +java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter +java.util.logging.SimpleFormatter.format=[%1$tF %1$tT][%4$s]%5$s %n \ No newline at end of file diff --git a/src/fr/klemek/marble/DefaultGenerator.java b/src/fr/klemek/marble/DefaultGenerator.java index 4e2d63c..45d7919 100644 --- a/src/fr/klemek/marble/DefaultGenerator.java +++ b/src/fr/klemek/marble/DefaultGenerator.java @@ -2,6 +2,7 @@ package fr.klemek.marble; import java.util.Random; import java.util.concurrent.ThreadLocalRandom; +import java.util.logging.Level; class DefaultGenerator extends Generator { @@ -38,14 +39,15 @@ class DefaultGenerator extends Generator { void generate() { if (seed == 0L) seed = ThreadLocalRandom.current().nextLong(); - System.out.println("\t\tseed : " + seed); - System.out.println("\t\tsize : " + size); - System.out.println("\t\tslope : " + slope); - System.out.println("\t\tdivergence : " + divergence + " = " + divergence.sum()); + Logger.log(Level.INFO, "Generating...."); + Logger.log(Level.INFO, "\tseed : {0}", seed); + Logger.log(Level.INFO, "\tsize : {0}", size); + Logger.log(Level.INFO, "\tslope : {0}", slope); + Logger.log(Level.INFO, "\tdivergence : {0} = {1}", divergence, divergence.sum()); rand = new Random(seed); table = new Color[width2][height2]; table[0][0] = source == null ? Color.random(rand) : source; - System.out.println("\t\tsource : " + source); + Logger.log(Level.INFO, "\tsource : {0}", source); for (int y = 0; y < height2; y++) generateLine(y); } diff --git a/src/fr/klemek/marble/Generator.java b/src/fr/klemek/marble/Generator.java index f7f8fe0..876826c 100644 --- a/src/fr/klemek/marble/Generator.java +++ b/src/fr/klemek/marble/Generator.java @@ -2,6 +2,7 @@ package fr.klemek.marble; import java.io.File; import java.util.Random; +import java.util.logging.Level; abstract class Generator { @@ -57,7 +58,7 @@ abstract class Generator { for (int x = 0; x < width2; x++) { for (int j = 0; j < Math.min(size, width - x * size); j++) { if (k >= data.length) { - System.err.println("\t\toverflow at x:" + x + " y:" + y + " j:" + j + " k:" + k); + Logger.log(Level.SEVERE, "Overflow at x:{0} y:{1} j:{2} k:{3}", x, y, k, j); return data; } data[k++] = table[x][y].r; diff --git a/src/fr/klemek/marble/ImageUtils.java b/src/fr/klemek/marble/ImageUtils.java index 0da91e3..07aa1f3 100644 --- a/src/fr/klemek/marble/ImageUtils.java +++ b/src/fr/klemek/marble/ImageUtils.java @@ -69,7 +69,7 @@ final class ImageUtils { fos.write(data); return true; } catch (IOException e) { - e.printStackTrace(); + Logger.logError(e); return false; } } @@ -80,7 +80,7 @@ final class ImageUtils { ImageIO.write(inputImage, "JPG", jpgFile); return true; } catch (IOException e) { - e.printStackTrace(); + Logger.logError(e); return false; } } diff --git a/src/fr/klemek/marble/LocalTests.java b/src/fr/klemek/marble/LocalTests.java index f3f31b4..9f3cbcc 100644 --- a/src/fr/klemek/marble/LocalTests.java +++ b/src/fr/klemek/marble/LocalTests.java @@ -5,6 +5,7 @@ import java.io.File; class LocalTests { public static void main(String[] args) { + Logger.init("logging.properties"); DefaultGenerator gen = new DefaultGenerator(800, 800, 2); gen.generate(); gen.saveBmp(new File("temp.bmp")); diff --git a/src/fr/klemek/marble/Logger.java b/src/fr/klemek/marble/Logger.java new file mode 100644 index 0000000..65b6fe1 --- /dev/null +++ b/src/fr/klemek/marble/Logger.java @@ -0,0 +1,113 @@ +package fr.klemek.marble; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Locale; +import java.util.logging.Level; +import java.util.logging.LogManager; + +/** + * Simple logger for this application + * + * @author Clement Gouin + */ +final class Logger { + + private static java.util.logging.Logger appLogger = java.util.logging.Logger.getLogger("VSquare"); + + private Logger() { + } + + /** + * Change the log level of this logger + * + * @param newLevel the level of log to show + */ + private static void setLevel(Level newLevel) { + appLogger.setLevel(newLevel); + } + + /** + * @return the current logger level; + */ + public static Level getLevel() { + return appLogger.getLevel(); + } + + /** + * Load a config file for the logger and set locale to english + * + * @param relativePath the path in resources of the config file + */ + public static void init(String relativePath) { + init(relativePath, Level.INFO); + } + + /** + * Load a config file for the logger and set locale to english + * + * @param relativePath the path in resources of the config file + * @param level the level to set the logger to + */ + private static void init(String relativePath, Level level) { + Locale.setDefault(Locale.ENGLISH); + loadConfigFromFile(relativePath); + Logger.setLevel(level); + } + + /** + * Load a config file for the logger + * + * @param relativePath the path in resources of the config file + */ + private static void loadConfigFromFile(String relativePath) { + try { + InputStream is = Logger.class.getClassLoader().getResourceAsStream(relativePath); + if (is == null) { + Logger.log(Level.SEVERE, "Logger config file not found at path {0}", relativePath); + return; + } + LogManager.getLogManager().readConfiguration(is); + appLogger = java.util.logging.Logger.getLogger("VSquare"); + } catch (IOException e) { + Logger.log(Level.SEVERE, e.toString(), e); + } + } + + /** + * Log a message + * + * @param lvl the level of logging + * @param message the message + * @param objects the object for the message formatting + */ + static void log(Level lvl, String message, Object... objects) { + Logger.log(Utils.getCallingClassName(3), lvl, message, objects); + } + + /** + * Log a message + * + * @param source the source class name + * @param lvl the level of logging + * @param message the message + * @param objects the object for the message formatting + */ + private static void log(String source, Level lvl, String message, Object... objects) { + message = String.format("[VSquare-%s] %s", source, message); + appLogger.log(lvl, message, objects); + if (lvl == Level.SEVERE && objects.length > 0 && objects[0] instanceof Exception) { + Exception e = (Exception) objects[0]; + for (StackTraceElement ste : e.getStackTrace()) + Logger.log(source, Level.SEVERE, "\t {0}", ste); + } + } + + static void logError(Exception ex) { + Logger.logError(Level.SEVERE, ex); + } + + private static void logError(Level lvl, Exception ex) { + Logger.log(lvl, ex.toString(), ex); + } +} diff --git a/src/fr/klemek/marble/MarbleViewer.java b/src/fr/klemek/marble/MarbleViewer.java index d03d6a1..ee41ddb 100644 --- a/src/fr/klemek/marble/MarbleViewer.java +++ b/src/fr/klemek/marble/MarbleViewer.java @@ -16,7 +16,7 @@ class MarbleViewer extends JFrame { private class Panel extends JPanel { - private transient final Generator generator; + private final transient Generator generator; Panel(Generator generator) { this.generator = generator; diff --git a/src/fr/klemek/marble/Utils.java b/src/fr/klemek/marble/Utils.java index 245ba08..3654c07 100644 --- a/src/fr/klemek/marble/Utils.java +++ b/src/fr/klemek/marble/Utils.java @@ -84,4 +84,16 @@ final class Utils { static int div(Random rand, byte src) { return Math.round(rand.nextFloat() * 2 * src - src); } + + /* + * Other utils + */ + + static String getCallingClassName(int stackLevel) { + StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); + if (stackLevel >= stackTrace.length) + return null; + String[] source = stackTrace[stackLevel].getClassName().split("\\."); + return source[source.length - 1]; + } } diff --git a/src/fr/klemek/marble/WallpaperGenerator.java b/src/fr/klemek/marble/WallpaperGenerator.java index 534513e..9232365 100644 --- a/src/fr/klemek/marble/WallpaperGenerator.java +++ b/src/fr/klemek/marble/WallpaperGenerator.java @@ -4,11 +4,14 @@ import java.awt.*; import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.util.logging.Level; class WallpaperGenerator { public static void main(String[] args) { + Logger.init("logging.properties"); + String file = "wallpaper"; Dimension screen = getScreenSizes(); int width = screen.width; @@ -41,7 +44,7 @@ class WallpaperGenerator { } private static void makeWallpaper(String name, int width, int height, int size) { - System.out.println("Making wallpaper '" + name + "' " + width + "x" + height + "px"); + Logger.log(Level.INFO, "Making wallpaper '{0}' {1}x{2}px", name, width, height); File bmpFile = new File(name + ".bmp"); File outputFile = new File(name + ".jpg"); @@ -50,30 +53,30 @@ class WallpaperGenerator { DefaultGenerator gen = size == 0 ? new DefaultGenerator(width, height) : new DefaultGenerator(width, height, size); long t1 = System.currentTimeMillis(); gen.generate(); - System.out.println("\tGeneration done in " + (System.currentTimeMillis() - t1) + " ms"); + Logger.log(Level.INFO, "\tGeneration done in {0} ms", (System.currentTimeMillis() - t1)); t1 = System.currentTimeMillis(); byte[] file = ImageUtils.generateBmpFile(width, gen.getData()); - System.out.println("\t\t" + file.length + " bytes"); - System.out.println("\tData writing done in " + (System.currentTimeMillis() - t1) + " ms"); + Logger.log(Level.INFO, "\t\tData : {0} bytes", file.length); + Logger.log(Level.INFO, "\tData writing done in {0} ms", (System.currentTimeMillis() - t1)); t1 = System.currentTimeMillis(); if (!ImageUtils.saveBmpFile(file, bmpFile)) return; - System.out.println("\tFile writing done in " + (System.currentTimeMillis() - t1) + " ms"); + Logger.log(Level.INFO, "\tFile '{0}' writing done in {1} ms", bmpFile, (System.currentTimeMillis() - t1)); t1 = System.currentTimeMillis(); if (!ImageUtils.convertBmpToJpg(bmpFile, outputFile)) return; - System.out.println("\tFile converting done in " + (System.currentTimeMillis() - t1) + " ms"); + Logger.log(Level.INFO, "\tFile '{0}' conversion to '{1}' done in {2} ms", bmpFile, outputFile, (System.currentTimeMillis() - t1)); try { Files.delete(bmpFile.toPath()); - System.out.println("\tFile '" + bmpFile.getName() + "' deleted"); + Logger.log(Level.INFO, "\tFile '{0}' deleted", bmpFile); } catch (IOException e) { - e.printStackTrace(); + Logger.logError(e); } - System.out.println("Wallpaper done in " + (System.currentTimeMillis() - t0) + " ms"); + Logger.log(Level.INFO, "Wallpaper done in {0} ms", (System.currentTimeMillis() - t0)); } }