diff --git a/.classpath b/.classpath
deleted file mode 100644
index 67de708..0000000
--- a/.classpath
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/.gitignore b/.gitignore
index 02b6b93..525bfcc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,3 +45,97 @@ target/
tmp/
img/
+### Gradle template
+.gradle
+/build/
+
+# Ignore Gradle GUI config
+gradle-app.setting
+
+# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
+!gradle-wrapper.jar
+
+# Cache of project
+.gradletasknamecache
+
+# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
+# gradle/wrapper/gradle-wrapper.properties
+### Java template
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+### JetBrains template
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/dictionaries
+.idea/**/shelf
+.idea/sonarlint/**
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# CMake
+cmake-build-debug/
+cmake-build-release/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
diff --git a/.project b/.project
deleted file mode 100644
index 13f3a24..0000000
--- a/.project
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
- OpenLogViewer
-
-
-
-
-
- org.eclipse.jdt.core.javabuilder
-
-
-
-
- org.maven.ide.eclipse.maven2Builder
-
-
-
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
-
-
- org.eclipse.m2e.core.maven2Nature
- org.maven.ide.eclipse.maven2Nature
- org.eclipse.jdt.core.javanature
-
-
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..6a0d67e
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,18 @@
+language: java
+jdk:
+- oraclejdk8
+- oraclejdk9
+- openjdk8
+
+cache:
+ directories:
+ - "${HOME}/.gradle"
+
+addons:
+ sonarcloud:
+ organization: "expeditioneer-github"
+ token:
+ secure: rOEze8AzsNOJ7eFZYOqSji3dXLiVvyTr4NsLCxNNWLtPf3wsnr25L/pzyTZtE01NWOg4njdV55FUJc9TrbMaxG7O2gntP4IAVjS7Co05jM9GF4YWtL5y5ZxxjCjae32aqagjMwyzR3YskSZ0QgG0HW+Sbvlnxc2adK3ORc9i8hOgjj4Z3jneAR1w2yCgqB3MMPvnJtDgLqJG6hixDTLi2SiKnp3dDrJ3nTuKXhasOqSOWskoetMh1W3PkQh4/A/B1e7lq+Dy9sW4KlvVaGnGpyY5u3yR6EEaC0mRXUi6BYJfvxpF1YB1Gl7K7Yy2u+9akPTOSPgyUXMRXfpMO9X0+JxrJ7e8Hs1C1CSIuSt5zo733B+2Ar6DtG1gH0a7gUwANUk1+S3GXOWMQ7ApwEtSgIu7P8JoBOnJ9CMhufQmchpiAvmF7iAqYV2YVhX0lnS8P7J4+qm2kIdfAsOaKWPrALroKP0paGpQaq4Z4nQtGWZ/2wuyIqhgRDk1FDRv9+S64/mEIolYme9XzchilhgDWvaQT1GVnw1pPZqIvSLsI43jihmgQVxfa5VcCRyAKxOMKmHyoqvWsDzg8h6DBOagHjxhvNXLI70p9vxkhdMM/qOqSx3k6L1gnZ8sAce5TyUpeqfh1vFj7H0SovFm5UPxztuC1JWd6V19JUXeqCQV55c=
+
+script:
+ - "./gradlew dependencyUpdates clean test shadow sonarqube"
diff --git a/Documentation/gpl.v3.full.txt b/LICENSE
similarity index 100%
rename from Documentation/gpl.v3.full.txt
rename to LICENSE
diff --git a/README.md b/README.md
index 57acc27..4b37bb3 100644
--- a/README.md
+++ b/README.md
@@ -1,109 +1,113 @@
-# OpenLogViewer
-
-OpenLogViewer, or OLV for short, is an open source project originally concieved
-by Bryan Harris. He says that he created it due to boredom, but that he intends
-for it to be reasonably easy to use. Ben Fenner, and to a lesser extent, Fred
-Cooke have done significant work to turn that dream into reality with UI and
-performance enhancements across the board.
-
-Gufi, as Bryan is known to his friends, would love for the program to become
-mainstream in the Automotive Datalog area as a tool. We feel that it's well on
-its way to doing just that.
-
-### Where do I get it?
-
-Download the latest release from the official [OLV website](http://olv.diyefi.org)
-or get the latest development version from the [build server!](http://builds.freeems.org)
-. Until 0.0.3 is released, the development version is a far better choice.
-
-### Prerequisites
-
-#### Running a precompiled version
-
-For using the precompiled application you only need a Java Runtime Environment
-(JRE) version 6 or above.
-
-#### Building the latest from source
-
-If you want to build the latest from source to make customisations, then you will
-need a Java Development Kit (JDK) version 6 or above AND maven 3. Maven 2 is
-not suitable as the project is configured for a number of plugins which are not
-compatible with maven 2. Additionally maven 2 does not provide the 100% stable
-build environment, which maven 3 does. Get maven from this link and follow the
-install instructions further down the page.
-
-http://maven.apache.org/download.html
-
-Additionally, you need to install the included settings.xml file in your ~/.m2
-directory. This allows your build to include artifacts that are only available
-from the DIYEFI.org Maven repository.
-
-You can get the source from one of the following repositories; use the network
-function to figure out whose is newest (though not necessarily best!):
-
-https://github.com/FreeEMS/OpenLogViewer - Tested commits
-https://github.com/fredcooke/OpenLogViewer - Latest from Fred
-https://github.com/BenFenner/OpenLogViewer - Latest from Ben
-
-A direct link to the network function:
-
-https://github.com/FreeEMS/OpenLogViewer/network
-
-Use git to obtain the source in an efficient way, for example:
-
-git clone git://github.com/FreeEMS/OpenLogViewer.git
-
-#### Using Ant
-
-Ant is deprecated in the professional development world, for good reasons, and
-as such is not supported as a build tool for this project.
-
-### Running OLV
-
-To run an OLV jar in a graphical desktop environment such as Microsoft Windows
-Gnome, KDE, or Mac OS X, simply double click the jar file. To run it from the
-command line use the following command:
-
-java -jar OLV.jar
-
-Where "OLV.jar" is replaced with the name of the file that you downloaded.
-
-If you're using Maven to build from source and run OLV, then the following
-simple command is all you need:
-
-mvn -DskipTests
-
-This does the same as "mvn install" and "mvn exec:exec" back to back. You may
-wish to clean the build directory before building and running, as you'd expect
-the required command is simply this:
-
-mvn clean
-
-Up to date documentation can be generated using maven in the following way:
-
-mvn site:site
-
-You can find the html index file in the target/site/ directory once complete.
-
-### OLV Website
-
-If you don't want to build the latest from source then you can pick up the last
-release from the extremely basic OLV website below. Automatically generated
-documentation is available from the same site.
-
-http://olv.diyefi.org
-
-### OLV Status
-
-Currently the application has an excellent mouse-based navigation UI. Adding
-and associating fields with traces is still sub-par, but should be fixed soon.
-
-The OLV development team are commited to regular releases of working software.
-This is the agile way, and as such have a clear roadmap for future releases.
-
-http://issues.freeems.org/roadmap_page.php?project_id=15
-
-Thanks for using this tool! We hope you love it as much as we do.
-
-The OLV Team.
-
+# OpenLogViewer
+
+[](https://travis-ci.org/expeditioneer/OpenLogViewer)
+[](https://sonarcloud.io/dashboard?id=org.diyefi.openlogviewer)
+[](https://sonarcloud.io/dashboard?id=org.diyefi.openlogviewer)
+[](https://sonarcloud.io/dashboard?id=org.diyefi.openlogviewer)
+
+OpenLogViewer, or OLV for short, is an open source project originally concieved
+by Bryan Harris. He says that he created it due to boredom, but that he intends
+for it to be reasonably easy to use. Ben Fenner, and to a lesser extent, Fred
+Cooke have done significant work to turn that dream into reality with UI and
+performance enhancements across the board.
+
+Gufi, as Bryan is known to his friends, would love for the program to become
+mainstream in the Automotive Datalog area as a tool. We feel that it's well on
+its way to doing just that.
+
+### Where do I get it?
+
+Download the latest release from the official [OLV website](http://olv.diyefi.org)
+or get the latest development version from the [build server!](http://builds.freeems.org)
+. Until 0.0.3 is released, the development version is a far better choice.
+
+### Prerequisites
+
+#### Running a precompiled version
+
+For using the precompiled application you only need a Java Runtime Environment (JRE) version 8 or above.
+
+#### Building the latest from source
+
+If you want to build the latest from source to make customisations, then you will
+need a Java Development Kit (JDK) version 6 or above AND maven 3. Maven 2 is
+not suitable as the project is configured for a number of plugins which are not
+compatible with maven 2. Additionally maven 2 does not provide the 100% stable
+build environment, which maven 3 does. Get maven from this link and follow the
+install instructions further down the page.
+
+http://maven.apache.org/download.html
+
+Additionally, you need to install the included settings.xml file in your ~/.m2
+directory. This allows your build to include artifacts that are only available
+from the DIYEFI.org Maven repository.
+
+You can get the source from one of the following repositories; use the network
+function to figure out whose is newest (though not necessarily best!):
+
+https://github.com/FreeEMS/OpenLogViewer - Tested commits
+https://github.com/fredcooke/OpenLogViewer - Latest from Fred
+https://github.com/BenFenner/OpenLogViewer - Latest from Ben
+
+A direct link to the network function:
+
+https://github.com/FreeEMS/OpenLogViewer/network
+
+Use git to obtain the source in an efficient way, for example:
+
+git clone git://github.com/FreeEMS/OpenLogViewer.git
+
+#### Using Ant
+
+Ant is deprecated in the professional development world, for good reasons, and
+as such is not supported as a build tool for this project.
+
+### Running OLV
+
+To run an OLV jar in a graphical desktop environment such as Microsoft Windows
+Gnome, KDE, or Mac OS X, simply double click the jar file. To run it from the
+command line use the following command:
+
+java -jar OLV.jar
+
+Where "OLV.jar" is replaced with the name of the file that you downloaded.
+
+If you're using Maven to build from source and run OLV, then the following
+simple command is all you need:
+
+mvn -DskipTests
+
+This does the same as "mvn install" and "mvn exec:exec" back to back. You may
+wish to clean the build directory before building and running, as you'd expect
+the required command is simply this:
+
+mvn clean
+
+Up to date documentation can be generated using maven in the following way:
+
+mvn site:site
+
+You can find the html index file in the target/site/ directory once complete.
+
+### OLV Website
+
+If you don't want to build the latest from source then you can pick up the last
+release from the extremely basic OLV website below. Automatically generated
+documentation is available from the same site.
+
+http://olv.diyefi.org
+
+### OLV Status
+
+Currently the application has an excellent mouse-based navigation UI. Adding
+and associating fields with traces is still sub-par, but should be fixed soon.
+
+The OLV development team are commited to regular releases of working software.
+This is the agile way, and as such have a clear roadmap for future releases.
+
+http://issues.freeems.org/roadmap_page.php?project_id=15
+
+Thanks for using this tool! We hope you love it as much as we do.
+
+The OLV Team.
+
diff --git a/RELEASE.md b/RELEASE.md
deleted file mode 100644
index 1d0fdc8..0000000
--- a/RELEASE.md
+++ /dev/null
@@ -1,52 +0,0 @@
-# Releases
-
-Releases are performed by one person with appropriate credentials to deploy the
-artifacts and upload the documentation. For a release to occur in Maven a number
-of things must be true.
-
- - The application builds without any errors
- - Repository clean - no uncommitted changes
- - Repository shared - no local changes unpushed
- - All unit tests pass
-
-Additionally the following conditions must be checked by the release manager.
-All of these are to be done after the last commit to be included in the release.
-If new commits go in to remedy issues that are found, all checks should be done
-again on the latest code base.
-
- - All issues with target == next version are not only resolved, but also closed
- - No known regressions from last release present in current build
- - No known regressions in features added since the last release
- - No inappropriate string literals shall be present in the code base
- - All localisation files complete and contain no English, except the English one
- - No commented out code shall be present in the code base
- - No SNAPSHOT versions shall be depended upon, including plugins
- - mvn site:site style counts are equal to, or better than the last release
- - findbugs shows no serious issues and equal to, or less than the last release
- - Test data-log files load correctly and display correctly for all decoders
- - mvn install on mac produces working bin.jar, linux.tar.bz2, .deb, .exe, .dmg
- - Windows exe executes and displays properly on XP and 7
- - Linux zip and deb function correctly and display properly on a variety of wms
- - Mac dmg and app.zip function correctly and display properly on 10.6 and 10.7
-
-Note, issues listed for future releases beyond the release in question can, and
-likely are present in the code that is about to be released. This is normal and
-completely OK.
-
-# Platform Check List
-
- - Full-screen entry/exit for each platform
- - Button behaviour for each platform
- - Key bindings for each platform
- - Settings file/dir behaviour on each platform
- - Panel sizes make sense and don't affect functionality
-
-# Post Release
-
- - Update all repos
- - Update the website
- - Update the issue tracker
- - Announce on forum and facebook
- - Tag SNAPSHOT version for git describe
- - git push --tags to all repos
-
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..1d5ab4c
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,75 @@
+plugins {
+ id 'com.github.johnrengelman.shadow' version '2.0.4'
+ id 'com.gorylenko.gradle-git-properties' version '1.5.1'
+ id 'org.sonarqube' version '2.6.2'
+ id 'com.github.ben-manes.versions' version '0.20.0'
+}
+
+apply plugin: 'java'
+apply plugin: 'jacoco'
+apply plugin: 'maven'
+apply plugin: 'com.github.johnrengelman.shadow'
+
+
+group = 'org.diyefi.openlogviewer'
+version = '0.0.3-SNAPSHOT'
+
+description = 'OpenLogViewer is a free, open source, cross-platform data-log visualisation application that currently supports many CSV data-log formats (including MegaSquirt style), and FreeEMS binary data-logs. OpenLogViewer is currently in its infancy. While in the future it will be amazing, right now it has all of the basics that you need.'
+
+sourceCompatibility = 1.8
+targetCompatibility = 1.8
+
+tasks.withType(JavaCompile) {
+ options.encoding = 'UTF-8'
+}
+
+configurations.all {
+}
+
+processResources {
+ filesMatching('**/buildInfo.properties') {
+ expand(project.properties)
+ }
+}
+
+jar {
+ manifest {
+ attributes 'Main-Class': 'org.diyefi.openlogviewer.OpenLogViewer'
+ }
+}
+
+shadowJar {
+ dependencies {
+ exclude(dependency('com.yuvimasory:orange-extensions:1.3.0'))
+ }
+}
+
+repositories {
+ maven { url "http://repo.maven.apache.org/maven2" }
+}
+
+dependencies {
+ implementation 'org.apache.logging.log4j:log4j-api:2.11.0'
+ implementation 'org.apache.logging.log4j:log4j-core:2.11.0'
+ implementation 'org.apache.commons:commons-lang3:3.7'
+ implementation 'com.yuvimasory:orange-extensions:1.3.0'
+ testImplementation 'org.junit.jupiter:junit-jupiter-api:5.2.0'
+ testImplementation 'org.junit.jupiter:junit-jupiter-params:5.2.0'
+ testImplementation 'org.junit.platform:junit-platform-surefire-provider:1.2.0'
+ testImplementation 'org.mockito:mockito-core:2.19.0'
+ testImplementation 'org.mockito:mockito-junit-jupiter:2.19.0'
+ testImplementation 'org.assertj:assertj-core:3.10.0'
+ testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.1.1'
+}
+
+test {
+ useJUnitPlatform()
+}
+
+sonarqube {
+ properties {
+ property "sonar.projectName", "OpenLogViewer"
+ property "sonar.projectKey", "org.diyefi.openlogviewer"
+ }
+}
+
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..01b8bf6
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..3ec500c
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Jun 27 09:58:39 CEST 2018
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-all.zip
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..cccdd3d
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/pom.xml b/pom.xml
deleted file mode 100644
index 334c4d2..0000000
--- a/pom.xml
+++ /dev/null
@@ -1,398 +0,0 @@
-
- 4.0.0
-
- org.diyefi.openlogviewer
- OpenLogViewer
- jar
- 0.0.3-SNAPSHOT
-
- OpenLogViewer
- http://olv.diyefi.org
-
-
- DIYEFI.org
- http://www.diyefi.org
-
-
-
- OpenLogViewer is a free, open source, cross-platform data-log visualisation application that currently supports many CSV data-log formats (including MegaSquirt style), and FreeEMS binary data-logs. OpenLogViewer is currently in its infancy. While in the future it will be amazing, right now it has all of the basics that you need.
-
-
- MantisBT
- http://issues.freeems.org
-
-
-
- scm:git:git://github.com/FreeEMS/OpenLogViewer.git
- https://github.com/FreeEMS/OpenLogViewer
- scm:git:git@github.com:FreeEMS/OpenLogViewer.git
-
-
-
- http://mvn.diyefi.org/nexus/content/repositories/releases/org/diyefi/openlogviewer/OpenLogViewer/
-
- freeemsreleases
- http://mvn.diyefi.org/nexus/content/repositories/releases
-
-
- freeemssnapshots
- http://mvn.diyefi.org/nexus/content/repositories/snapshots
-
-
- olvsite
- OLV Website
- scp://raptor:443/home/olv/site/releases/${project.version}/
-
-
-
-
-
- GPL V3
- manual
- You're free to download and use OpenLogViewer for any purpose, including
- viewing MegaSquirt logs as a free alternative to MegaLogViewer (MLV)
-
-
-
-
-
- Gufi
- Bryan Harris
-
- Founder
- Hacker
-
-
-
- Fred
- Fred Cooke
-
- FreeEMS Plugin
- Quality Control
-
-
-
- BenFenner
- Ben Fenner
-
- User Interface
- Refactoring
-
-
-
-
-
-
- Preston Saunders
-
-
-
-
- 1.8
- -Xms128m
- -Xmx1024m
- UTF-8
- http://forum.diyefi.org/viewforum.php?f=32
- http://issues.freeems.org
-
-
-
-
-
- org.apache.maven.plugins
- maven-jxr-plugin
- 2.5
-
-
- org.apache.maven.plugins
- maven-project-info-reports-plugin
- 2.9
-
-
- org.apache.maven.plugins
- maven-checkstyle-plugin
- 2.17
-
- src/site/fredsChecks.xml
-
-
-
-
- checkstyle
-
-
-
-
-
- org.codehaus.mojo
- findbugs-maven-plugin
- 3.0.2
-
- Max
- Low
-
-
-
- org.codehaus.mojo
- jdepend-maven-plugin
- 2.0
-
-
- org.apache.maven.plugins
- maven-pmd-plugin
- 3.6
-
- 20
- 1.6
-
-
-
- /rulesets/java/basic.xml
- /rulesets/java/braces.xml
- /rulesets/java/clone.xml
- /rulesets/java/codesize.xml
-
- ${project.basedir}/src/site/pmd/rulesets/controversial.xml
- ${project.basedir}/src/site/pmd/rulesets/coupling.xml
- ${project.basedir}/src/site/pmd/rulesets/design.xml
-
- /rulesets/java/finalizers.xml
- /rulesets/java/imports.xml
-
- /rulesets/java/junit.xml
-
- /rulesets/java/optimizations.xml
- /rulesets/java/sunsecure.xml
- /rulesets/java/strictexception.xml
- /rulesets/java/strings.xml
- /rulesets/java/typeresolution.xml
-
- /rulesets/java/unusedcode.xml
-
-
-
-
- org.apache.maven.plugins
- maven-javadoc-plugin
- 2.10.4
-
-
- org.codehaus.mojo
- cobertura-maven-plugin
- 2.7
-
-
- org.codehaus.mojo
- javancss-maven-plugin
- 2.1
-
-
- org.apache.maven.plugins
- maven-surefire-report-plugin
- 2.19.1
-
-
-
-
-
- install exec:exec
-
-
- false
- src/main/resources
-
- **/*
-
-
-
- true
- src/main/resources/build/
- build
-
- buildInfo.xml
-
-
-
-
-
- pl.project13.maven
- git-commit-id-plugin
- 2.2.1
-
-
-
- revision
-
-
-
-
-
- false
- true
- 7
- -DEV
- false
-
-
-
-
- org.apache.maven.plugins
- maven-enforcer-plugin
- 1.4.1
-
-
- validate
- enforce-versions
-
- enforce
-
-
-
-
- [3.3.9,)
-
-
- [1.8,)
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.5.1
-
- ${java.version}
- ${java.version}
-
-
-
- org.codehaus.mojo
- exec-maven-plugin
- 1.5.0
-
-
-
- java
-
- ${project.initial.heap}
- ${project.maximum.heap}
-
- -jar
- ${project.basedir}/target/${project.artifactId}-${project.version}-bin.jar
-
-
-
-
- org.codehaus.mojo
- build-helper-maven-plugin
- 1.12
-
-
- maven-version
-
- maven-version
-
-
-
-
-
- org.apache.maven.plugins
- maven-assembly-plugin
- 2.6
-
-
- bin
- package
-
- single
-
-
-
- src/main/assembly/runnable.xml
-
-
-
- ${project.groupId}.${project.artifactId}
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-jar-plugin
- 3.0.2
-
-
-
- ${project.groupId}.${project.artifactId}
-
-
-
-
-
- org.apache.maven.plugins
- maven-site-plugin
- 3.5.1
-
- org.apache.maven.plugins
- maven-release-plugin
- 2.5.3
-
- @{project.version}
-
-
-
-
-
- org.apache.maven.wagon
- wagon-ssh
- 2.10
-
-
-
-
-
-
-
-
-
-
- junit
- junit
- 4.12
- test
-
-
-
-
- org.apache.commons
- commons-lang3
- 3.1
-
-
-
-
-
-
- com.apple.eawt
- ui
- 1.6.0_24
-
-
-
-
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..1c994d4
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'OpenLogViewer'
diff --git a/settings.xml b/settings.xml
deleted file mode 100644
index 2b17d09..0000000
--- a/settings.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
- diyefi.org
-
-
-
-
-
- diyefi.org
-
-
- maven.diyefi.org
- DIYEFI.org Maven Repo
-
- true
- always
- fail
-
-
- false
- never
- fail
-
- http://maven.diyefi.org/content/groups/DIYEFI.org/
- default
-
-
-
-
-
-
- central
-
- true
-
-
-
- central
-
- false
-
- Central CNAME Redirect
- http://repo1.maven.org/maven2
-
-
-
-
-
diff --git a/src/main/assembly/runnable.xml b/src/main/assembly/runnable.xml
deleted file mode 100644
index 6f589ec..0000000
--- a/src/main/assembly/runnable.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-
- bin
-
- jar
-
- false
-
-
- /
- true
- true
- runtime
-
-
- META-INF/MANIFEST.MF
-
-
-
- com.apple.eawt:ui
-
-
-
-
\ No newline at end of file
diff --git a/src/main/java/org/diyefi/openlogviewer/FileExtensions.java b/src/main/java/org/diyefi/openlogviewer/FileExtensions.java
index 042a241..da29a08 100644
--- a/src/main/java/org/diyefi/openlogviewer/FileExtensions.java
+++ b/src/main/java/org/diyefi/openlogviewer/FileExtensions.java
@@ -1,18 +1,38 @@
package org.diyefi.openlogviewer;
-public final class FileExtensions {
- public static final String STAR_DOT = "*.";
-
- public static final String LA = "la";
- public static final String BIN = "bin";
- public static final String CSV = "csv";
- public static final String LOG = "log";
- public static final String XLS = "xls";
- public static final String MSL = "msl";
-
- /**
- * Prevent instantiation.
- */
- private FileExtensions() {
- }
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+public enum FileExtensions {
+ STAR_DOT("*."),
+ LA("la"),
+ BIN("bin"),
+ CSV("csv"),
+ LOG("log"),
+ XLS("xls"),
+ MSL("msl");
+
+ private static final Map lookupByExtension = new HashMap<>();
+
+ static {
+ Arrays.stream(FileExtensions.values())
+ .forEach(fileExtension -> lookupByExtension.put(fileExtension.getExtension(), fileExtension));
+ }
+
+ private final String extension;
+
+ public static FileExtensions getByExtension(String extension) {
+ return Optional.ofNullable(lookupByExtension.get(extension))
+ .orElseThrow(() -> new IllegalArgumentException("Unsupported file extension '" + extension + "'"));
+ }
+
+ FileExtensions(String extension) {
+ this.extension = extension;
+ }
+
+ public String getExtension() {
+ return extension;
+ }
}
diff --git a/src/main/java/org/diyefi/openlogviewer/OpenLogViewer.java b/src/main/java/org/diyefi/openlogviewer/OpenLogViewer.java
index ae0887f..5082cbb 100644
--- a/src/main/java/org/diyefi/openlogviewer/OpenLogViewer.java
+++ b/src/main/java/org/diyefi/openlogviewer/OpenLogViewer.java
@@ -28,52 +28,12 @@
*/
package org.diyefi.openlogviewer;
-import java.awt.BorderLayout;
-import java.awt.Dimension;
-import java.awt.EventQueue;
-import java.awt.GraphicsDevice;
-import java.awt.GraphicsEnvironment;
-import java.awt.IllegalComponentStateException;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Toolkit;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.WindowEvent;
-import java.io.File;
-import java.io.IOException;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Locale;
-import java.util.Properties;
-import java.util.ResourceBundle;
-
-import javax.swing.AbstractAction;
-import javax.swing.Action;
-import javax.swing.JComponent;
-import javax.swing.JFileChooser;
-import javax.swing.JFrame;
-import javax.swing.JMenu;
-import javax.swing.JMenuBar;
-import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.KeyStroke;
-import javax.swing.UIManager;
-import javax.swing.UnsupportedLookAndFeelException;
-import javax.swing.filechooser.FileFilter;
-
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
import org.diyefi.openlogviewer.decoder.AbstractDecoder;
import org.diyefi.openlogviewer.decoder.CSVTypeLog;
import org.diyefi.openlogviewer.decoder.FreeEMSBin;
-import org.diyefi.openlogviewer.filefilters.CSVFileFilter;
-import org.diyefi.openlogviewer.filefilters.FreeEMSBinFileFilter;
-import org.diyefi.openlogviewer.filefilters.FreeEMSLAFileFilter;
-import org.diyefi.openlogviewer.filefilters.LogFileFilter;
-import org.diyefi.openlogviewer.filefilters.MSTypeFileFilter;
-import org.diyefi.openlogviewer.filefilters.FreeEMSFileFilter;
+import org.diyefi.openlogviewer.filefilters.*;
import org.diyefi.openlogviewer.genericlog.GenericLog;
import org.diyefi.openlogviewer.graphing.EntireGraphingPanel;
import org.diyefi.openlogviewer.graphing.MultiGraphLayeredPane;
@@ -84,651 +44,625 @@
import org.diyefi.openlogviewer.subframes.MacOSAboutHandler;
import org.diyefi.openlogviewer.utils.Utilities;
+import javax.swing.*;
+import javax.swing.filechooser.FileFilter;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.WindowEvent;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.*;
+import java.util.List;
+
public final class OpenLogViewer extends JFrame {
- public static final String NEWLINE = System.getProperty(Keys.LINE_SEPARATOR);
-
- private static final long serialVersionUID = 1L;
-
- private static final Properties buildInfo = new Properties();
-
- private static final String APPLICATION_NAME = OpenLogViewer.class.getSimpleName();
- private static final String SETTINGS_DIRECTORY = "." + APPLICATION_NAME;
-
- private static final String GIT_DESCRIBE_KEY = "git.commit.id.describe";
-
- // TODO localise and refactor these:
- private static final String PROPERTIES_FILENAME = "OLVAllProperties.olv";
-
- private static final String NAME_OF_LAST_FILE_KEY = "lastFingFile";
- private static final String NAME_OF_LAST_DIR_KEY = "lastFingDir";
- private static final String NAME_OF_LAST_CHOOSER_CLASS = "chooserClass";
-
- // Real vars start here, many will probably get ripped out later
- private static final int GRAPH_PANEL_WIDTH = 600;
- private static final int GRAPH_PANEL_HEIGHT = 420;
-
- private static final String OS_NAME = System.getProperty(Keys.OS_NAME);
- private static final boolean IS_MAC_OS_X = OS_NAME.contains("OS X"); // TN2110
- private static final boolean IS_WINDOWS = OS_NAME.contains("Windows");
- private static final boolean IS_LINUX = OS_NAME.contains("Linux");
-
- private static OpenLogViewer mainAppRef;
- private static ResourceBundle labels;
-
- private final String applicationTitle;
- private final String applicationVersion;
- private final EntireGraphingPanel graphingPanel;
- private final FooterPanel footerPanel;
- private final OptionFrameV2 optionFrame;
- private final PropertiesPane prefFrame;
-
- private final List properties;
- private AbstractDecoder decoderInUse;
- private final JMenuBar menuBar;
- private boolean fullscreen;
-
- private int extendedState;
- private Point location;
- private Dimension size;
- private int containingDevice;
-
- public OpenLogViewer() {
- try {
- buildInfo.loadFromXML(getClass().getClassLoader().getResourceAsStream("build/buildInfo.xml"));
- } catch (IOException e) {
- System.out.println("Uh oh, looks like a hacked copy! UNSUPPORTED VERSION! DO NOT USE!");
- } finally {
- String preliminaryVersion = buildInfo.getProperty(GIT_DESCRIBE_KEY);
- if (preliminaryVersion == null || "".equals(preliminaryVersion.trim())) {
- System.out.println("Application version not found! UNSUPPORTED VERSION! DO NOT USE!");
- applicationVersion = "UNSUPPORTED VERSION! DO NOT USE!";
- buildInfo.setProperty(GIT_DESCRIBE_KEY, applicationVersion);
- } else {
- applicationVersion = buildInfo.getProperty(GIT_DESCRIBE_KEY);
- buildInfo.setProperty(GIT_DESCRIBE_KEY, applicationVersion);
- }
- }
-
- applicationTitle = APPLICATION_NAME + " " + applicationVersion;
- buildInfo.setProperty("application.title", applicationTitle);
-
- prefFrame = new PropertiesPane(labels, SETTINGS_DIRECTORY);
- properties = new ArrayList();
- prefFrame.setProperties(properties);
-
- footerPanel = new FooterPanel(labels);
- optionFrame = new OptionFrameV2(labels);
- graphingPanel = new EntireGraphingPanel(labels);
- graphingPanel.setPreferredSize(new Dimension(GRAPH_PANEL_WIDTH, GRAPH_PANEL_HEIGHT));
-
- setDefaultCloseOperation(EXIT_ON_CLOSE);
- setTitle(applicationTitle);
- setLayout(new BorderLayout());
- setFocusable(true);
-
- final JPanel mainPanel = new JPanel();
- mainPanel.setLayout(new BorderLayout());
- mainPanel.add(graphingPanel, BorderLayout.CENTER);
- mainPanel.add(footerPanel, BorderLayout.SOUTH);
- add(mainPanel, BorderLayout.CENTER);
-
- final JMenuItem openFileMenuItem = new JMenuItem(labels.getString(Text.FILE_MENU_ITEM_OPEN_NAME));
- openFileMenuItem.setName(Text.FILE_MENU_ITEM_OPEN_NAME);
- openFileMenuItem.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(final ActionEvent e) {
- openChosenFile();
- }
- });
-
- final JMenuItem reloadFileMenuItem = new JMenuItem(labels.getString(Text.FILE_MENU_ITEM_RELOAD_NAME));
- reloadFileMenuItem.setName(Text.FILE_MENU_ITEM_RELOAD_NAME);
- reloadFileMenuItem.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(final ActionEvent e) {
- openLastFile();
- }
- });
-
- final JMenuItem quitFileMenuItem = new JMenuItem(labels.getString(Text.FILE_MENU_ITEM_QUIT_NAME));
- quitFileMenuItem.setName(Text.FILE_MENU_ITEM_QUIT_NAME);
- quitFileMenuItem.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(final ActionEvent e) {
- OpenLogViewer.getInstance().quit();
- }
- });
-
- final JMenuItem fullScreenViewMenuItem = new JMenuItem(labels.getString(Text.VIEW_MENU_ITEM_FULL_SCREEN_NAME));
- fullScreenViewMenuItem.setName(Text.VIEW_MENU_ITEM_FULL_SCREEN_NAME);
- fullScreenViewMenuItem.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(final ActionEvent e) {
- enterFullScreen();
- }
- });
-
- final JMenuItem scaleAndColorViewMenuItem = new JMenuItem(labels.getString(Text.VIEW_MENU_ITEM_SCALE_AND_COLOR_NAME));
- scaleAndColorViewMenuItem.setName(Text.VIEW_MENU_ITEM_SCALE_AND_COLOR_NAME);
- scaleAndColorViewMenuItem.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(final ActionEvent e) {
- prefFrame.setVisible(true);
- }
- });
-
- final JMenuItem fieldsAndDivisionsViewMenuItem = new JMenuItem(labels.getString(Text.VIEW_MENU_ITEM_FIELDS_AND_DIVISIONS_NAME));
- fieldsAndDivisionsViewMenuItem.setName(Text.VIEW_MENU_ITEM_FIELDS_AND_DIVISIONS_NAME);
- fieldsAndDivisionsViewMenuItem.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(final ActionEvent e) {
- optionFrame.setVisible(true);
- }
- });
-
- final JMenuItem aboutMenuItem = new JMenuItem(labels.getString(Text.HELP_MENU_ITEM_ABOUT_NAME));
- aboutMenuItem.setName(Text.HELP_MENU_ITEM_ABOUT_NAME);
- aboutMenuItem.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(final ActionEvent e) {
- AboutFrame.show(buildInfo);
- }
- });
-
- /*
- * 13 January 2012 Had Chick-fil-A #1 meal with no pickle and Dr Pepper for lunch.
- * Dr Pepper with no period. "Dude didn't even get his degree." Either that or he is British.
- * 1 November 2011 Migrated Gufi's menu from the pointless class it's in to here.
- * 22 October 2011 Left Gufi's menu in place for future dev's enjoyment.
- *
- * 5 February 2011 meal for the night DO NOT EDIT MENU!
- * Sesame chicken alacarte
- * chicken lo mein alacarte
- * orange chicken x2
- */
-
- final JMenu fileMenu = new JMenu(labels.getString(Text.FILE_MENU_NAME));
- fileMenu.setName(Text.FILE_MENU_NAME);
- fileMenu.add(openFileMenuItem);
- fileMenu.add(reloadFileMenuItem);
- if (!IS_MAC_OS_X) {
- fileMenu.add(quitFileMenuItem);
- }
-
- final JMenu viewMenu = new JMenu(labels.getString(Text.VIEW_MENU_NAME));
- viewMenu.setName(Text.VIEW_MENU_NAME);
- viewMenu.add(fullScreenViewMenuItem);
- viewMenu.add(scaleAndColorViewMenuItem);
- viewMenu.add(fieldsAndDivisionsViewMenuItem);
-
- final JMenu helpMenu = new JMenu(labels.getString(Text.HELP_MENU_NAME));
- helpMenu.setName(Text.HELP_MENU_NAME);
- helpMenu.add(aboutMenuItem);
-
- menuBar = new JMenuBar();
- menuBar.add(fileMenu);
- menuBar.add(viewMenu);
- if (IS_MAC_OS_X) {
- new MacOSAboutHandler(buildInfo);
- } else {
- menuBar.add(helpMenu);
- }
- setJMenuBar(menuBar);
-
- //Listener stuff
- addComponentListener(graphingPanel);
- setupWindowKeyBindings(this);
-
- setName(applicationTitle);
-
- pack();
-
- setVisible(true);
- }
-
- /**
- * The entry point of OLV!
- *
- * @param args the command line arguments
- */
- public static void main(final String[] args) {
- EventQueue.invokeLater(new Runnable() {
-
- @Override
- public void run() {
- final Locale currentLocale = Locale.getDefault();
-
- labels = ResourceBundle.getBundle(OpenLogViewer.class.getPackage().getName() + ".Labels", currentLocale);
-
- final String lookAndFeel;
- final String systemLookAndFeel = UIManager.getSystemLookAndFeelClassName();
- if (IS_MAC_OS_X) {
- System.setProperty(Keys.APPLE_LAF_USE_SCREEN_MENU_BAR, Boolean.TRUE.toString());
- }
- lookAndFeel = systemLookAndFeel;
-
- try {
- UIManager.setLookAndFeel(lookAndFeel);
- } catch (UnsupportedLookAndFeelException e) {
- e.printStackTrace();
- System.out.println(labels.getString(Text.LOOK_AND_FEEL_EXCEPTION_MESSAGE_ONE));
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- System.out.println(labels.getString(Text.LOOK_AND_FEEL_EXCEPTION_MESSAGE_TWO));
- } catch (InstantiationException e) {
- e.printStackTrace();
- System.out.println(labels.getString(Text.LOOK_AND_FEEL_EXCEPTION_MESSAGE_THREE));
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- System.out.println(labels.getString(Text.LOOK_AND_FEEL_EXCEPTION_MESSAGE_FOUR));
- }
-
- mainAppRef = new OpenLogViewer();
-
- if (args.length > 0) {
- final File toOpen = new File(args[0]).getAbsoluteFile();
- if (toOpen.exists() && toOpen.isFile()) {
- if (args.length > 1) {
- System.out.println(args.length + labels.getString(Text.TOO_MANY_ARGUMENTS) + args[0]);
- } else {
- System.out.println(labels.getString(Text.ATTEMPTING_TO_OPEN_FILE) + args[0]);
- }
- final FileFilter ms = new MSTypeFileFilter(labels);
- final FileFilter fe = new FreeEMSFileFilter(labels);
- if (fe.accept(toOpen) || ms.accept(toOpen)) {
- mainAppRef.openFile(toOpen, mainAppRef.generateChooser());
- } else {
- System.out.println(labels.getString(Text.FILE_TYPE_NOT_SUPPORTED) + args[0]);
- mainAppRef.quit();
- }
- } else {
- System.out.println(labels.getString(Text.FILE_ARGUMENT_NOT_GOOD) + args[0]);
- mainAppRef.quit();
- }
- }
- }
- });
- }
-
- public void quit() {
- final WindowEvent wev = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
- Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
- }
-
- public void openChosenFile() {
- final JFileChooser fileChooser = generateChooser();
- final int acceptValue = fileChooser.showOpenDialog(this);
- if (acceptValue == JFileChooser.APPROVE_OPTION) {
- final File fileToOpen = fileChooser.getSelectedFile();
- if (!openFile(fileToOpen, fileChooser)) {
- JOptionPane.showMessageDialog(mainAppRef, labels.getObject(Text.OPEN_FILE_ERROR_MESSAGE)
- + NEWLINE + fileToOpen.getAbsolutePath(),
- labels.getString(Text.OPEN_FILE_ERROR_TITLE),
- JOptionPane.ERROR_MESSAGE);
- }
- }
- }
-
- public void openLastFile() {
- final String lastFingFile = getApplicationWideProperty(NAME_OF_LAST_FILE_KEY);
- final String chooserClass = getApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS);
- if (chooserClass != null && lastFingFile != null) {
- final File fileToOpen = new File(lastFingFile);
- final JFileChooser fileChooser = generateChooser();
- if (!openFile(fileToOpen, fileChooser)) {
- JOptionPane.showMessageDialog(mainAppRef, labels.getObject(Text.OPEN_LAST_FILE_ERROR_MESSAGE)
- + NEWLINE + fileToOpen.getAbsolutePath(),
- labels.getString(Text.OPEN_LAST_FILE_ERROR_TITLE),
- JOptionPane.ERROR_MESSAGE);
- }
- } else {
- JOptionPane.showMessageDialog(mainAppRef, labels.getObject(Text.OPEN_LAST_FILE_MISSING_PROPERTY_MESSAGE),
- labels.getString(Text.OPEN_LAST_FILE_MISSING_PROPERTY_TITLE),
- JOptionPane.ERROR_MESSAGE);
- }
- }
-
- public boolean openFile(final File fileToOpen, final JFileChooser fileChooser) {
- if (fileToOpen.exists()) {
- if (decoderInUse != null) {
- // Clear out all references to data that we don't need and thereby ensure that we have lots of memory free for data we're about to gather!
- final GenericLog logInUse = decoderInUse.getDecodedLog();
- if (logInUse != null) {
- logInUse.clearOut(); // This is the wrong approach. The correct approach is to reuse the object, try that next...
- }
- decoderInUse = null;
- setLog(null);
- } // else haven't read in a log yet.
-
- setTitle(applicationTitle + " - " + fileToOpen.getName());
- saveApplicationWideProperty(NAME_OF_LAST_DIR_KEY, fileToOpen.getParent());
- saveApplicationWideProperty(NAME_OF_LAST_FILE_KEY, fileToOpen.getPath());
- saveApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS, fileChooser.getFileFilter().getClass().getCanonicalName());
-
- if (FileExtensions.BIN.equals(Utilities.getExtension(fileToOpen))
- || FileExtensions.LA.equals(Utilities.getExtension(fileToOpen))
- || (fileChooser.getFileFilter() instanceof FreeEMSFileFilter)) {
- decoderInUse = new FreeEMSBin(fileToOpen, labels);
- } else {
- decoderInUse = new CSVTypeLog(fileToOpen, labels);
- }
- return true;
- } else {
- setTitle(applicationTitle);
- return false;
- }
- }
-
- public JFileChooser generateChooser() {
- final JFileChooser fileChooser = new JFileChooser();
- final String lastFingFile = getApplicationWideProperty(NAME_OF_LAST_FILE_KEY);
-
- if (lastFingFile != null) {
- fileChooser.setSelectedFile(new File(lastFingFile));
- } else {
- final String lastFingDir = getApplicationWideProperty(NAME_OF_LAST_DIR_KEY);
- if (lastFingDir != null) {
- fileChooser.setCurrentDirectory(new File(lastFingDir));
- }
- }
-
- fileChooser.addChoosableFileFilter(new FreeEMSFileFilter(labels));
- fileChooser.addChoosableFileFilter(new FreeEMSBinFileFilter());
- fileChooser.addChoosableFileFilter(new FreeEMSLAFileFilter());
- fileChooser.addChoosableFileFilter(new CSVFileFilter());
- fileChooser.addChoosableFileFilter(new LogFileFilter());
- fileChooser.addChoosableFileFilter(new MSTypeFileFilter(labels));
-
- final String chooserClass = getApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS);
-
- if (chooserClass != null) {
- try {
- final FileFilter[] existingFilters = fileChooser.getChoosableFileFilters();
- boolean alreadyHasSavedFilter = false;
- for (int i = 0; i < existingFilters.length; i++) {
- final String thisFilter = existingFilters[i].getClass().getCanonicalName();
- if (thisFilter.equals(chooserClass)) {
- alreadyHasSavedFilter = true;
- fileChooser.setFileFilter(existingFilters[i]); // If set to a new instance the list will contain two!
- }
- }
-
- // If it's not one of ours, create a new one and set it, though that almost certainly means we'll throw an exception and clean up the prefs...
- if (!alreadyHasSavedFilter) {
- final FileFilter savedFilter = (FileFilter) Class.forName(chooserClass).newInstance();
- fileChooser.setFileFilter(savedFilter);
- }
- } catch (ClassNotFoundException c) {
- removeApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS);
- System.out.println(labels.getString(Text.CLASS_NOT_FOUND) + NAME_OF_LAST_CHOOSER_CLASS + labels.getString(Text.REMOVED_FROM_PROPS));
- } catch (InstantiationException i) {
- removeApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS);
- System.out.println(labels.getString(Text.COULD_NOT_INSTANTIATE_CLASS) + NAME_OF_LAST_CHOOSER_CLASS + labels.getString(Text.REMOVED_FROM_PROPS));
- } catch (IllegalAccessException l) {
- removeApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS);
- System.out.println(labels.getString(Text.COULD_NOT_ACCESS_CLASS) + NAME_OF_LAST_CHOOSER_CLASS + labels.getString(Text.REMOVED_FROM_PROPS));
- }
- }
- return fileChooser;
- }
-
- private String getApplicationWideProperty(final String key) {
- final Properties appWide = new Properties();
- openAppWideProps(appWide);
- return appWide.getProperty(key);
- }
-
- private void saveApplicationWideProperty(final String key, final String value) {
- FileOutputStream fos = null;
- try {
- final Properties appWide = new Properties();
- final File appWideFile = openAppWideProps(appWide);
- appWide.setProperty(key, value);
- fos = new FileOutputStream(appWideFile);
- appWide.store(fos, "saved");
- } catch (IOException e) {
- e.printStackTrace();
- throw new RuntimeException(labels.getString(Text.IO_ISSUE_SAVING_PROPERTY) + e.getMessage(), e);
- } finally {
- try {
- if (fos != null) {
- fos.close();
- }
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- }
- }
-
- private void removeApplicationWideProperty(final String key) {
- FileOutputStream fos = null;
- try {
- final Properties appWide = new Properties();
- final File appWideFile = openAppWideProps(appWide);
- appWide.remove(key);
- fos = new FileOutputStream(appWideFile);
- appWide.store(fos, "removed");
- } catch (IOException e) {
- e.printStackTrace();
- throw new RuntimeException(labels.getString(Text.IO_ISSUE_REMOVING_PROPERTY) + e.getMessage(), e);
- } finally {
- try {
- if (fos != null) {
- fos.close();
- }
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- }
- }
-
- private File openAppWideProps(final Properties appWide) {
- File appWideFile;
- appWideFile = new File(System.getProperty(Keys.USER_HOME));
-
- if (!appWideFile.exists() || !appWideFile.canRead() || !appWideFile.canWrite()) {
- System.out.println(labels.getString(Text.HOME_DIRECTORY_NOT_ACCESSIBLE));
- } else {
- appWideFile = new File(appWideFile, SETTINGS_DIRECTORY);
- }
-
- if (!appWideFile.exists()) {
- FileInputStream fis = null;
- try {
- if (appWideFile.mkdir()) {
- appWideFile = new File(appWideFile, PROPERTIES_FILENAME);
- if (appWideFile.createNewFile()) {
- fis = new FileInputStream(appWideFile);
- appWide.load(fis);
- }
- } else {
- throw new RuntimeException(labels.getString(Text.FAILED_TO_CREATE_DIRECTORY_MESSAGE));
- // This should be passed up to the GUI as a dialog that tells you it can't do what it has to be able to...
- }
- } catch (IOException e) {
- System.out.print(e.getMessage());
- } finally {
- try {
- if (fis != null) {
- fis.close();
- }
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- }
- } else {
- appWideFile = new File(appWideFile, PROPERTIES_FILENAME);
- FileInputStream fis = null;
- try {
- if (!appWideFile.createNewFile()) {
- fis = new FileInputStream(appWideFile);
- appWide.load(fis);
- }
- } catch (IOException ioe) {
- ioe.printStackTrace();
- } finally {
- try {
- if (fis != null) {
- fis.close();
- }
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- }
- }
- return appWideFile;
- }
-
- public static void setupWindowKeyBindings(final JFrame window) {
- final Action closeWindow = new AbstractAction() {
- private static final long serialVersionUID = 1L;
- public void actionPerformed(final ActionEvent e) {
- final WindowEvent wev = new WindowEvent(window, WindowEvent.WINDOW_CLOSING);
- Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
- }
- };
-
- boolean isMainApp = false;
- if (window instanceof OpenLogViewer) {
- isMainApp = true;
- }
-
- // Close any window
- if (IS_WINDOWS || IS_LINUX) {
- window.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(Keys.CONTROL_W), Keys.CLOSE_WINDOW);
- } else if (IS_MAC_OS_X) {
- window.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(Keys.COMMAND_W), Keys.CLOSE_WINDOW);
- }
-
- // Just close the main app window
- if (IS_LINUX && isMainApp) {
- window.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(Keys.CONTROL_Q), Keys.CLOSE_WINDOW);
- }
-
- window.getRootPane().getActionMap().put(Keys.CLOSE_WINDOW, closeWindow);
- }
-
- public void enterFullScreen() {
- if (!fullscreen) {
- final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
- final GraphicsDevice[] device = ge.getScreenDevices();
-
- for (int i = 0; i < device.length; i++) { // Cycle through available devices (monitors) looking for device that has center of app
- final Rectangle bounds = device[i].getDefaultConfiguration().getBounds();
- final int centerX = (int) Math.round(getBounds().getCenterX());
- final int centerY = (int) Math.round(getBounds().getCenterY());
- final Point center = new Point(centerX, centerY);
- if (bounds.contains(center)) { // Found the device (monitor) that contains the center of the app
- containingDevice = i;
- if (device[containingDevice].isFullScreenSupported()) {
- try {
- fullscreen = true; // Remember so that we can react accordingly.
- saveScreenState(); // Save the current state of things to restore later when exiting fullscreen mode.
- setVisible(false); // Hide how the sausage is made!
- setJMenuBar(null); // Remove the menu bar for maximum space, load files with the buttons?
- dispose(); // Make the JFrame undisplayable so setUndecorated(true) will work!
- setUndecorated(true); // Remove the window frame/bezel!
- setVisible(true); // Make the JFrame displayable again!
+ private static final long serialVersionUID = 1L;
+
+ private static final Logger LOG = LogManager.getLogger(OpenLogViewer.class);
+
+ public static final String NEWLINE = System.getProperty(Keys.LINE_SEPARATOR);
+
+ private static final Properties buildInfo = new Properties();
+
+ private static final String APPLICATION_NAME = OpenLogViewer.class.getSimpleName();
+ private static final String SETTINGS_DIRECTORY = "." + APPLICATION_NAME;
+
+ private static final String GIT_DESCRIBE_KEY = "git.commit.id.describe";
+
+ // TODO localise and refactor these:
+ private static final String PROPERTIES_FILENAME = "OLVAllProperties.olv";
+
+ private static final String NAME_OF_LAST_FILE_KEY = "lastFingFile";
+ private static final String NAME_OF_LAST_DIR_KEY = "lastFingDir";
+ private static final String NAME_OF_LAST_CHOOSER_CLASS = "chooserClass";
+
+ // Real vars start here, many will probably get ripped out later
+ private static final int GRAPH_PANEL_WIDTH = 600;
+ private static final int GRAPH_PANEL_HEIGHT = 420;
+
+ private static final String OS_NAME = System.getProperty(Keys.OS_NAME);
+ private static final boolean IS_MAC_OS_X = OS_NAME.contains("OS X"); // TN2110
+ private static final boolean IS_WINDOWS = OS_NAME.contains("Windows");
+ private static final boolean IS_LINUX = OS_NAME.contains("Linux");
+
+ private static OpenLogViewer mainAppRef;
+ private static ResourceBundle labels;
+
+ private final String applicationTitle;
+ private final String applicationVersion;
+ private final EntireGraphingPanel graphingPanel;
+ private final FooterPanel footerPanel;
+ private final OptionFrameV2 optionFrame;
+ private final PropertiesPane prefFrame;
+
+ private final List properties;
+ private final JMenuBar menuBar;
+ private AbstractDecoder decoderInUse;
+ private boolean fullscreen;
+
+ private int extendedState;
+ private Point location;
+ private Dimension size;
+ private int containingDevice;
+
+ public OpenLogViewer() {
+ try {
+ buildInfo.load(getClass().getClassLoader().getResourceAsStream("buildInfo.properties"));
+ buildInfo.load(getClass().getClassLoader().getResourceAsStream("git.properties"));
+ } catch (IOException e) {
+ LOG.error("Uh oh, looks like a hacked copy! UNSUPPORTED VERSION! DO NOT USE!");
+ } finally {
+ String preliminaryVersion = buildInfo.getProperty(GIT_DESCRIBE_KEY);
+ if (preliminaryVersion == null || "".equals(preliminaryVersion.trim())) {
+ LOG.error("Application version not found! UNSUPPORTED VERSION! DO NOT USE!");
+ applicationVersion = "UNSUPPORTED VERSION! DO NOT USE!";
+ buildInfo.setProperty(GIT_DESCRIBE_KEY, applicationVersion);
+ } else {
+ applicationVersion = buildInfo.getProperty(GIT_DESCRIBE_KEY);
+ buildInfo.setProperty(GIT_DESCRIBE_KEY, applicationVersion);
+ }
+ }
+
+ applicationTitle = APPLICATION_NAME + " " + applicationVersion;
+ buildInfo.setProperty("application.title", applicationTitle);
+
+ prefFrame = new PropertiesPane(labels, SETTINGS_DIRECTORY);
+ properties = new ArrayList<>();
+ prefFrame.setProperties(properties);
+
+ footerPanel = new FooterPanel(labels);
+ optionFrame = new OptionFrameV2(labels);
+ graphingPanel = new EntireGraphingPanel(labels);
+ graphingPanel.setPreferredSize(new Dimension(GRAPH_PANEL_WIDTH, GRAPH_PANEL_HEIGHT));
+
+ setDefaultCloseOperation(EXIT_ON_CLOSE);
+ setTitle(applicationTitle);
+ setLayout(new BorderLayout());
+ setFocusable(true);
+
+ final JPanel mainPanel = new JPanel();
+ mainPanel.setLayout(new BorderLayout());
+ mainPanel.add(graphingPanel, BorderLayout.CENTER);
+ mainPanel.add(footerPanel, BorderLayout.SOUTH);
+ add(mainPanel, BorderLayout.CENTER);
+
+ final JMenuItem openFileMenuItem = new JMenuItem(labels.getString(Text.FILE_MENU_ITEM_OPEN_NAME));
+ openFileMenuItem.setName(Text.FILE_MENU_ITEM_OPEN_NAME);
+ openFileMenuItem.addActionListener(e -> openChosenFile());
+
+ final JMenuItem reloadFileMenuItem = new JMenuItem(labels.getString(Text.FILE_MENU_ITEM_RELOAD_NAME));
+ reloadFileMenuItem.setName(Text.FILE_MENU_ITEM_RELOAD_NAME);
+ reloadFileMenuItem.addActionListener(e -> openLastFile());
+
+ final JMenuItem quitFileMenuItem = new JMenuItem(labels.getString(Text.FILE_MENU_ITEM_QUIT_NAME));
+ quitFileMenuItem.setName(Text.FILE_MENU_ITEM_QUIT_NAME);
+ quitFileMenuItem.addActionListener(e -> OpenLogViewer.getInstance().quit());
+
+ final JMenuItem fullScreenViewMenuItem = new JMenuItem(labels.getString(Text.VIEW_MENU_ITEM_FULL_SCREEN_NAME));
+ fullScreenViewMenuItem.setName(Text.VIEW_MENU_ITEM_FULL_SCREEN_NAME);
+ fullScreenViewMenuItem.addActionListener(e -> enterFullScreen());
+
+ final JMenuItem scaleAndColorViewMenuItem = new JMenuItem(labels.getString(Text.VIEW_MENU_ITEM_SCALE_AND_COLOR_NAME));
+ scaleAndColorViewMenuItem.setName(Text.VIEW_MENU_ITEM_SCALE_AND_COLOR_NAME);
+ scaleAndColorViewMenuItem.addActionListener(e -> prefFrame.setVisible(true));
+
+ final JMenuItem fieldsAndDivisionsViewMenuItem = new JMenuItem(labels.getString(Text.VIEW_MENU_ITEM_FIELDS_AND_DIVISIONS_NAME));
+ fieldsAndDivisionsViewMenuItem.setName(Text.VIEW_MENU_ITEM_FIELDS_AND_DIVISIONS_NAME);
+ fieldsAndDivisionsViewMenuItem.addActionListener(e -> optionFrame.setVisible(true));
+
+ final JMenuItem aboutMenuItem = new JMenuItem(labels.getString(Text.HELP_MENU_ITEM_ABOUT_NAME));
+ aboutMenuItem.setName(Text.HELP_MENU_ITEM_ABOUT_NAME);
+ aboutMenuItem.addActionListener(e -> AboutFrame.show(buildInfo));
+
+ /*
+ * 13 January 2012 Had Chick-fil-A #1 meal with no pickle and Dr Pepper for lunch.
+ * Dr Pepper with no period. "Dude didn't even get his degree." Either that or he is British.
+ * 1 November 2011 Migrated Gufi's menu from the pointless class it's in to here.
+ * 22 October 2011 Left Gufi's menu in place for future dev's enjoyment.
+ *
+ * 5 February 2011 meal for the night DO NOT EDIT MENU!
+ * Sesame chicken alacarte
+ * chicken lo mein alacarte
+ * orange chicken x2
+ */
+
+ final JMenu fileMenu = new JMenu(labels.getString(Text.FILE_MENU_NAME));
+ fileMenu.setName(Text.FILE_MENU_NAME);
+ fileMenu.add(openFileMenuItem);
+ fileMenu.add(reloadFileMenuItem);
+ if (!IS_MAC_OS_X) {
+ fileMenu.add(quitFileMenuItem);
+ }
+
+ final JMenu viewMenu = new JMenu(labels.getString(Text.VIEW_MENU_NAME));
+ viewMenu.setName(Text.VIEW_MENU_NAME);
+ viewMenu.add(fullScreenViewMenuItem);
+ viewMenu.add(scaleAndColorViewMenuItem);
+ viewMenu.add(fieldsAndDivisionsViewMenuItem);
+
+ final JMenu helpMenu = new JMenu(labels.getString(Text.HELP_MENU_NAME));
+ helpMenu.setName(Text.HELP_MENU_NAME);
+ helpMenu.add(aboutMenuItem);
+
+ menuBar = new JMenuBar();
+ menuBar.add(fileMenu);
+ menuBar.add(viewMenu);
+ if (IS_MAC_OS_X) {
+ new MacOSAboutHandler(buildInfo);
+ } else {
+ menuBar.add(helpMenu);
+ }
+ setJMenuBar(menuBar);
+
+ //Listener stuff
+ addComponentListener(graphingPanel);
+ setupWindowKeyBindings(this);
+
+ setName(applicationTitle);
+
+ pack();
+
+ setVisible(true);
+ }
+
+ /**
+ * The entry point of OLV!
+ *
+ * @param args the command line arguments
+ */
+ public static void main(final String[] args) {
+ EventQueue.invokeLater(() -> {
+ final Locale currentLocale = Locale.getDefault();
+
+ labels = ResourceBundle.getBundle(OpenLogViewer.class.getPackage().getName() + ".Labels", currentLocale);
+
+ final String lookAndFeel;
+ final String systemLookAndFeel = UIManager.getSystemLookAndFeelClassName();
+ if (IS_MAC_OS_X) {
+ System.setProperty(Keys.APPLE_LAF_USE_SCREEN_MENU_BAR, Boolean.TRUE.toString());
+ }
+ lookAndFeel = systemLookAndFeel;
+
+ try {
+ UIManager.setLookAndFeel(lookAndFeel);
+ } catch (UnsupportedLookAndFeelException e) {
+ LOG.error(labels.getString(Text.LOOK_AND_FEEL_EXCEPTION_MESSAGE_ONE), e);
+ } catch (ClassNotFoundException e) {
+ LOG.error(labels.getString(Text.LOOK_AND_FEEL_EXCEPTION_MESSAGE_TWO), e);
+ } catch (InstantiationException e) {
+ LOG.error(labels.getString(Text.LOOK_AND_FEEL_EXCEPTION_MESSAGE_THREE), e);
+ } catch (IllegalAccessException e) {
+ LOG.error(labels.getString(Text.LOOK_AND_FEEL_EXCEPTION_MESSAGE_FOUR), e);
+ }
+
+ mainAppRef = new OpenLogViewer();
+
+ if (args.length > 0) {
+ final File toOpen = new File(args[0]).getAbsoluteFile();
+ if (toOpen.exists() && toOpen.isFile()) {
+ if (args.length > 1) {
+ LOG.error(args.length + labels.getString(Text.TOO_MANY_ARGUMENTS) + args[0]);
+ } else {
+ LOG.error(labels.getString(Text.ATTEMPTING_TO_OPEN_FILE) + args[0]);
+ }
+ final FileFilter ms = new MSTypeFileFilter(labels);
+ final FileFilter fe = new FreeEMSFileFilter(labels);
+ if (fe.accept(toOpen) || ms.accept(toOpen)) {
+ mainAppRef.openFile(toOpen, mainAppRef.generateChooser());
+ } else {
+ LOG.error(labels.getString(Text.FILE_TYPE_NOT_SUPPORTED) + args[0]);
+ mainAppRef.quit();
+ }
+ } else {
+ LOG.error(labels.getString(Text.FILE_ARGUMENT_NOT_GOOD) + args[0]);
+ mainAppRef.quit();
+ }
+ }
+ });
+ }
+
+ public static void setupWindowKeyBindings(final JFrame window) {
+ final Action closeWindow = new AbstractAction() {
+ private static final long serialVersionUID = 1L;
+
+ public void actionPerformed(final ActionEvent e) {
+ final WindowEvent wev = new WindowEvent(window, WindowEvent.WINDOW_CLOSING);
+ Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
+ }
+ };
+
+ boolean isMainApp = false;
+ if (window instanceof OpenLogViewer) {
+ isMainApp = true;
+ }
+
+ // Close any window
+ if (IS_WINDOWS || IS_LINUX) {
+ window.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(Keys.CONTROL_W), Keys.CLOSE_WINDOW);
+ } else if (IS_MAC_OS_X) {
+ window.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(Keys.COMMAND_W), Keys.CLOSE_WINDOW);
+ }
+
+ // Just close the main app window
+ if (IS_LINUX && isMainApp) {
+ window.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(Keys.CONTROL_Q), Keys.CLOSE_WINDOW);
+ }
+
+ window.getRootPane().getActionMap().put(Keys.CLOSE_WINDOW, closeWindow);
+ }
+
+ /**
+ * Returns the reference to this instance, it is meant to be a method to make getting the main frame simpler
+ *
+ * @return this instance
+ */
+ public static OpenLogViewer getInstance() {
+ return mainAppRef;
+ }
+
+ public void quit() {
+ final WindowEvent wev = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
+ Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
+ }
+
+ public void openChosenFile() {
+ final JFileChooser fileChooser = generateChooser();
+ final int acceptValue = fileChooser.showOpenDialog(this);
+ if (acceptValue == JFileChooser.APPROVE_OPTION) {
+ final File fileToOpen = fileChooser.getSelectedFile();
+ if (!openFile(fileToOpen, fileChooser)) {
+ JOptionPane.showMessageDialog(mainAppRef, labels.getObject(Text.OPEN_FILE_ERROR_MESSAGE)
+ + NEWLINE + fileToOpen.getAbsolutePath(),
+ labels.getString(Text.OPEN_FILE_ERROR_TITLE),
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ }
+
+ public void openLastFile() {
+ final String lastFingFile = getApplicationWideProperty(NAME_OF_LAST_FILE_KEY);
+ final String chooserClass = getApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS);
+ if (chooserClass != null && lastFingFile != null) {
+ final File fileToOpen = new File(lastFingFile);
+ final JFileChooser fileChooser = generateChooser();
+ if (!openFile(fileToOpen, fileChooser)) {
+ JOptionPane.showMessageDialog(mainAppRef, labels.getObject(Text.OPEN_LAST_FILE_ERROR_MESSAGE)
+ + NEWLINE + fileToOpen.getAbsolutePath(),
+ labels.getString(Text.OPEN_LAST_FILE_ERROR_TITLE),
+ JOptionPane.ERROR_MESSAGE);
+ }
+ } else {
+ JOptionPane.showMessageDialog(mainAppRef, labels.getObject(Text.OPEN_LAST_FILE_MISSING_PROPERTY_MESSAGE),
+ labels.getString(Text.OPEN_LAST_FILE_MISSING_PROPERTY_TITLE),
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ public boolean openFile(final File fileToOpen, final JFileChooser fileChooser) {
+ if (fileToOpen.exists()) {
+ if (decoderInUse != null) {
+ // Clear out all references to data that we don't need and thereby ensure that we have lots of memory free for data we're about to gather!
+ final GenericLog logInUse = decoderInUse.getDecodedLog();
+ if (logInUse != null) {
+ logInUse.clearOut(); // This is the wrong approach. The correct approach is to reuse the object, try that next...
+ }
+ decoderInUse = null;
+ setLog(null);
+ } // else haven't read in a log yet.
+
+ setTitle(applicationTitle + " - " + fileToOpen.getName());
+ saveApplicationWideProperty(NAME_OF_LAST_DIR_KEY, fileToOpen.getParent());
+ saveApplicationWideProperty(NAME_OF_LAST_FILE_KEY, fileToOpen.getPath());
+ saveApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS, fileChooser.getFileFilter().getClass().getCanonicalName());
+
+ if (FileExtensions.BIN.equals(FileExtensions.getByExtension(Utilities.getExtension(fileToOpen)))
+ || FileExtensions.LA.equals(FileExtensions.getByExtension(Utilities.getExtension(fileToOpen)))
+ || (fileChooser.getFileFilter() instanceof FreeEMSFileFilter)) {
+ decoderInUse = new FreeEMSBin(fileToOpen, labels);
+ } else {
+ decoderInUse = new CSVTypeLog(fileToOpen, labels);
+ }
+ return true;
+ } else {
+ setTitle(applicationTitle);
+ return false;
+ }
+ }
+
+ public JFileChooser generateChooser() {
+ final JFileChooser fileChooser = new JFileChooser();
+ final String lastFingFile = getApplicationWideProperty(NAME_OF_LAST_FILE_KEY);
+
+ if (lastFingFile != null) {
+ fileChooser.setSelectedFile(new File(lastFingFile));
+ } else {
+ final String lastFingDir = getApplicationWideProperty(NAME_OF_LAST_DIR_KEY);
+ if (lastFingDir != null) {
+ fileChooser.setCurrentDirectory(new File(lastFingDir));
+ }
+ }
+
+ fileChooser.addChoosableFileFilter(new FreeEMSFileFilter(labels));
+ fileChooser.addChoosableFileFilter(new FreeEMSBinFileFilter());
+ fileChooser.addChoosableFileFilter(new FreeEMSLAFileFilter());
+ fileChooser.addChoosableFileFilter(new CSVFileFilter());
+ fileChooser.addChoosableFileFilter(new LogFileFilter());
+ fileChooser.addChoosableFileFilter(new MSTypeFileFilter(labels));
+
+ final String chooserClass = getApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS);
+
+ if (chooserClass != null) {
+ try {
+ final FileFilter[] existingFilters = fileChooser.getChoosableFileFilters();
+ boolean alreadyHasSavedFilter = false;
+ for (FileFilter existingFilter : existingFilters) {
+ final String thisFilter = existingFilter.getClass().getCanonicalName();
+ if (thisFilter.equals(chooserClass)) {
+ alreadyHasSavedFilter = true;
+ fileChooser.setFileFilter(existingFilter); // If set to a new instance the list will contain two!
+ }
+ }
+
+ // If it's not one of ours, create a new one and set it, though that almost certainly means we'll throw an exception and clean up the prefs...
+ if (!alreadyHasSavedFilter) {
+ final FileFilter savedFilter = (FileFilter) Class.forName(chooserClass).newInstance();
+ fileChooser.setFileFilter(savedFilter);
+ }
+ } catch (ClassNotFoundException c) {
+ removeApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS);
+ LOG.error(labels.getString(Text.CLASS_NOT_FOUND) + NAME_OF_LAST_CHOOSER_CLASS + labels.getString(Text.REMOVED_FROM_PROPS));
+ } catch (InstantiationException i) {
+ removeApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS);
+ LOG.error(labels.getString(Text.COULD_NOT_INSTANTIATE_CLASS) + NAME_OF_LAST_CHOOSER_CLASS + labels.getString(Text.REMOVED_FROM_PROPS));
+ } catch (IllegalAccessException l) {
+ removeApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS);
+ LOG.error(labels.getString(Text.COULD_NOT_ACCESS_CLASS) + NAME_OF_LAST_CHOOSER_CLASS + labels.getString(Text.REMOVED_FROM_PROPS));
+ }
+ }
+ return fileChooser;
+ }
+
+ private String getApplicationWideProperty(final String key) {
+ final Properties appWide = new Properties();
+ openAppWideProps(appWide);
+ return appWide.getProperty(key);
+ }
+
+ private void saveApplicationWideProperty(final String key, final String value) {
+ FileOutputStream fos = null;
+ try {
+ final Properties appWide = new Properties();
+ final File appWideFile = openAppWideProps(appWide);
+ appWide.setProperty(key, value);
+ fos = new FileOutputStream(appWideFile);
+ appWide.store(fos, "saved");
+ } catch (IOException e) {
+ LOG.error(e);
+ throw new RuntimeException(labels.getString(Text.IO_ISSUE_SAVING_PROPERTY) + e.getMessage(), e);
+ } finally {
+ try {
+ if (fos != null) {
+ fos.close();
+ }
+ } catch (IOException e) {
+ LOG.error(e);
+ }
+ }
+ }
+
+ private void removeApplicationWideProperty(final String key) {
+ FileOutputStream fos = null;
+ try {
+ final Properties appWide = new Properties();
+ final File appWideFile = openAppWideProps(appWide);
+ appWide.remove(key);
+ fos = new FileOutputStream(appWideFile);
+ appWide.store(fos, "removed");
+ } catch (IOException e) {
+ LOG.error(e);
+ throw new RuntimeException(labels.getString(Text.IO_ISSUE_REMOVING_PROPERTY) + e.getMessage(), e);
+ } finally {
+ try {
+ if (fos != null) {
+ fos.close();
+ }
+ } catch (IOException e) {
+ LOG.error(e);
+ }
+ }
+ }
+
+ private File openAppWideProps(final Properties appWide) {
+ File appWideFile;
+ appWideFile = new File(System.getProperty(Keys.USER_HOME));
+
+ if (!appWideFile.exists() || !appWideFile.canRead() || !appWideFile.canWrite()) {
+ LOG.error(labels.getString(Text.HOME_DIRECTORY_NOT_ACCESSIBLE));
+ } else {
+ appWideFile = new File(appWideFile, SETTINGS_DIRECTORY);
+ }
+
+ if (!appWideFile.exists()) {
+ FileInputStream fis = null;
+ try {
+ if (appWideFile.mkdir()) {
+ appWideFile = new File(appWideFile, PROPERTIES_FILENAME);
+ if (appWideFile.createNewFile()) {
+ fis = new FileInputStream(appWideFile);
+ appWide.load(fis);
+ }
+ } else {
+ throw new RuntimeException(labels.getString(Text.FAILED_TO_CREATE_DIRECTORY_MESSAGE));
+ // This should be passed up to the GUI as a dialog that tells you it can't do what it has to be able to...
+ }
+ } catch (IOException e) {
+ LOG.error(e);
+ } finally {
+ try {
+ if (fis != null) {
+ fis.close();
+ }
+ } catch (IOException e) {
+ LOG.error(e);
+ }
+ }
+ } else {
+ appWideFile = new File(appWideFile, PROPERTIES_FILENAME);
+ FileInputStream fis = null;
+ try {
+ if (!appWideFile.createNewFile()) {
+ fis = new FileInputStream(appWideFile);
+ appWide.load(fis);
+ }
+ } catch (IOException e) {
+ LOG.error(e);
+ } finally {
+ try {
+ if (fis != null) {
+ fis.close();
+ }
+ } catch (IOException e) {
+ LOG.error(e);
+ }
+ }
+ }
+ return appWideFile;
+ }
+
+ public void enterFullScreen() {
+ if (!fullscreen) {
+ final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ final GraphicsDevice[] device = ge.getScreenDevices();
+
+ for (int i = 0; i < device.length; i++) { // Cycle through available devices (monitors) looking for device that has center of app
+ final Rectangle bounds = device[i].getDefaultConfiguration().getBounds();
+ final int centerX = (int) Math.round(getBounds().getCenterX());
+ final int centerY = (int) Math.round(getBounds().getCenterY());
+ final Point center = new Point(centerX, centerY);
+ if (bounds.contains(center)) { // Found the device (monitor) that contains the center of the app
+ containingDevice = i;
+ if (device[containingDevice].isFullScreenSupported()) {
+ try {
+ fullscreen = true; // Remember so that we can react accordingly.
+ saveScreenState(); // Save the current state of things to restore later when exiting fullscreen mode.
+ setVisible(false); // Hide how the sausage is made!
+ setJMenuBar(null); // Remove the menu bar for maximum space, load files with the buttons?
+ dispose(); // Make the JFrame undisplayable so setUndecorated(true) will work!
+ setUndecorated(true); // Remove the window frame/bezel!
+ setVisible(true); // Make the JFrame displayable again!
// setResizable(false); // Fred: doesn't make sense and could be dangerous, according to oracle.
- // Ben: Removed setResizable(false) because it causes GNOME menu bar
- // and GNOME task bar to show in front of the app!
- device[containingDevice].setFullScreenWindow(this);
- validate(); // Required after rearranging component hierarchy
- toFront(); // Might as well
- requestFocusInWindow(); // Put keyboard focus here so toggling fullscreen works
- graphingPanel.moveGraphDueToResize(); // Done so centering still works on Mac
- } catch (IllegalComponentStateException e) {
- e.printStackTrace();
- System.out.println(labels.getString(Text.FAILED_TO_GO_FULLSCREEN_MESSAGE));
- fullscreen = false;
- }
- } else {
- System.out.println(labels.getString(Text.CANT_GO_FULLSCREEN_MESSAGE));
- }
- }
- }
- }
- }
-
- public void exitFullScreen() {
- if (fullscreen) {
- fullscreen = false;
- final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
- final GraphicsDevice[] device = ge.getScreenDevices();
- // Do the reverse of what we did to put it into full screen!
- device[containingDevice].setFullScreenWindow(null); // Exit full screen
- dispose(); // Make the JFrame undisplayable so setUndecorated(false) will work
- setUndecorated(false); // Restore the window frame/bezel
- setJMenuBar(menuBar); // Remove the menu bar
- validate(); // Required after rearranging component hierarchy
- restoreScreenState(); // Size and place the window where it was before
- setVisible(true); // Make the JFrame displayable again
- requestFocusInWindow(); // Put keyboard focus here so toggling fullscreen works
- graphingPanel.moveGraphDueToResize(); // Done so centering still works on Mac
- }
- }
-
- public void toggleFullScreen() {
- if (fullscreen) {
- exitFullScreen();
- } else {
- enterFullScreen();
- }
- }
-
- private void saveScreenState() {
- extendedState = getExtendedState();
- location = getLocation();
- size = getSize();
- }
-
- private void restoreScreenState() {
- setExtendedState(extendedState);
- setLocation(location);
- setSize(size);
- }
-
- public void setLog(final GenericLog genericLog) {
- graphingPanel.setLog(genericLog);
- }
-
- public void defaultBrowserNotFound() {
- final Object message = labels.getObject(Text.DEFAULT_BROWSER_ERROR_MESSAGE);
- final String title = labels.getString(Text.DEFAULT_BROWSER_ERROR_TITLE);
- JOptionPane.showMessageDialog(mainAppRef, message, title, JOptionPane.ERROR_MESSAGE); // DIRTY
- }
-
- // All of the references below are indicators of bad design, marking with DIRTY:
-
- /**
- * Returns the reference to this instance, it is meant to be a method to make getting the main frame simpler
- * @return this instance
- */
- public static OpenLogViewer getInstance() {
- return mainAppRef;
- }
-
- public NavBarPanel getNavBarPanel() {
- return footerPanel.getNavBarPanel();
- }
-
- public EntireGraphingPanel getEntireGraphingPanel() {
- return graphingPanel;
- }
-
- public MultiGraphLayeredPane getMultiGraphLayeredPane() {
- return graphingPanel.getMultiGraphLayeredPane();
- }
-
- public OptionFrameV2 getOptionFrame() {
- return optionFrame;
- }
-
- public PropertiesPane getPropertyPane() {
- return prefFrame;
- }
-
- public List getProperties() {
- return properties;
- }
+ // Ben: Removed setResizable(false) because it causes GNOME menu bar
+ // and GNOME task bar to show in front of the app!
+ device[containingDevice].setFullScreenWindow(this);
+ validate(); // Required after rearranging component hierarchy
+ toFront(); // Might as well
+ requestFocusInWindow(); // Put keyboard focus here so toggling fullscreen works
+ graphingPanel.moveGraphDueToResize(); // Done so centering still works on Mac
+ } catch (IllegalComponentStateException e) {
+ LOG.error(e);
+ LOG.error(labels.getString(Text.FAILED_TO_GO_FULLSCREEN_MESSAGE));
+ fullscreen = false;
+ }
+ } else {
+ LOG.error(labels.getString(Text.CANT_GO_FULLSCREEN_MESSAGE));
+ }
+ }
+ }
+ }
+ }
+
+ public void exitFullScreen() {
+ if (fullscreen) {
+ fullscreen = false;
+ final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ final GraphicsDevice[] device = ge.getScreenDevices();
+ // Do the reverse of what we did to put it into full screen!
+ device[containingDevice].setFullScreenWindow(null); // Exit full screen
+ dispose(); // Make the JFrame undisplayable so setUndecorated(false) will work
+ setUndecorated(false); // Restore the window frame/bezel
+ setJMenuBar(menuBar); // Remove the menu bar
+ validate(); // Required after rearranging component hierarchy
+ restoreScreenState(); // Size and place the window where it was before
+ setVisible(true); // Make the JFrame displayable again
+ requestFocusInWindow(); // Put keyboard focus here so toggling fullscreen works
+ graphingPanel.moveGraphDueToResize(); // Done so centering still works on Mac
+ }
+ }
+
+ public void toggleFullScreen() {
+ if (fullscreen) {
+ exitFullScreen();
+ } else {
+ enterFullScreen();
+ }
+ }
+
+ private void saveScreenState() {
+ extendedState = getExtendedState();
+ location = getLocation();
+ size = getSize();
+ }
+
+ private void restoreScreenState() {
+ setExtendedState(extendedState);
+ setLocation(location);
+ setSize(size);
+ }
+
+ public void setLog(final GenericLog genericLog) {
+ graphingPanel.setLog(genericLog);
+ }
+
+ // All of the references below are indicators of bad design, marking with DIRTY:
+
+ public void defaultBrowserNotFound() {
+ final Object message = labels.getObject(Text.DEFAULT_BROWSER_ERROR_MESSAGE);
+ final String title = labels.getString(Text.DEFAULT_BROWSER_ERROR_TITLE);
+ JOptionPane.showMessageDialog(mainAppRef, message, title, JOptionPane.ERROR_MESSAGE); // DIRTY
+ }
+
+ public NavBarPanel getNavBarPanel() {
+ return footerPanel.getNavBarPanel();
+ }
+
+ public EntireGraphingPanel getEntireGraphingPanel() {
+ return graphingPanel;
+ }
+
+ public MultiGraphLayeredPane getMultiGraphLayeredPane() {
+ return graphingPanel.getMultiGraphLayeredPane();
+ }
+
+ public OptionFrameV2 getOptionFrame() {
+ return optionFrame;
+ }
+
+ public PropertiesPane getPropertyPane() {
+ return prefFrame;
+ }
+
+ public List getProperties() {
+ return properties;
+ }
}
diff --git a/src/main/java/org/diyefi/openlogviewer/coloring/InitialLineColoring.java b/src/main/java/org/diyefi/openlogviewer/coloring/InitialLineColoring.java
index 6ab15c9..00a590b 100644
--- a/src/main/java/org/diyefi/openlogviewer/coloring/InitialLineColoring.java
+++ b/src/main/java/org/diyefi/openlogviewer/coloring/InitialLineColoring.java
@@ -30,6 +30,7 @@
/**
* InitialLineColoring is used to provide the coloring for the GenericDataElements.
* The colors provided should be the most contrasting colors possible.
+ *
* @author Ben Fenner
*/
public enum InitialLineColoring {
@@ -50,7 +51,7 @@ public enum InitialLineColoring {
private final Color bookEndRed = Color.getHSBColor(ALMOST_ONE, 1.0F, 1.0F);
private InitialLineColoring() {
- colorList = new LinkedList();
+ colorList = new LinkedList<>();
colorList.add(0, bookEndRed); // Seed with high value red
}
diff --git a/src/main/java/org/diyefi/openlogviewer/decoder/CSVTypeLog.java b/src/main/java/org/diyefi/openlogviewer/decoder/CSVTypeLog.java
index d21c598..c48e122 100644
--- a/src/main/java/org/diyefi/openlogviewer/decoder/CSVTypeLog.java
+++ b/src/main/java/org/diyefi/openlogviewer/decoder/CSVTypeLog.java
@@ -81,34 +81,35 @@ public final void run() {
* @throws IOException
*/
protected final void decodeLog() throws IOException {
- final Scanner scan = new Scanner(new BufferedReader(new FileReader(getLogFile())));
- final String delimiter = scanForDelimiter();
+ try (Scanner scan = new Scanner(new BufferedReader(new FileReader(getLogFile())))) {
+ final String delimiter = scanForDelimiter();
- String[] splitLine;
- String[] headers = new String[1];
+ String[] splitLine;
+ String[] headers = new String[1];
- int finalAndInitialLength = Utilities.countBytes(getLogFile(), (byte) '\n');
+ int finalAndInitialLength = Utilities.countBytes(getLogFile(), (byte) '\n');
- String line = "";
- boolean headerSet = false;
- while (scan.hasNextLine() && !headerSet) {
- line = scan.nextLine();
- splitLine = line.split(delimiter);
+ String line = "";
+ boolean headerSet = false;
+ while (scan.hasNextLine() && !headerSet) {
+ line = scan.nextLine();
+ splitLine = line.split(delimiter);
- if (splitLine.length == fieldCount) {
- headers = splitLine;
- this.setDecodedLog(new GenericLog(splitLine, finalAndInitialLength, LOAD_FACTOR, labels));
- headerSet = true;
+ if (splitLine.length == fieldCount) {
+ headers = splitLine;
+ this.setDecodedLog(new GenericLog(splitLine, finalAndInitialLength, LOAD_FACTOR, labels));
+ headerSet = true;
+ }
}
- }
- while (scan.hasNextLine()) {
- line = scan.nextLine();
- splitLine = line.split(delimiter);
- this.getDecodedLog().incrementPosition();
- if (splitLine.length == fieldCount) {
- for (int x = 0; x < splitLine.length; x++) {
- this.getDecodedLog().addValue(headers[x], Double.parseDouble(splitLine[x]));
+ while (scan.hasNextLine()) {
+ line = scan.nextLine();
+ splitLine = line.split(delimiter);
+ this.getDecodedLog().incrementPosition();
+ if (splitLine.length == fieldCount) {
+ for (int x = 0; x < splitLine.length; x++) {
+ this.getDecodedLog().addValue(headers[x], Double.parseDouble(splitLine[x]));
+ }
}
}
}
diff --git a/src/main/java/org/diyefi/openlogviewer/filefilters/CSVFileFilter.java b/src/main/java/org/diyefi/openlogviewer/filefilters/CSVFileFilter.java
index e83a030..9b2feef 100644
--- a/src/main/java/org/diyefi/openlogviewer/filefilters/CSVFileFilter.java
+++ b/src/main/java/org/diyefi/openlogviewer/filefilters/CSVFileFilter.java
@@ -22,26 +22,26 @@
*/
package org.diyefi.openlogviewer.filefilters;
-import java.io.File;
-import javax.swing.filechooser.FileFilter;
-
import org.diyefi.openlogviewer.FileExtensions;
import org.diyefi.openlogviewer.utils.Utilities;
+import javax.swing.filechooser.FileFilter;
+import java.io.File;
+
public class CSVFileFilter extends FileFilter {
- @Override
- public final String getDescription() {
- return FileExtensions.STAR_DOT + FileExtensions.CSV;
- }
+ @Override
+ public final String getDescription() {
+ return FileExtensions.STAR_DOT.getExtension() + FileExtensions.CSV.getExtension();
+ }
- @Override
- public final boolean accept(final File file) {
- if (file.isDirectory()) {
- return true;
- }
+ @Override
+ public final boolean accept(final File file) {
+ if (file.isDirectory()) {
+ return true;
+ }
- final String extension = Utilities.getExtension(file);
+ final String extension = Utilities.getExtension(file);
- return FileExtensions.CSV.equals(extension);
- }
+ return FileExtensions.CSV.equals(FileExtensions.getByExtension(extension));
+ }
}
diff --git a/src/main/java/org/diyefi/openlogviewer/filefilters/FreeEMSBinFileFilter.java b/src/main/java/org/diyefi/openlogviewer/filefilters/FreeEMSBinFileFilter.java
index f1a2a49..3bff6d8 100644
--- a/src/main/java/org/diyefi/openlogviewer/filefilters/FreeEMSBinFileFilter.java
+++ b/src/main/java/org/diyefi/openlogviewer/filefilters/FreeEMSBinFileFilter.java
@@ -23,26 +23,26 @@
package org.diyefi.openlogviewer.filefilters;
-import java.io.File;
-import javax.swing.filechooser.FileFilter;
-
import org.diyefi.openlogviewer.FileExtensions;
import org.diyefi.openlogviewer.utils.Utilities;
+import javax.swing.filechooser.FileFilter;
+import java.io.File;
+
public class FreeEMSBinFileFilter extends FileFilter {
- @Override
- public final String getDescription() {
- return FileExtensions.STAR_DOT + FileExtensions.BIN;
- }
+ @Override
+ public final String getDescription() {
+ return FileExtensions.STAR_DOT.getExtension() + FileExtensions.BIN.getExtension();
+ }
- @Override
- public final boolean accept(final File file) {
- if (file.isDirectory()) {
- return true;
- }
+ @Override
+ public final boolean accept(final File file) {
+ if (file.isDirectory()) {
+ return true;
+ }
- final String extension = Utilities.getExtension(file);
+ final String extension = Utilities.getExtension(file);
- return FileExtensions.BIN.equals(extension);
- }
+ return FileExtensions.BIN.equals(FileExtensions.getByExtension(extension));
+ }
}
diff --git a/src/main/java/org/diyefi/openlogviewer/filefilters/FreeEMSFileFilter.java b/src/main/java/org/diyefi/openlogviewer/filefilters/FreeEMSFileFilter.java
index fcfca3e..ad17632 100644
--- a/src/main/java/org/diyefi/openlogviewer/filefilters/FreeEMSFileFilter.java
+++ b/src/main/java/org/diyefi/openlogviewer/filefilters/FreeEMSFileFilter.java
@@ -52,9 +52,9 @@ public final boolean accept(final File file) {
final String extension = Utilities.getExtension(file);
- if (FileExtensions.BIN.equals(extension)) {
+ if (FileExtensions.BIN.equals(FileExtensions.getByExtension(extension))) {
return true;
- } else if (FileExtensions.LA.equals(extension)) {
+ } else if (FileExtensions.LA.equals(FileExtensions.getByExtension(extension))) {
return true;
}
diff --git a/src/main/java/org/diyefi/openlogviewer/filefilters/FreeEMSLAFileFilter.java b/src/main/java/org/diyefi/openlogviewer/filefilters/FreeEMSLAFileFilter.java
index 54ff3ff..4ffa796 100644
--- a/src/main/java/org/diyefi/openlogviewer/filefilters/FreeEMSLAFileFilter.java
+++ b/src/main/java/org/diyefi/openlogviewer/filefilters/FreeEMSLAFileFilter.java
@@ -23,26 +23,26 @@
package org.diyefi.openlogviewer.filefilters;
-import java.io.File;
-import javax.swing.filechooser.FileFilter;
-
import org.diyefi.openlogviewer.FileExtensions;
import org.diyefi.openlogviewer.utils.Utilities;
+import javax.swing.filechooser.FileFilter;
+import java.io.File;
+
public class FreeEMSLAFileFilter extends FileFilter {
- @Override
- public final String getDescription() {
- return FileExtensions.STAR_DOT + FileExtensions.LA;
- }
+ @Override
+ public final String getDescription() {
+ return FileExtensions.STAR_DOT.getExtension() + FileExtensions.LA.getExtension();
+ }
- @Override
- public final boolean accept(final File file) {
- if (file.isDirectory()) {
- return true;
- }
+ @Override
+ public final boolean accept(final File file) {
+ if (file.isDirectory()) {
+ return true;
+ }
- final String extension = Utilities.getExtension(file);
+ final String extension = Utilities.getExtension(file);
- return FileExtensions.LA.equals(extension);
- }
+ return FileExtensions.LA.equals(FileExtensions.getByExtension(extension));
+ }
}
diff --git a/src/main/java/org/diyefi/openlogviewer/filefilters/LogFileFilter.java b/src/main/java/org/diyefi/openlogviewer/filefilters/LogFileFilter.java
index bb5362a..20e5087 100644
--- a/src/main/java/org/diyefi/openlogviewer/filefilters/LogFileFilter.java
+++ b/src/main/java/org/diyefi/openlogviewer/filefilters/LogFileFilter.java
@@ -22,26 +22,26 @@
*/
package org.diyefi.openlogviewer.filefilters;
-import java.io.File;
-import javax.swing.filechooser.FileFilter;
-
import org.diyefi.openlogviewer.FileExtensions;
import org.diyefi.openlogviewer.utils.Utilities;
+import javax.swing.filechooser.FileFilter;
+import java.io.File;
+
public class LogFileFilter extends FileFilter {
- @Override
- public final String getDescription() {
- return FileExtensions.STAR_DOT + FileExtensions.LOG;
- }
+ @Override
+ public final String getDescription() {
+ return FileExtensions.STAR_DOT.getExtension() + FileExtensions.LOG.getExtension();
+ }
- @Override
- public final boolean accept(final File file) {
- if (file.isDirectory()) {
- return true;
- }
+ @Override
+ public final boolean accept(final File file) {
+ if (file.isDirectory()) {
+ return true;
+ }
- final String extension = Utilities.getExtension(file);
+ final String extension = Utilities.getExtension(file);
- return FileExtensions.LOG.equals(extension);
- }
+ return FileExtensions.LOG.getExtension().equals(extension);
+ }
}
diff --git a/src/main/java/org/diyefi/openlogviewer/filefilters/MSTypeFileFilter.java b/src/main/java/org/diyefi/openlogviewer/filefilters/MSTypeFileFilter.java
index 0995b26..415a927 100644
--- a/src/main/java/org/diyefi/openlogviewer/filefilters/MSTypeFileFilter.java
+++ b/src/main/java/org/diyefi/openlogviewer/filefilters/MSTypeFileFilter.java
@@ -53,11 +53,11 @@ public final boolean accept(final File file) {
if (FileExtensions.LOG.equals(extension)) {
return true;
- } else if (FileExtensions.CSV.equals(extension)) {
+ } else if (FileExtensions.CSV.equals(FileExtensions.getByExtension(extension))) {
return true;
- } else if (FileExtensions.XLS.equals(extension)) {
+ } else if (FileExtensions.XLS.equals(FileExtensions.getByExtension(extension))) {
return true;
- } else if (FileExtensions.MSL.equals(extension)) {
+ } else if (FileExtensions.MSL.equals(FileExtensions.getByExtension(extension))) {
return true;
}
diff --git a/src/main/java/org/diyefi/openlogviewer/genericlog/GenericDataElement.java b/src/main/java/org/diyefi/openlogviewer/genericlog/GenericDataElement.java
index 5ebd3f0..86e07e5 100644
--- a/src/main/java/org/diyefi/openlogviewer/genericlog/GenericDataElement.java
+++ b/src/main/java/org/diyefi/openlogviewer/genericlog/GenericDataElement.java
@@ -31,6 +31,8 @@
import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays;
+import java.util.Objects;
+import java.util.stream.IntStream;
import org.diyefi.openlogviewer.Keys;
import org.diyefi.openlogviewer.coloring.InitialLineColoring;
@@ -170,6 +172,20 @@ public int compareTo(final GenericDataElement otherGDE) {
return this.getName().compareToIgnoreCase(otherGDE.getName());
}
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ GenericDataElement that = (GenericDataElement) o;
+ return Objects.equals(name.toLowerCase(), that.name.toLowerCase());
+ }
+
+ @Override
+ public int hashCode() {
+
+ return Objects.hash(name.toLowerCase());
+ }
+
@Override
public Object getTransferData(final DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if (flavor.equals(dataFlavor[0])) {
@@ -190,12 +206,8 @@ public DataFlavor[] getTransferDataFlavors() {
@Override
public boolean isDataFlavorSupported(final DataFlavor flavor) {
- for (int i = 0; i < dataFlavor.length; i++) {
- if (flavor.equals(dataFlavor[i])) {
- return true;
- }
- }
- return false;
+ return IntStream.range(0, dataFlavor.length)
+ .anyMatch(i -> flavor.equals(dataFlavor[i]));
}
/**
diff --git a/src/main/java/org/diyefi/openlogviewer/graphing/GraphPositionPanel.java b/src/main/java/org/diyefi/openlogviewer/graphing/GraphPositionPanel.java
index 627f11f..b34cebe 100644
--- a/src/main/java/org/diyefi/openlogviewer/graphing/GraphPositionPanel.java
+++ b/src/main/java/org/diyefi/openlogviewer/graphing/GraphPositionPanel.java
@@ -179,7 +179,7 @@ private void paintPositionData(final Graphics2D g2d, final boolean zoomedOut) {
String positionDataString;
if (majorGraduationSpacing > TENTHS_DISPLAY_THRESHOLD) {
- final BigDecimal positionData = new BigDecimal(nextPositionMarker);
+ final BigDecimal positionData = BigDecimal.valueOf(nextPositionMarker);
positionDataString = positionData.toPlainString();
} else if (majorGraduationSpacing > HUNDRETHS_DISPLAY_THRESHOLD) {
positionDataString = MathUtils.roundDecimalPlaces(nextPositionMarker, 1);
diff --git a/src/main/java/org/diyefi/openlogviewer/graphing/InfoPanel.java b/src/main/java/org/diyefi/openlogviewer/graphing/InfoPanel.java
index 5d44f9f..8c335af 100644
--- a/src/main/java/org/diyefi/openlogviewer/graphing/InfoPanel.java
+++ b/src/main/java/org/diyefi/openlogviewer/graphing/InfoPanel.java
@@ -22,171 +22,169 @@
*/
package org.diyefi.openlogviewer.graphing;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.awt.event.MouseMotionListener;
-import java.util.ResourceBundle;
-
-import javax.swing.JPanel;
-
import org.diyefi.openlogviewer.OpenLogViewer;
import org.diyefi.openlogviewer.Text;
import org.diyefi.openlogviewer.genericlog.GenericLog;
import org.diyefi.openlogviewer.utils.MathUtils;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.util.ResourceBundle;
+
public class InfoPanel extends JPanel implements MouseMotionListener, MouseListener {
- private static final long serialVersionUID = 1L;
-
- private static final int LEFT_MARGIN_OFFSET = 10;
- private static final int ONE_TEXTUAL_HEIGHT = 20;
- private static final int FONT_SIZE = 12;
- private static final int INFO_DISPLAY_OFFSET = 4;
- private static final Font HOVER_FONT = new Font(Font.MONOSPACED, Font.PLAIN, FONT_SIZE);
-
- private final ResourceBundle labels;
- private final Color vertBar = new Color(255, 255, 255, 100);
- private final Color textBackground = new Color(0, 0, 0, 170);
-
- private GenericLog genLog;
- private int xMouseCoord;
- private int yMouseCoord;
- private boolean shouldDraw;
-
- public InfoPanel(final ResourceBundle labels) {
- this.labels = labels;
- setOpaque(false);
- }
-
- @Override
- public final void paintComponent(final Graphics g) {
- super.paintComponent(g);
-
- if (!this.getSize().equals(this.getParent().getSize())) {
- this.setSize(this.getParent().getSize());
- }
-
- g.setFont(HOVER_FONT); // Required to keep font consistent when using Mac L&F
- if (genLog == null) {
- g.setColor(Color.RED);
- g.drawString(labels.getString(Text.NO_LOG_LOADED), LEFT_MARGIN_OFFSET, ONE_TEXTUAL_HEIGHT);
- } else {
- if (genLog.getLogStatus() == GenericLog.LogState.LOG_LOADING) {
- g.setColor(Color.red);
- g.drawString(labels.getString(Text.LOADING_LOG), LEFT_MARGIN_OFFSET, ONE_TEXTUAL_HEIGHT);
- } else if (genLog.getLogStatus() == GenericLog.LogState.LOG_LOADED) {
- if (genLog.getLogStatusMessage() != null) {
- g.setColor(Color.RED);
- g.drawString(labels.getString(Text.DECODER_CRASHED_PART1), LEFT_MARGIN_OFFSET, ONE_TEXTUAL_HEIGHT);
- g.drawString(genLog.getLogStatusMessage(), LEFT_MARGIN_OFFSET, ONE_TEXTUAL_HEIGHT * 2);
- g.drawString(labels.getString(Text.DECODER_CRASHED_PART2), LEFT_MARGIN_OFFSET, ONE_TEXTUAL_HEIGHT * 3);
- }
- if (shouldDraw) {
- final int dataWidth = getWidestDataWidth();
- final Dimension d = this.getSize();
- final Graphics2D g2d = (Graphics2D) g;
- final FontMetrics fm = g.getFontMetrics(g.getFont()); // For getting string width
- final int fontHeight = fm.getHeight();
- final GraphPositionPanel graphPositionPanel = OpenLogViewer.getInstance().getEntireGraphingPanel().getGraphPositionPanel();
- final int zoom = OpenLogViewer.getInstance().getEntireGraphingPanel().getZoom();
- final boolean zoomedOut = OpenLogViewer.getInstance().getEntireGraphingPanel().isZoomedOutBeyondOneToOne();
- int snappedDataPosition = xMouseCoord;
- if (!zoomedOut && zoom > 1) {
- snappedDataPosition = graphPositionPanel.getBestSnappingPosition(xMouseCoord);
- }
- g2d.setColor(vertBar);
- g2d.drawLine(d.width / 2, 0, d.width / 2, d.height); // center position line
- g2d.drawLine(snappedDataPosition, 0, snappedDataPosition, d.height); // mouse cursor line
-
- final MultiGraphLayeredPane multigGraph = OpenLogViewer.getInstance().getMultiGraphLayeredPane();
- for (int i = 0; i < multigGraph.getComponentCount(); i++) {
- if (multigGraph.getComponent(i) instanceof SingleGraphPanel) {
- final SingleGraphPanel singleGraph = (SingleGraphPanel) multigGraph.getComponent(i);
- g2d.setColor(textBackground);
- String mouseData = singleGraph.getMouseInfo(snappedDataPosition, dataWidth);
- mouseData = mouseData + " " + singleGraph.getData().getName();
- final int stringWidth = fm.stringWidth(mouseData);
- g2d.fillRect(snappedDataPosition - 2 + INFO_DISPLAY_OFFSET,
- yMouseCoord + 2 + (fontHeight * i),
- stringWidth + 4,
- fontHeight);
- g2d.setColor(singleGraph.getColor());
- g2d.drawString(mouseData,
- snappedDataPosition + INFO_DISPLAY_OFFSET,
- yMouseCoord + fontHeight + (fontHeight * i));
- }
- }
- }
- }
- }
- }
-
- public final void setLog(final GenericLog log) {
- genLog = log;
- this.repaint();
- }
-
- private int getWidestDataWidth() {
- String widestDataToDisplay = "";
- final MultiGraphLayeredPane multigGraph = OpenLogViewer.getInstance().getMultiGraphLayeredPane();
- for (int i = 0; i < multigGraph.getComponentCount(); i++) {
- if (multigGraph.getComponent(i) instanceof SingleGraphPanel) {
- final SingleGraphPanel singleGraph = (SingleGraphPanel) multigGraph.getComponent(i);
- final String minValue = MathUtils.roundDecimalPlaces(singleGraph.getData().getMinValue(), SingleGraphPanel.DECIMAL_PLACES);
- final String maxValue = MathUtils.roundDecimalPlaces(singleGraph.getData().getMaxValue(), SingleGraphPanel.DECIMAL_PLACES);
- if (minValue.length() > widestDataToDisplay.length()) {
- widestDataToDisplay = minValue;
- }
- if (maxValue.length() > widestDataToDisplay.length()) {
- widestDataToDisplay = maxValue;
- }
- }
- }
- return widestDataToDisplay.length();
- }
-
- @Override
- public final void mouseEntered(final MouseEvent e) {
- shouldDraw = true;
- }
-
- @Override
- public final void mouseExited(final MouseEvent e) {
- if (!e.isShiftDown()) {
- // Old default behaviour
- shouldDraw = false;
- repaint();
- } // else leave coordinates alone
- }
-
- @Override
- public final void mouseMoved(final MouseEvent e) {
- if (!e.isShiftDown()) {
- xMouseCoord = e.getX();
- yMouseCoord = e.getY();
- repaint();
- } // else hold position
- }
-
- @Override
- public void mouseClicked(final MouseEvent e) {
- }
-
- @Override
- public void mousePressed(final MouseEvent e) {
- }
-
- @Override
- public void mouseReleased(final MouseEvent e) {
- }
-
- @Override
- public void mouseDragged(final MouseEvent e) {
-
- }
+ private static final long serialVersionUID = 1L;
+
+ private static final int LEFT_MARGIN_OFFSET = 10;
+ private static final int ONE_TEXTUAL_HEIGHT = 20;
+ private static final int FONT_SIZE = 12;
+ private static final int INFO_DISPLAY_OFFSET = 4;
+ private static final Font HOVER_FONT = new Font(Font.MONOSPACED, Font.PLAIN, FONT_SIZE);
+
+ private final ResourceBundle labels;
+ private final Color vertBar = new Color(255, 255, 255, 100);
+ private final Color textBackground = new Color(0, 0, 0, 170);
+
+ private GenericLog genLog;
+ private int xMouseCoord;
+ private int yMouseCoord;
+ private boolean shouldDraw;
+
+ public InfoPanel(final ResourceBundle labels) {
+ this.labels = labels;
+ setOpaque(false);
+ }
+
+ @Override
+ public final void paintComponent(final Graphics g) {
+ super.paintComponent(g);
+
+ if (!this.getSize().equals(this.getParent().getSize())) {
+ this.setSize(this.getParent().getSize());
+ }
+
+ g.setFont(HOVER_FONT); // Required to keep font consistent when using Mac L&F
+ if (genLog == null) {
+ g.setColor(Color.RED);
+ g.drawString(labels.getString(Text.NO_LOG_LOADED), LEFT_MARGIN_OFFSET, ONE_TEXTUAL_HEIGHT);
+ } else {
+ if (genLog.getLogStatus() == GenericLog.LogState.LOG_LOADING) {
+ g.setColor(Color.red);
+ g.drawString(labels.getString(Text.LOADING_LOG), LEFT_MARGIN_OFFSET, ONE_TEXTUAL_HEIGHT);
+ } else if (genLog.getLogStatus() == GenericLog.LogState.LOG_LOADED) {
+ if (genLog.getLogStatusMessage() != null) {
+ g.setColor(Color.RED);
+ g.drawString(labels.getString(Text.DECODER_CRASHED_PART1), LEFT_MARGIN_OFFSET, ONE_TEXTUAL_HEIGHT);
+ g.drawString(genLog.getLogStatusMessage(), LEFT_MARGIN_OFFSET, ONE_TEXTUAL_HEIGHT * 2);
+ g.drawString(labels.getString(Text.DECODER_CRASHED_PART2), LEFT_MARGIN_OFFSET, ONE_TEXTUAL_HEIGHT * 3);
+ }
+ if (shouldDraw) {
+ final int dataWidth = getWidestDataWidth();
+ final Dimension d = this.getSize();
+ final Graphics2D g2d = (Graphics2D) g;
+ final FontMetrics fm = g.getFontMetrics(g.getFont()); // For getting string width
+ final int fontHeight = fm.getHeight();
+ final GraphPositionPanel graphPositionPanel = OpenLogViewer.getInstance().getEntireGraphingPanel().getGraphPositionPanel();
+ final int zoom = OpenLogViewer.getInstance().getEntireGraphingPanel().getZoom();
+ final boolean zoomedOut = OpenLogViewer.getInstance().getEntireGraphingPanel().isZoomedOutBeyondOneToOne();
+ int snappedDataPosition = xMouseCoord;
+ if (!zoomedOut && zoom > 1) {
+ snappedDataPosition = graphPositionPanel.getBestSnappingPosition(xMouseCoord);
+ }
+ g2d.setColor(vertBar);
+ g2d.drawLine(d.width / 2, 0, d.width / 2, d.height); // center position line
+ g2d.drawLine(snappedDataPosition, 0, snappedDataPosition, d.height); // mouse cursor line
+
+ final MultiGraphLayeredPane multigGraph = OpenLogViewer.getInstance().getMultiGraphLayeredPane();
+ for (int i = 0; i < multigGraph.getComponentCount(); i++) {
+ if (multigGraph.getComponent(i) instanceof SingleGraphPanel) {
+ final SingleGraphPanel singleGraph = (SingleGraphPanel) multigGraph.getComponent(i);
+ g2d.setColor(textBackground);
+
+ String mouseData = singleGraph.getMouseInfo(snappedDataPosition, dataWidth) + " " + singleGraph.getData().getName();
+
+ final int stringWidth = fm.stringWidth(mouseData);
+ g2d.fillRect(snappedDataPosition - 2 + INFO_DISPLAY_OFFSET,
+ yMouseCoord + 2 + (fontHeight * i),
+ stringWidth + 4,
+ fontHeight);
+ g2d.setColor(singleGraph.getColor());
+ g2d.drawString(mouseData,
+ snappedDataPosition + INFO_DISPLAY_OFFSET,
+ yMouseCoord + fontHeight + (fontHeight * i));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public final void setLog(final GenericLog log) {
+ genLog = log;
+ this.repaint();
+ }
+
+ private int getWidestDataWidth() {
+ String widestDataToDisplay = "";
+ final MultiGraphLayeredPane multigGraph = OpenLogViewer.getInstance().getMultiGraphLayeredPane();
+ for (int i = 0; i < multigGraph.getComponentCount(); i++) {
+ if (multigGraph.getComponent(i) instanceof SingleGraphPanel) {
+ final SingleGraphPanel singleGraph = (SingleGraphPanel) multigGraph.getComponent(i);
+ final String minValue = MathUtils.roundDecimalPlaces(singleGraph.getData().getMinValue(), SingleGraphPanel.DECIMAL_PLACES);
+ final String maxValue = MathUtils.roundDecimalPlaces(singleGraph.getData().getMaxValue(), SingleGraphPanel.DECIMAL_PLACES);
+ if (minValue.length() > widestDataToDisplay.length()) {
+ widestDataToDisplay = minValue;
+ }
+ if (maxValue.length() > widestDataToDisplay.length()) {
+ widestDataToDisplay = maxValue;
+ }
+ }
+ }
+ return widestDataToDisplay.length();
+ }
+
+ @Override
+ public final void mouseEntered(final MouseEvent e) {
+ shouldDraw = true;
+ }
+
+ @Override
+ public final void mouseExited(final MouseEvent e) {
+ if (!e.isShiftDown()) {
+ // Old default behaviour
+ shouldDraw = false;
+ repaint();
+ } // else leave coordinates alone
+ }
+
+ @Override
+ public final void mouseMoved(final MouseEvent e) {
+ if (!e.isShiftDown()) {
+ xMouseCoord = e.getX();
+ yMouseCoord = e.getY();
+ repaint();
+ } // else hold position
+ }
+
+ @Override
+ public void mouseClicked(final MouseEvent e) {
+ // NO-OP
+ }
+
+ @Override
+ public void mousePressed(final MouseEvent e) {
+ // NO-OP
+ }
+
+ @Override
+ public void mouseReleased(final MouseEvent e) {
+ // NO-OP
+ }
+
+ @Override
+ public void mouseDragged(final MouseEvent e) {
+ // NO-OP
+ }
}
diff --git a/src/main/java/org/diyefi/openlogviewer/propertypanel/PropertiesPane.java b/src/main/java/org/diyefi/openlogviewer/propertypanel/PropertiesPane.java
index ba9cc37..0e79b99 100644
--- a/src/main/java/org/diyefi/openlogviewer/propertypanel/PropertiesPane.java
+++ b/src/main/java/org/diyefi/openlogviewer/propertypanel/PropertiesPane.java
@@ -208,25 +208,24 @@ public void actionPerformed(final ActionEvent e) {
private void loadProperties() {
try {
- final Scanner scan = new Scanner(new FileReader(OLVProperties));
-
- while (scan.hasNext()) {
- final String[] propLine = scan.nextLine().split("=");
- final SingleProperty sp = new SingleProperty();
- final String[] prop = propLine[1].split(",");
- sp.setHeader(propLine[0]);
- sp.setColor(new Color(
- Integer.parseInt(prop[0]),
- Integer.parseInt(prop[1]),
- Integer.parseInt(prop[2])));
- sp.setMin(Double.parseDouble(prop[3]));
- sp.setMax(Double.parseDouble(prop[4]));
- sp.setTrackIndex(Integer.parseInt(prop[5]));
- sp.setActive(Boolean.parseBoolean(prop[6]));
- addProperty(sp);
+ try (Scanner scan = new Scanner(new FileReader(OLVProperties))) {
+
+ while (scan.hasNext()) {
+ final String[] propLine = scan.nextLine().split("=");
+ final SingleProperty sp = new SingleProperty();
+ final String[] prop = propLine[1].split(",");
+ sp.setHeader(propLine[0]);
+ sp.setColor(new Color(
+ Integer.parseInt(prop[0]),
+ Integer.parseInt(prop[1]),
+ Integer.parseInt(prop[2])));
+ sp.setMin(Double.parseDouble(prop[3]));
+ sp.setMax(Double.parseDouble(prop[4]));
+ sp.setTrackIndex(Integer.parseInt(prop[5]));
+ sp.setActive(Boolean.parseBoolean(prop[6]));
+ addProperty(sp);
+ }
}
-
- scan.close();
} catch (FileNotFoundException fnf) {
System.out.print(fnf.toString());
throw new RuntimeException(fnf);
@@ -237,8 +236,10 @@ public final void save() {
try {
removeProperties.clear();
updateProperties();
- final FileWriter fstream = new FileWriter(OLVProperties);
- final BufferedWriter out = new BufferedWriter(fstream);
+ final BufferedWriter out;
+ try (FileWriter fstream = new FileWriter(OLVProperties)) {
+ out = new BufferedWriter(fstream);
+ }
for (int i = 0; i < properties.size(); i++) {
out.write(properties.get(i).toString());
diff --git a/src/main/java/org/diyefi/openlogviewer/subframes/AboutFrame.java b/src/main/java/org/diyefi/openlogviewer/subframes/AboutFrame.java
index 69be485..4348445 100644
--- a/src/main/java/org/diyefi/openlogviewer/subframes/AboutFrame.java
+++ b/src/main/java/org/diyefi/openlogviewer/subframes/AboutFrame.java
@@ -178,7 +178,7 @@ private JPanel createSouthPanel() {
final JPanel southPanel = new JPanel();
southPanel.setLayout(new BoxLayout(southPanel, BoxLayout.Y_AXIS));
- addTextToPanel(southPanel, "Built by " + buildInfo.getProperty("git.build.user.name") + " using Maven " + buildInfo.getProperty("maven.version") + LINK_CLOSE);
+ addTextToPanel(southPanel, "Built by " + buildInfo.getProperty("git.build.user.name") + " using Gradle " + buildInfo.getProperty("gradle.version") + LINK_CLOSE);
addTextToPanel(southPanel, "Built on " + buildInfo.getProperty("os.name") + " " + buildInfo.getProperty("os.arch") + " " + buildInfo.getProperty("os.version"));
addTextToPanel(southPanel, "Built using Java " + buildInfo.getProperty("java.version") + " on a " + buildInfo.getProperty("java.vm.version") + " VM");
addTextToPanel(southPanel, "Build date and time: " + buildInfo.getProperty("git.build.time"));
diff --git a/src/main/java/org/diyefi/openlogviewer/utils/MathUtils.java b/src/main/java/org/diyefi/openlogviewer/utils/MathUtils.java
index 78a577b..b15441c 100644
--- a/src/main/java/org/diyefi/openlogviewer/utils/MathUtils.java
+++ b/src/main/java/org/diyefi/openlogviewer/utils/MathUtils.java
@@ -25,51 +25,54 @@
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
/**
* MathUtils is used to provide math functions specific to the project.
+ *
* @author Ben Fenner
*/
public final class MathUtils {
- private static final char DS = DecimalFormatSymbols.getInstance().getDecimalSeparator();
- private static final DecimalFormat CUSTOM = (DecimalFormat) NumberFormat.getNumberInstance();
- private static final DecimalFormat NORMAL = (DecimalFormat) NumberFormat.getNumberInstance();
- static {
- CUSTOM.setGroupingUsed(false);
- NORMAL.setGroupingUsed(false);
- }
+ private static final char DS = DecimalFormatSymbols.getInstance().getDecimalSeparator();
+ private static final DecimalFormat CUSTOM = (DecimalFormat) NumberFormat.getNumberInstance();
+ private static final DecimalFormat NORMAL = (DecimalFormat) NumberFormat.getNumberInstance();
+
+ static {
+ CUSTOM.setGroupingUsed(false);
+ NORMAL.setGroupingUsed(false);
+ }
- private MathUtils() {
- }
+ private MathUtils() {
+ }
- /**
- *
- * @param input - The double you'd like to round the decimal places for
- * @param decimalPlaces - The number of decimal places you'd like
- * @return the formatted number
- */
- public static String roundDecimalPlaces(final double input, final int decimalPlaces) {
- // Deal with zero or negative decimal places requested
- if (decimalPlaces <= 0) {
- return NORMAL.format(Math.round(input));
- }
+ /**
+ * @param input - The double you'd like to round the decimal places for
+ * @param decimalPlaces - The number of decimal places you'd like
+ * @return the formatted number
+ */
+ public static String roundDecimalPlaces(final double input, final int decimalPlaces) {
+ // Deal with zero or negative decimal places requested
+ if (decimalPlaces <= 0) {
+ return NORMAL.format(Math.round(input));
+ }
- final StringBuilder format = new StringBuilder("###0" + DS);
- final StringBuilder negativeZero = new StringBuilder("-0" + DS);
+ final String format;
+ final StringBuilder negativeZero = new StringBuilder("-0" + DS);
- for (int i = 0; i < decimalPlaces; i++) {
- format.append('0');
- negativeZero.append('0');
- }
+ format = IntStream
+ .range(0, decimalPlaces)
+ .mapToObj(i -> "0" + '0')
+ .collect(Collectors.joining("", "###0" + DS, ""));
- CUSTOM.applyLocalizedPattern(format.toString());
- final StringBuilder output = new StringBuilder(CUSTOM.format(input));
+ CUSTOM.applyLocalizedPattern(format);
+ final StringBuilder output = new StringBuilder(CUSTOM.format(input));
- // Deal with negative zero
- if (output.toString().equals(negativeZero.toString())) {
- output.deleteCharAt(0);
- }
+ // Deal with negative zero
+ if (output.toString().equals(negativeZero.toString())) {
+ output.deleteCharAt(0);
+ }
- return output.toString();
- }
+ return output.toString();
+ }
}
diff --git a/src/main/resources/build/buildInfo.xml b/src/main/resources/build/buildInfo.xml
deleted file mode 100644
index f0852de..0000000
--- a/src/main/resources/build/buildInfo.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-Maven and Git properties filtered during build and available for use at runtime!
-
-
-
-
-${project.version}
-${project.description}
-${project.url}
-
-${maven.version}
-${maven.build.timestamp}
-
-${project.forum.url}
-${project.issueManagement.url}
-
-${os.name}
-${os.arch}
-${os.version}
-
-${java.version}
-${java.vm.version}
-${java.class.version}
-
-
-
-${git.commit.user.name}
-${git.commit.user.email}
-${git.commit.time}
-
-${git.build.user.name}
-${git.build.user.email}
-${git.build.time}
-
-${git.commit.id.describe}
-${git.commit.id.abbrev}
-${git.commit.id}
-
-
diff --git a/src/main/resources/buildInfo.properties b/src/main/resources/buildInfo.properties
new file mode 100644
index 0000000..b344321
--- /dev/null
+++ b/src/main/resources/buildInfo.properties
@@ -0,0 +1,4 @@
+project.version=${version}
+project.description=${description}
+
+gradle.version=${gradle.gradleVersion}
\ No newline at end of file
diff --git a/src/main/resources/log4j2.properties b/src/main/resources/log4j2.properties
new file mode 100644
index 0000000..c641461
--- /dev/null
+++ b/src/main/resources/log4j2.properties
@@ -0,0 +1,14 @@
+#---- Categories ----
+log4j.rootLogger = INFO, STDOUT, LOGFILE
+
+#---- Appenders ----
+log4j.appender.STDOUT = org.apache.log4j.ConsoleAppender
+log4j.appender.STDOUT.Target = System.out
+log4j.appender.STDOUT.layout = org.apache.log4j.PatternLayout
+log4j.appender.STDOUT.layout.ConversionPattern=OpenLogViewer %d [%t] %-5p %c - %m%n
+
+log4j.appender.LOGFILE = org.apache.log4j.FileAppender
+log4j.appender.LOGFILE.File = test.log
+log4j.appender.LOGFILE.Append = false
+log4j.appender.LOGFILE.layout = org.apache.log4j.PatternLayout
+log4j.appender.LOGFILE.layout.ConversionPattern=OpenLogViewer %d [%t] %-5p %c - %m%n
\ No newline at end of file
diff --git a/src/site/fredsChecks.xml b/src/site/fredsChecks.xml
deleted file mode 100644
index 41fed64..0000000
--- a/src/site/fredsChecks.xml
+++ /dev/null
@@ -1,145 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/site/pmd/rulesets/controversial.xml b/src/site/pmd/rulesets/controversial.xml
deleted file mode 100644
index 669efef..0000000
--- a/src/site/pmd/rulesets/controversial.xml
+++ /dev/null
@@ -1,622 +0,0 @@
-
-
-
-
-
-The Controversial ruleset contains rules that, for whatever reason, are considered controversial.
-They are held here to allow people to include them as they see fit within their custom rulesets.
-
-
-
-
-This rule detects when a constructor is not necessary; i.e., when there is only one constructor,
-its public, has an empty body, and takes no arguments.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Assigning a "null" to a variable (outside of its declaration) is usually bad form. Sometimes, this type
-of assignment is an indication that the programmer doesn't completely understand what is going on in the code.
-
-NOTE: This sort of assignment may used in some cases to dereference objects and encourage garbage collection.
-
- 3
-
-
-
-
-
-
-
-Avoid assignments in operands; this can make code more complicated and harder to read.
-
- 3
-
-
-
-
-
-
-
-Each class should declare at least one constructor.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Avoid importing anything from the 'sun.*' packages. These packages are not portable and are likely to change.
-
- 4
-
-
-
-
-
-
-
-A suspicious octal escape sequence was found inside a String literal.
-The Java language specification (section 3.10.6) says an octal
-escape sequence inside a literal String shall consist of a backslash
-followed by:
-
- OctalDigit | OctalDigit OctalDigit | ZeroToThree OctalDigit OctalDigit
-
-Any octal escape sequence followed by non-octal digits can be confusing,
-e.g. "\038" is interpreted as the octal escape sequence "\03" followed by
-the literal character "8".
-
- 3
-
-
-
-
-
-
-
-Sometimes expressions are wrapped in unnecessary parentheses, making them look like function calls.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Use bitwise inversion to invert boolean values - it's the fastest way to do this.
-See http://www.javaspecialists.co.za/archive/newsletter.do?issue=042&locale=en_US for specific details
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 4
-
-
-
- 1]
- ]]>
-
-
-
-
-
-
-
-
-
-
-
-
- 4
-
-
-
-
-
-
-
-
-
-
-
-
-
-When you write a public method, you should be thinking in terms of an API. If your method is public, it means other class
-will use it, therefore, you want (or need) to offer a comprehensive and evolutive API. If you pass a lot of information
-as a simple series of Strings, you may think of using an Object to represent all those information. You'll get a simplier
-API (such as doWork(Workload workload), rather than a tedious series of Strings) and more importantly, if you need at some
-point to pass extra data, you'll be able to do so by simply modifying or extending Workload without any modification to
-your API.
-
- 3
-
-
-
- 3
-]
-]]>
-
-
-
-
-
-
-
-
-
diff --git a/src/site/pmd/rulesets/coupling.xml b/src/site/pmd/rulesets/coupling.xml
deleted file mode 100644
index b3322a5..0000000
--- a/src/site/pmd/rulesets/coupling.xml
+++ /dev/null
@@ -1,141 +0,0 @@
-
-
-
-
-
-Rules which find instances of high or inappropriate coupling between objects and packages.
-
-
-
-
-This rule counts the number of unique attributes, local variables, and return types within an object.
-A number higher than the specified threshold can indicate a high degree of coupling.
-
- 3
-
-
-
-
-
-
-
-A high number of imports can indicate a high degree of coupling within an object. This rule
-counts the number of unique imports and reports a violation if the count is above the
-user-specified threshold.
-
- 3
-
-
-
-
-
-
-
-The use of implementation types as object references limits your ability to use alternate
-implementations in the future as requirements change. Whenever available, referencing objects
-by their interface types provides much more flexibility.
-
- 3
-
-
-
-
-
-
-
-
-The Law of Demeter is a simple rule, that says "only talk to friends". It helps to reduce coupling between classes or objects.
-See also the references:
-Andrew Hunt, David Thomas, and Ward Cunningham. The Pragmatic Programmer. From Journeyman to Master. Addison-Wesley Longman, Amsterdam, October 1999.;
-K.J. Lieberherr and I.M. Holland. Assuring good style for object-oriented programs. Software, IEEE, 6(5):38–48, 1989.;
-http://www.ccs.neu.edu/home/lieber/LoD.html;
-http://en.wikipedia.org/wiki/Law_of_Demeter
-
- 3
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/site/pmd/rulesets/design.xml b/src/site/pmd/rulesets/design.xml
deleted file mode 100644
index d89cff8..0000000
--- a/src/site/pmd/rulesets/design.xml
+++ /dev/null
@@ -1,1745 +0,0 @@
-
-
-
-
-
-The Design ruleset contains rules that flag suboptimal code implementations. Alternate approaches
-are suggested.
-
-
-
-
-
-
- 3
-
-
-
-
-
-
-
-
-Avoid unnecessary if-then-else statements when returning a boolean. The result of
-the conditional test can be returned instead.
-
- 3
-
-
-
-
-
-
-
-Avoid unnecessary comparisons in boolean expressions, they serve no purpose and impacts readability.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-All switch statements should include a default option to catch any unspecified values.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Avoid creating deeply nested if-then statements since they are harder to read and error-prone to maintain.
-
- 3
-
-y) {
- if (y>z) {
- if (z==x) {
- // !! too deep
- }
- }
- }
- }
-}
-]]>
-
-
-
-
-
-
-Reassigning values to incoming parameters is not recommended. Use temporary local variables instead.
-
- 2
-
-
-
-
-
-
-
-A high ratio of statements to labels in a switch statement implies that the switch statement
-is overloaded. Consider moving the statements into new methods or creating subclasses based
-on the switch variable.
-
- 3
-
-
-
-
-
-
-
-Calling overridable methods during construction poses a risk of invoking methods on an incompletely
-constructed object and can be difficult to debug.
-It may leave the sub-class unable to construct its superclass or forced to replicate the construction
-process completely within itself, losing the ability to call super(). If the default constructor
-contains a call to an overridable method, the subclass may be completely uninstantiable. Note that
-this includes method calls throughout the control flow graph - i.e., if a constructor Foo() calls a
-private method bar() that calls a public method buz(), this denotes a problem.
-
- 1
-
-
-
-
-
-
-
-Instantiation by way of private constructors from outside of the constructor's class often causes the
-generation of an accessor. A factory method, or non-privatization of the constructor can eliminate this
-situation. The generated class file is actually an interface. It gives the accessing class the ability
-to invoke a new hidden package scope constructor that takes the interface as a supplementary parameter.
-This turns a private constructor effectively into one with package scope, and is challenging to discern.
-
- 3
-
-
-
-
-
-
-
-If a final field is assigned to a compile-time constant, it could be made static, thus saving overhead
-in each object at runtime.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Ensure that resources (like Connection, Statement, and ResultSet objects) are always closed after use.
-
- 3
-
-
-
-
-
-
-
-A non-static initializer block will be called any time a constructor is invoked (just prior to
-invoking the constructor). While this is a valid language construct, it is rarely used and is
-confusing.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-By convention, the default label should be the last label in a switch statement.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-A non-case label (e.g. a named break/continue label) was present in a switch statement.
-This legal, but confusing. It is easy to mix up the case labels and the non-case labels.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Calls to a collection's toArray() method should specify target arrays sized to match the size of the
-collection. Initial arrays that are too small are discarded in favour of new ones that have to be created
-that are the proper size.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Avoid equality comparisons with Double.NaN. Due to the implicit lack of representation
-precision when comparing floating point numbers these are likely to cause logic errors.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Tests for null should not use the equals() method. The '==' operator should be used instead.
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Avoid instantiating an object just to call getClass() on it; use the .class public member instead.
-
- 4
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Avoid idempotent operations - they have no effect.
-
- 3
-
-
-
-
-
-
-
-
-Be sure to specify a Locale when creating SimpleDateFormat instances to ensure that locale-appropriate
-formatting is used.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Identifies private fields whose values never change once they are initialized either in the declaration
-of the field or by a constructor. This helps in converting existing classes to becoming immutable ones.
-
- 3
-
-
-
-
-
-
-
-
-When doing String.toLowerCase()/toUpperCase() conversions, use Locales to avoids problems with languages that
-have unusual conventions, i.e. Turkish.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Do not use protected fields in final classes since they cannot be subclassed.
-Clarify your intent by using private or package access modifiers instead.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Identifies a possible unsafe usage of a static field.
-
- 3
-
-
-
-
-
-
-
-A class that has private constructors and does not have any static methods or fields cannot be used.
-
- 3
-
-
-
- 0
- and count(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration) = count(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration[@Private='true']) )
-and
-count(.//MethodDeclaration[@Static='true'])=0
-and
-count(.//FieldDeclaration[@Private='false'][@Static='true'])=0
-]
- ]]>
-
-
-
-
-
-
-
-
-
-
-
-Method-level synchronization can cause problems when new code is added to the method.
-Block-level synchronization helps to ensure that only the code that needs synchronization
-gets it.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Switch statements without break or return statements for each case option
-may indicate problematic behaviour. Empty cases are ignored as these indicate an intentional fall-through.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Thread.notify() awakens a thread monitoring the object. If more than one thread is monitoring, then only
-one is chosen. The thread chosen is arbitrary; thus its usually safer to call notifyAll() instead.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Each caught exception type should be handled in its own catch clause.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-The abstract class does not contain any abstract methods. An abstract class suggests
-an incomplete implementation, which is to be completed by subclasses implementing the
-abstract methods. If the class is intended to be used as a base class only (not to be instantiated
-directly) a protected constructor can be provided prevent direct instantiation.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-No need to check for null before an instanceof; the instanceof keyword returns false when given a null argument.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Use equals() to compare object references; avoid comparing them with ==.
-
- 3
-
-
-
-
-
-
-
-
-Position literals first in comparisons, if the second argument is null then NullPointerExceptions
-can be avoided, they will just return false.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Avoid the creation of unnecessary local variables
-
- 3
-
-
-
-
-
-
-
-Non-thread safe singletons can result in bad state changes. Eliminate
-static singletons if possible by instantiating the object directly. Static
-singletons are usually not needed as only a single instance exists anyway.
-Other possible fixes are to synchronize the entire method or to use an
-initialize-on-demand holder class (do not use the double-check idiom).
-
-See Effective Java, item 48.
-
- 3
-
-
-
-
-
-
-
-Uncommented Empty Method finds instances where a method does not contain
-statements, but there is no comment. By explicitly commenting empty methods
-it is easier to distinguish between intentional (commented) and unintentional
-empty methods.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Uncommented Empty Constructor finds instances where a constructor does not
-contain statements, but there is no comment. By explicitly commenting empty
-constructors it is easier to distinguish between intentional (commented)
-and unintentional empty constructors.
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-An interface should be used only to characterize the external behaviour of an
-implementing class: using an interface as a container of constants is a poor
-usage pattern and not recommended.
-
- 3
-
-
-
- 0
- ]
- ]]>
-
-
-
-
-
-
-
-
-
-
-SimpleDateFormat instances are not synchronized. Sun recommends using separate format instances
-for each thread. If multiple threads must access a static formatter, the formatter must be
-synchronized either on method or block level.
-
- 3
-
-
-
-
-
-
-
-Throwing a new exception from a catch block without passing the original exception into the
-new exception will cause the original stack trace to be lost making it difficult to debug
-effectively.
-
- 3
-
-
-
-
-
-
-
-The isEmpty() method on java.util.Collection is provided to determine if a collection has any elements.
-Comparing the value of size() to 0 does not convey intent as well as the isEmpty() method.
-
- 3
-
-
-
-
-
-
-
-A class with only private constructors should be final, unless the private constructor
-is invoked by a inner class.
-
- 1
-
-
- = 1 ]
-[count(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration[(@Public = 'true') or (@Protected = 'true') or (@PackagePrivate = 'true')]) = 0 ]
-[not(.//ClassOrInterfaceDeclaration)]
- ]]>
-
-
-
-
-
-
-
-
-Empty methods in an abstract class should be tagged as abstract. This helps to remove their inapproprate
-usage by developers who should be implementing their own versions in the concrete subclasses.
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 3
-
-
-
-
-
-For any method that returns an array, it is a better to return an empty array rather than a
-null reference. This removes the need for null checking all results and avoids inadvertent
-NullPointerExceptions.
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-If an abstract class does not provides any methods, it may be acting as a simple data container
-that is not meant to be instantiated. In this case, it is probably better to use a private or
-protected constructor in order to prevent instantiation than make the class misleadingly abstract.
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Switch statements are indended to be used to support complex branching behaviour. Using a switch for only a few
-cases is ill-advised, since switches are not as easy to understand as if-then statements. In these cases use the
-if-then statement to increase code readability.
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Use opposite operator instead of negating the whole expression with a logic complement operator.
-
- 3
-
-
-
-
-
-
-
-
- =
- return false;
-
- return true;
-}
- ]]>
-
-
-
-
-
-Java 5 introduced the varargs parameter declaration for methods and constructors. This syntactic
-sugar provides flexibility for users of these methods and constructors, allowing them to avoid
-having to deal with the creation of an array.
-
- 4
-
-
-
-
-
-
-
-
-
-
-Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.
-
- 3
-
-
-
- 0]
- ]]>
-
-
-
-
-
-
-
-
-
-
-The God Class rule detects the God Class design flaw using metrics. God classes do too many things,
-are very big and overly complex. They should be split apart to be more object-oriented.
-The rule uses the detection strategy described in "Object-Oriented Metrics in Practice".
-The violations are reported against the entire class. See also the references:
-Michele Lanza and Radu Marinescu. Object-Oriented Metrics in Practice:
-Using Software Metrics to Characterize, Evaluate, and Improve the Design
-of Object-Oriented Systems. Springer, Berlin, 1 edition, October 2006. Page 80.
-
- 3
-
-
diff --git a/src/test/java/org/diyefi/openlogviewer/FileExtensionsTest.java b/src/test/java/org/diyefi/openlogviewer/FileExtensionsTest.java
new file mode 100644
index 0000000..13db93d
--- /dev/null
+++ b/src/test/java/org/diyefi/openlogviewer/FileExtensionsTest.java
@@ -0,0 +1,48 @@
+package org.diyefi.openlogviewer;
+
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import java.util.stream.Stream;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class FileExtensionsTest {
+
+ private static Stream fileExtensionProvider() {
+ return Stream.of(
+ Arguments.of(FileExtensions.STAR_DOT, "*."),
+ Arguments.of(FileExtensions.LA, "la"),
+ Arguments.of(FileExtensions.BIN, "bin"),
+ Arguments.of(FileExtensions.BIN, "bin"),
+ Arguments.of(FileExtensions.CSV, "csv"),
+ Arguments.of(FileExtensions.LOG, "log"),
+ Arguments.of(FileExtensions.XLS, "xls"),
+ Arguments.of(FileExtensions.MSL, "msl"));
+ }
+
+ @ParameterizedTest(name = "run #{index} with [{arguments}]")
+ @MethodSource("fileExtensionProvider")
+ void shouldReturnCorrectExtensionStringForGivenEnum(FileExtensions given, String expected) {
+ // ARRANGE
+
+ // ACT
+ String result = given.getExtension();
+
+ // ASSERT
+ assertThat(result).isEqualTo(expected);
+ }
+
+ @ParameterizedTest(name = "run #{index} with [{arguments}]")
+ @MethodSource("fileExtensionProvider")
+ void shouldReturnCorrectEnumforGivenExtensionString(FileExtensions expected, String given) {
+ // ARRANGE
+
+ // ACT
+ FileExtensions result = FileExtensions.getByExtension(given);
+
+ // ASSERT
+ assertThat(result).isEqualTo(expected);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/org/diyefi/openlogviewer/LanguageTextTest.java b/src/test/java/org/diyefi/openlogviewer/LanguageTextTest.java
deleted file mode 100644
index 6a7f5d8..0000000
--- a/src/test/java/org/diyefi/openlogviewer/LanguageTextTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package org.diyefi.openlogviewer;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.ResourceBundle;
-import java.util.Set;
-
-import org.junit.Ignore;
-import org.junit.Test;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.Validate;
-import org.diyefi.openlogviewer.Text;
-
-import static org.junit.Assert.*;
-
-
-/**
- * A set of tests to shake down the translations setup. It won't catch defaults pasted into the non-English file, but that shouldn't be done anyway.
- *
- * @author Fred Cooke
- */
-public class LanguageTextTest {
-
- private static final Field[] keys;
- static {
- keys = Text.class.getDeclaredFields();
- }
-
-
- private final Set keySet = new HashSet();
-
- /**
- * Ensure that no keys are themselves blank, forgotten or duplicated.
- *
- * Doing it here gets us a line number and blatant stack traces dumped.
- */
- public LanguageTextTest() {
- Validate.isTrue(keys.length > 0);
- // System.out.println("Text lookups: " + keys.length);
- for (Field k : keys) {
- if (!Modifier.isTransient(k.getModifiers())) {
- String key = null;
- try {
- key = (String)k.get(null);
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- Validate.isTrue(false); // Should never happen
- }
- Validate.notBlank(key); // No empties/blanks/nulls
- Validate.isTrue(keySet.add(key)); // No dupes
- } // Ignore cobertura's implanted field :-p
- }
- }
-
- // Individual tests below so as to see what went wrong, at a glance
-
- @Test
- public void testEnglishComplete() {
- testLanguageComplete(Locale.ENGLISH, "");
- }
-
- @Test
- public void testEnglishNoUnused() {
- testNoUnusedText(Locale.ENGLISH, "");
- }
-
- @Test
- @Ignore("Not yet complete!")
- public void testSpanishComplete() {
- testLanguageComplete(new Locale("es"), "_es");
- }
-
- @Test
- public void testSpanishNoUnused() {
- testNoUnusedText(new Locale("es"), "_es");
- }
-
- /**
- * Ensure that all keys for this language have a valid label
- *
- * @param locale
- * @param suffix
- */
- private void testLanguageComplete(Locale locale, String suffix) {
- ResourceBundle labels = getLabels(locale, suffix);
-
- for (String key : keySet) {
- String value = labels.getString(key);
- // System.out.println("Key/value: " + key + " = \"" + value + "\""); // Useful while debugging
- assertTrue(StringUtils.isNotBlank(value));
- }
- }
-
- /**
- * Ensure that everything in the properties files is referred to by a field in the text class.
- *
- * @param locale
- * @param suffix
- */
- private void testNoUnusedText(Locale locale, String suffix) {
- ResourceBundle labels = getLabels(locale, suffix);
-
- for (String label : labels.keySet()) {
- // System.out.println("Label: " + label); // Useful while debugging
- assertTrue(keySet.contains(label));
- }
- }
-
- private ResourceBundle getLabels(Locale locale, String suffix) {
- return ResourceBundle.getBundle(OpenLogViewer.class.getPackage().getName() + ".Labels" + suffix , locale);
- }
-}
diff --git a/src/test/java/org/diyefi/openlogviewer/decoder/FreeEMSBinaryTest.java b/src/test/java/org/diyefi/openlogviewer/decoder/FreeEMSBinaryTest.java
deleted file mode 100644
index 7009b4c..0000000
--- a/src/test/java/org/diyefi/openlogviewer/decoder/FreeEMSBinaryTest.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- *
- */
-package org.diyefi.openlogviewer.decoder;
-
-import junit.framework.TestCase;
-
-public class FreeEMSBinaryTest extends TestCase {
-
- public void testChecksum(){
- assertEquals(true, true);
- }
-
- public void testFail(){
- assertTrue(true);
- }
-
- public void testPass(){
- assertTrue(true);
- }
-}
diff --git a/src/test/java/org/diyefi/openlogviewer/utils/MathUtilsTest.java b/src/test/java/org/diyefi/openlogviewer/utils/MathUtilsTest.java
deleted file mode 100644
index bf3c30c..0000000
--- a/src/test/java/org/diyefi/openlogviewer/utils/MathUtilsTest.java
+++ /dev/null
@@ -1,197 +0,0 @@
-package org.diyefi.openlogviewer.utils;
-
-import java.util.Locale;
-
-import junit.framework.TestCase;
-
-public class MathUtilsTest extends TestCase {
-
- public MathUtilsTest(String name) {
- super(name);
- }
-
- protected void setUp() throws Exception {
- super.setUp();
- Locale.setDefault(Locale.US); // Ensure tests pass in Europe! :-)
- }
-
- public void testRoundDecimalPlaces(){
- int decimalPlaces = -1;
- assertEquals("0", MathUtils.roundDecimalPlaces(0D, decimalPlaces));
- assertEquals("0", MathUtils.roundDecimalPlaces(1D/3D, decimalPlaces));
- assertEquals("1", MathUtils.roundDecimalPlaces(0.5D, decimalPlaces));
- assertEquals("1", MathUtils.roundDecimalPlaces(2D/3D, decimalPlaces));
- assertEquals("1", MathUtils.roundDecimalPlaces(1.3333333D, decimalPlaces));
- assertEquals("2", MathUtils.roundDecimalPlaces(1.5D, decimalPlaces));
- assertEquals("2", MathUtils.roundDecimalPlaces(1.6666666D, decimalPlaces));
- assertEquals("22", MathUtils.roundDecimalPlaces(22.3333333D, decimalPlaces));
- assertEquals("23", MathUtils.roundDecimalPlaces(22.6666666D, decimalPlaces));
- assertEquals("1", MathUtils.roundDecimalPlaces(0.99D, decimalPlaces));
- assertEquals("1", MathUtils.roundDecimalPlaces(0.999D, decimalPlaces));
- assertEquals("1", MathUtils.roundDecimalPlaces(0.9999D, decimalPlaces));
- assertEquals("12345678912345678", MathUtils.roundDecimalPlaces(12345678912345678D, decimalPlaces));
- assertEquals("0", MathUtils.roundDecimalPlaces(0.0001234D, decimalPlaces));
- assertEquals("0", MathUtils.roundDecimalPlaces(0.0006789D, decimalPlaces));
-
- assertEquals("0", MathUtils.roundDecimalPlaces(-0D, decimalPlaces));
- assertEquals("0", MathUtils.roundDecimalPlaces(-1D/3D, decimalPlaces));
- assertEquals("0", MathUtils.roundDecimalPlaces(-0.5D, decimalPlaces));
- assertEquals("-1", MathUtils.roundDecimalPlaces(-2D/3D, decimalPlaces));
- assertEquals("-1", MathUtils.roundDecimalPlaces(-1.3333333D, decimalPlaces));
- assertEquals("-1", MathUtils.roundDecimalPlaces(-1.5D, decimalPlaces));
- assertEquals("-2", MathUtils.roundDecimalPlaces(-1.6666666D, decimalPlaces));
- assertEquals("-22", MathUtils.roundDecimalPlaces(-22.3333333D, decimalPlaces));
- assertEquals("-23", MathUtils.roundDecimalPlaces(-22.6666666D, decimalPlaces));
- assertEquals("-1", MathUtils.roundDecimalPlaces(-0.99D, decimalPlaces));
- assertEquals("-1", MathUtils.roundDecimalPlaces(-0.999D, decimalPlaces));
- assertEquals("-1", MathUtils.roundDecimalPlaces(-0.9999D, decimalPlaces));
- assertEquals("-12345678912345678", MathUtils.roundDecimalPlaces(-12345678912345678D, decimalPlaces));
- assertEquals("0", MathUtils.roundDecimalPlaces(-0.0001234D, decimalPlaces));
- assertEquals("0", MathUtils.roundDecimalPlaces(-0.0006789D, decimalPlaces));
-
- decimalPlaces = 0;
- assertEquals("0", MathUtils.roundDecimalPlaces(0D, decimalPlaces));
- assertEquals("0", MathUtils.roundDecimalPlaces(1D/3D, decimalPlaces));
- assertEquals("1", MathUtils.roundDecimalPlaces(0.5D, decimalPlaces));
- assertEquals("1", MathUtils.roundDecimalPlaces(2D/3D, decimalPlaces));
- assertEquals("1", MathUtils.roundDecimalPlaces(1.3333333D, decimalPlaces));
- assertEquals("2", MathUtils.roundDecimalPlaces(1.5D, decimalPlaces));
- assertEquals("2", MathUtils.roundDecimalPlaces(1.6666666D, decimalPlaces));
- assertEquals("22", MathUtils.roundDecimalPlaces(22.3333333D, decimalPlaces));
- assertEquals("23", MathUtils.roundDecimalPlaces(22.6666666D, decimalPlaces));
- assertEquals("1", MathUtils.roundDecimalPlaces(0.99D, decimalPlaces));
- assertEquals("1", MathUtils.roundDecimalPlaces(0.999D, decimalPlaces));
- assertEquals("1", MathUtils.roundDecimalPlaces(0.9999D, decimalPlaces));
- assertEquals("12345678912345678", MathUtils.roundDecimalPlaces(12345678912345678D, decimalPlaces));
- assertEquals("0", MathUtils.roundDecimalPlaces(0.0001234D, decimalPlaces));
- assertEquals("0", MathUtils.roundDecimalPlaces(0.0006789D, decimalPlaces));
-
- assertEquals("0", MathUtils.roundDecimalPlaces(-0D, decimalPlaces));
- assertEquals("0", MathUtils.roundDecimalPlaces(-1D/3D, decimalPlaces));
- assertEquals("0", MathUtils.roundDecimalPlaces(-0.5D, decimalPlaces));
- assertEquals("-1", MathUtils.roundDecimalPlaces(-2D/3D, decimalPlaces));
- assertEquals("-1", MathUtils.roundDecimalPlaces(-1.3333333D, decimalPlaces));
- assertEquals("-1", MathUtils.roundDecimalPlaces(-1.5D, decimalPlaces));
- assertEquals("-2", MathUtils.roundDecimalPlaces(-1.6666666D, decimalPlaces));
- assertEquals("-22", MathUtils.roundDecimalPlaces(-22.3333333D, decimalPlaces));
- assertEquals("-23", MathUtils.roundDecimalPlaces(-22.6666666D, decimalPlaces));
- assertEquals("-1", MathUtils.roundDecimalPlaces(-0.99D, decimalPlaces));
- assertEquals("-1", MathUtils.roundDecimalPlaces(-0.999D, decimalPlaces));
- assertEquals("-1", MathUtils.roundDecimalPlaces(-0.9999D, decimalPlaces));
- assertEquals("-12345678912345678", MathUtils.roundDecimalPlaces(-12345678912345678D, decimalPlaces));
- assertEquals("0", MathUtils.roundDecimalPlaces(-0.0001234D, decimalPlaces));
- assertEquals("0", MathUtils.roundDecimalPlaces(-0.0006789D, decimalPlaces));
-
- decimalPlaces = 1;
- assertEquals("0.0", MathUtils.roundDecimalPlaces(0D, decimalPlaces));
- assertEquals("0.3", MathUtils.roundDecimalPlaces(1D/3D, decimalPlaces));
- assertEquals("0.5", MathUtils.roundDecimalPlaces(0.5D, decimalPlaces));
- assertEquals("0.7", MathUtils.roundDecimalPlaces(2D/3D, decimalPlaces));
- assertEquals("1.3", MathUtils.roundDecimalPlaces(1.3333333D, decimalPlaces));
- assertEquals("1.5", MathUtils.roundDecimalPlaces(1.5D, decimalPlaces));
- assertEquals("1.7", MathUtils.roundDecimalPlaces(1.6666666D, decimalPlaces));
- assertEquals("22.3", MathUtils.roundDecimalPlaces(22.3333333D, decimalPlaces));
- assertEquals("22.7", MathUtils.roundDecimalPlaces(22.6666666D, decimalPlaces));
- assertEquals("1.0", MathUtils.roundDecimalPlaces(0.99D, decimalPlaces));
- assertEquals("1.0", MathUtils.roundDecimalPlaces(0.999D, decimalPlaces));
- assertEquals("1.0", MathUtils.roundDecimalPlaces(0.9999D, decimalPlaces));
- assertEquals("12345678912345678.0", MathUtils.roundDecimalPlaces(12345678912345678D, decimalPlaces));
- assertEquals("0.0", MathUtils.roundDecimalPlaces(0.0001234D, decimalPlaces));
- assertEquals("0.0", MathUtils.roundDecimalPlaces(0.0006789D, decimalPlaces));
-
- assertEquals("0.0", MathUtils.roundDecimalPlaces(-0D, decimalPlaces));
- assertEquals("-0.3", MathUtils.roundDecimalPlaces(-1D/3D, decimalPlaces));
- assertEquals("-0.5", MathUtils.roundDecimalPlaces(-0.5D, decimalPlaces));
- assertEquals("-0.7", MathUtils.roundDecimalPlaces(-2D/3D, decimalPlaces));
- assertEquals("-1.3", MathUtils.roundDecimalPlaces(-1.3333333D, decimalPlaces));
- assertEquals("-1.5", MathUtils.roundDecimalPlaces(-1.5D, decimalPlaces));
- assertEquals("-1.7", MathUtils.roundDecimalPlaces(-1.6666666D, decimalPlaces));
- assertEquals("-22.3", MathUtils.roundDecimalPlaces(-22.3333333D, decimalPlaces));
- assertEquals("-22.7", MathUtils.roundDecimalPlaces(-22.6666666D, decimalPlaces));
- assertEquals("-1.0", MathUtils.roundDecimalPlaces(-0.99D, decimalPlaces));
- assertEquals("-1.0", MathUtils.roundDecimalPlaces(-0.999D, decimalPlaces));
- assertEquals("-1.0", MathUtils.roundDecimalPlaces(-0.9999D, decimalPlaces));
- assertEquals("-12345678912345678.0", MathUtils.roundDecimalPlaces(-12345678912345678D, decimalPlaces));
- assertEquals("0.0", MathUtils.roundDecimalPlaces(-0.0001234D, decimalPlaces));
- assertEquals("0.0", MathUtils.roundDecimalPlaces(-0.0006789D, decimalPlaces));
-
-
- decimalPlaces = 2;
- assertEquals("0.00", MathUtils.roundDecimalPlaces(0D, decimalPlaces));
- assertEquals("0.33", MathUtils.roundDecimalPlaces(1D/3D, decimalPlaces));
- assertEquals("0.50", MathUtils.roundDecimalPlaces(0.5D, decimalPlaces));
- assertEquals("0.67", MathUtils.roundDecimalPlaces(2D/3D, decimalPlaces));
- assertEquals("1.33", MathUtils.roundDecimalPlaces(1.3333333D, decimalPlaces));
- assertEquals("1.50", MathUtils.roundDecimalPlaces(1.5D, decimalPlaces));
- assertEquals("1.67", MathUtils.roundDecimalPlaces(1.6666666D, decimalPlaces));
- assertEquals("22.33", MathUtils.roundDecimalPlaces(22.3333333D, decimalPlaces));
- assertEquals("22.67", MathUtils.roundDecimalPlaces(22.6666666D, decimalPlaces));
- assertEquals("0.99", MathUtils.roundDecimalPlaces(0.99D, decimalPlaces));
- assertEquals("1.00", MathUtils.roundDecimalPlaces(0.999D, decimalPlaces));
- assertEquals("1.00", MathUtils.roundDecimalPlaces(0.9999D, decimalPlaces));
- assertEquals("12345678912345678.00", MathUtils.roundDecimalPlaces(12345678912345678D, decimalPlaces));
- assertEquals("0.00", MathUtils.roundDecimalPlaces(0.0001234D, decimalPlaces));
- assertEquals("0.00", MathUtils.roundDecimalPlaces(0.0006789D, decimalPlaces));
-
- assertEquals("0.00", MathUtils.roundDecimalPlaces(-0D, decimalPlaces));
- assertEquals("-0.33", MathUtils.roundDecimalPlaces(-1D/3D, decimalPlaces));
- assertEquals("-0.50", MathUtils.roundDecimalPlaces(-0.5D, decimalPlaces));
- assertEquals("-0.67", MathUtils.roundDecimalPlaces(-2D/3D, decimalPlaces));
- assertEquals("-1.33", MathUtils.roundDecimalPlaces(-1.3333333D, decimalPlaces));
- assertEquals("-1.50", MathUtils.roundDecimalPlaces(-1.5D, decimalPlaces));
- assertEquals("-1.67", MathUtils.roundDecimalPlaces(-1.6666666D, decimalPlaces));
- assertEquals("-22.33", MathUtils.roundDecimalPlaces(-22.3333333D, decimalPlaces));
- assertEquals("-22.67", MathUtils.roundDecimalPlaces(-22.6666666D, decimalPlaces));
- assertEquals("-0.99", MathUtils.roundDecimalPlaces(-0.99D, decimalPlaces));
- assertEquals("-1.00", MathUtils.roundDecimalPlaces(-0.999D, decimalPlaces));
- assertEquals("-1.00", MathUtils.roundDecimalPlaces(-0.9999D, decimalPlaces));
- assertEquals("-12345678912345678.00", MathUtils.roundDecimalPlaces(-12345678912345678D, decimalPlaces));
- assertEquals("0.00", MathUtils.roundDecimalPlaces(-0.0001234D, decimalPlaces));
- assertEquals("0.00", MathUtils.roundDecimalPlaces(-0.0006789D, decimalPlaces));
-
-
- decimalPlaces = 6;
- assertEquals("0.000000", MathUtils.roundDecimalPlaces(0D, decimalPlaces));
- assertEquals("0.333333", MathUtils.roundDecimalPlaces(1D/3D, decimalPlaces));
- assertEquals("0.500000", MathUtils.roundDecimalPlaces(0.5D, decimalPlaces));
- assertEquals("0.666667", MathUtils.roundDecimalPlaces(2D/3D, decimalPlaces));
- assertEquals("1.333333", MathUtils.roundDecimalPlaces(1.3333333D, decimalPlaces));
- assertEquals("1.500000", MathUtils.roundDecimalPlaces(1.5D, decimalPlaces));
- assertEquals("1.666667", MathUtils.roundDecimalPlaces(1.6666666D, decimalPlaces));
- assertEquals("22.333333", MathUtils.roundDecimalPlaces(22.3333333D, decimalPlaces));
- assertEquals("22.666667", MathUtils.roundDecimalPlaces(22.6666666D, decimalPlaces));
- assertEquals("0.990000", MathUtils.roundDecimalPlaces(0.99D, decimalPlaces));
- assertEquals("0.999000", MathUtils.roundDecimalPlaces(0.999D, decimalPlaces));
- assertEquals("0.999900", MathUtils.roundDecimalPlaces(0.9999D, decimalPlaces));
- assertEquals("12345678912345678.000000", MathUtils.roundDecimalPlaces(12345678912345678D, decimalPlaces));
- assertEquals("0.000123", MathUtils.roundDecimalPlaces(0.0001234D, decimalPlaces));
- assertEquals("0.000679", MathUtils.roundDecimalPlaces(0.0006789D, decimalPlaces));
-
- assertEquals("0.000000", MathUtils.roundDecimalPlaces(-0D, decimalPlaces));
- assertEquals("-0.333333", MathUtils.roundDecimalPlaces(-1D/3D, decimalPlaces));
- assertEquals("-0.500000", MathUtils.roundDecimalPlaces(-0.5D, decimalPlaces));
- assertEquals("-0.666667", MathUtils.roundDecimalPlaces(-2D/3D, decimalPlaces));
- assertEquals("-1.333333", MathUtils.roundDecimalPlaces(-1.3333333D, decimalPlaces));
- assertEquals("-1.500000", MathUtils.roundDecimalPlaces(-1.5D, decimalPlaces));
- assertEquals("-1.666667", MathUtils.roundDecimalPlaces(-1.6666666D, decimalPlaces));
- assertEquals("-22.333333", MathUtils.roundDecimalPlaces(-22.3333333D, decimalPlaces));
- assertEquals("-22.666667", MathUtils.roundDecimalPlaces(-22.6666666D, decimalPlaces));
- assertEquals("-0.990000", MathUtils.roundDecimalPlaces(-0.99D, decimalPlaces));
- assertEquals("-0.999000", MathUtils.roundDecimalPlaces(-0.999D, decimalPlaces));
- assertEquals("-0.999900", MathUtils.roundDecimalPlaces(-0.9999D, decimalPlaces));
- assertEquals("-12345678912345678.000000", MathUtils.roundDecimalPlaces(-12345678912345678D, decimalPlaces));
- assertEquals("-0.000123", MathUtils.roundDecimalPlaces(-0.0001234D, decimalPlaces));
- assertEquals("-0.000679", MathUtils.roundDecimalPlaces(-0.0006789D, decimalPlaces));
- }
-
- public void testRoundDecimalPlacesSpeed(){
- long thePast = System.currentTimeMillis();
- int iterations = 0;
-
- for (int i = 0; i < iterations; i++){
- testRoundDecimalPlaces();
- }
- long elapsedTime = System.currentTimeMillis() - thePast;
- System.out.println("Time to complete " + iterations + " iterations of testRoundDecimalPlaces(): " + elapsedTime + "ms");
- }
-}
diff --git a/src/test/resources/log4j2.properties b/src/test/resources/log4j2.properties
new file mode 100644
index 0000000..c641461
--- /dev/null
+++ b/src/test/resources/log4j2.properties
@@ -0,0 +1,14 @@
+#---- Categories ----
+log4j.rootLogger = INFO, STDOUT, LOGFILE
+
+#---- Appenders ----
+log4j.appender.STDOUT = org.apache.log4j.ConsoleAppender
+log4j.appender.STDOUT.Target = System.out
+log4j.appender.STDOUT.layout = org.apache.log4j.PatternLayout
+log4j.appender.STDOUT.layout.ConversionPattern=OpenLogViewer %d [%t] %-5p %c - %m%n
+
+log4j.appender.LOGFILE = org.apache.log4j.FileAppender
+log4j.appender.LOGFILE.File = test.log
+log4j.appender.LOGFILE.Append = false
+log4j.appender.LOGFILE.layout = org.apache.log4j.PatternLayout
+log4j.appender.LOGFILE.layout.ConversionPattern=OpenLogViewer %d [%t] %-5p %c - %m%n
\ No newline at end of file