mapjfx-1.2.1 released with mapjfx-demo-1.2.1

I released version 1.2.1 of the mapjfx project to maven central. It can be found at

  <dependency>
    <groupId>com.sothawo</groupId>
    <artifactId>mapjfx</artifactId>
    <version>1.2.1</version>
  </dependency>

The source is available at GitHub.

The demo program that showcases the possibilities is available at GitHub as well.

Changes since 1.1.1:

  • set the map’s extent, so that a collection of coordinates is visible
  • API modifications for fluent interface
  • possibility to switch between map types
  • added MapType enum and property

Comments and contributions are welcome!

mapjfx-1.1.1 released

I released version 1.1.1 of the mapjfx project to maven central. It can be found at

  <dependency>
    <groupId>com.sothawo</groupId>
    <artifactId>mapjfx</artifactId>
    <version>1.1.1</version>
  </dependency>

The source is available at GitHub.

Changes since 1.1.0:

  • animation duration property type changed from double to int

Comments and contributions are welcome!

mapjfx-1.1.0 released

I released version 1.1.0 of the mapjfx project to maven central. It can be found at

  <dependency>
    <groupId>com.sothawo</groupId>
    <artifactId>mapjfx</artifactId>
    <version>1.1.0</version>
  </dependency>

The source is available at GitHub.

Changes since 1.0.2:

  • removed unnecessary code
  • reworked MapView constructor to enable SceneBuilder compatibility
  • removed slf4j-api dependency and switched to java logging to enable SceneBuilder compatibility

Comments and contributions are welcome!

load java logging properties from the classpath

When using plain Java logging the configuration file normally must be set by setting the System property java.util.logging.config.file. There also is the possibility to configure the logging system with a configuration class, but this article deals with file configuration.

Using the system property is quite uncomfortable as it involves changing run configurations in the IDE or typing more on the commandline when starting the program. Especially in maven powered builds, where I might wish to have different configurations for test and normal execution this is not an optimal solution.

So I was looking for a way to configure the logging system by using a logging.properties file which is searched in the classpath. The logging properties file I am going to use in this post is:

[raw] #
.level = WARNING
handlers = java.util.logging.ConsoleHandler

com.sothawo.level = ALL

java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.ConsoleHandler.level = ALL

# Timestamp Level Source log message backtrace
java.util.logging.SimpleFormatter.format = %1$tF %1$tT:%1$tL %1$tZ %4$s %2$s: %5$s %6$s%n
[/raw]

I want to log everything from my com.sothawo classes, but all other messages should be restricted to level WARNING. The first solution I came up with was:

// SAMPLE CODE! NOT WORKING AS EXPECTED!
package com.sothawo.mapjfx.demo;
public class DemoApp extends Application {
   private static final Logger logger = Logger.getLogger(DemoApp.class.getCanonicalName());

  public static void main(String[] args) {
    InputStream inputStream = DemoApp.class.getResourceAsStream("/logging.properties");
    if (null != inputStream) {
      try {
        LogManager.getLogManager().readConfiguration(inputStream);
      } catch (IOException e) {
        Logger.getGlobal().log(Level.SEVERE, "init logging system", e);
      }
    }
    logger.fine("fine test logging");
    }
  }
}

This did not work. Debugging through the code I found that the input stream was loaded and the LogManager was reconfigured, but my logger was still configured to INFO level, which is the default and therefore the fine message was not logged. I checked the Javadoc for LogManager.readConfiguration() and there it says: “Any log level definitions in the new configuration file will be applied using Logger.setLevel(), if the target Logger exists.“. So why was my logger not set to the correct level?

I dug into the code for LogManager and found that only the level of the loggers with names that are exactly the same as the names defined in the properties are set and not the the levels of loggers which have a configured logger in their parent chain. In my case: In the properties I have the line
[code] com.sothawo.level = ALL
[/code] This sets the level for a logger named com.sothawo but in my code the logger has the name com.sothawo.mapjfx.demo.DemoApp, and so it is not set. The LogManager does not consider the parental relationships when reading the configuration, this is only done when a logger is created.

So care has to be taken and the logger must be created after reading the configuration:

// WORKING CODE BUT UGLY
package com.sothawo.mapjfx.demo;
public class DemoApp extends Application {

  private static Logger logger; // NOT FINAL ANY MORE!

  public static void main(String[] args) {
    InputStream inputStream = DemoApp.class.getResourceAsStream("/logging.properties");
    if (null != inputStream) {
      try {
        LogManager.getLogManager().readConfiguration(inputStream);
      } catch (IOException e) {
        Logger.getGlobal().log(Level.SEVERE, "init logging system", e);
      }
    }
    logger = Logger.getLogger(DemoApp.class.getCanonicalName());
    logger.fine("fine test logging");
    }
  }
}

This I consider to be ugly code, as I like my loggers to be final, and it clutters up the main method.

So my final solution is to put the relevant code in a static initializer:

package com.sothawo.mapjfx.demo;
public class DemoApp extends Application {
  private static final Logger logger;

  static {
    InputStream inputStream = DemoApp.class.getResourceAsStream("/logging.properties");
    if (null != inputStream) {
    try {
      LogManager.getLogManager().readConfiguration(inputStream);
    } catch (IOException e) {
      Logger.getGlobal().log(Level.SEVERE, "init logging system", e);
    }
    logger = Logger.getLogger(DemoApp.class.getCanonicalName());
  }

  public static void main(String[] args) {
    logger.fine("fine test logging");
  }
}

mapfjx-1.0.0 released

I released version 1.0.0 of the mapjfx project to maven central. It can be found at

  <dependency>
    <groupId>com.sothawo</groupId>
    <artifactId>mapjfx</artifactId>
    <version>1.0.0</version>
  </dependency>

The source is available at GitHub.

The showcase program contained in the sources displays the possibilities:

  • Above the map are some buttons, the first three set the center of the map to a predefined value, the fourth sets the zoom value.
  • Next to the buttons is a slider for setting the zoom level. This slider is birectional bound to the zoom property of the map view, so that changes by the slider are shown in the map and changes by using the map controls move the slider
  • Below the map view is a status line that reflects the current value for center and zoom, these values are adjusted when the map changes either programmatically or by the user panning or doubleclicking the map or using the map controls.

mapjfx-1.0.0

 

Comments and contributions are welcome!