13 Commits
0.9 ... 0.9.3

Author SHA1 Message Date
Andreas Billmann
cf9203549b Merge pull request #17 from aoetk/fileencoding
Add the setting changes encoding for CSV file to the preference dialog
2019-10-22 22:36:26 +02:00
AOE Takashi
02b102cfb2 Add the setting changes encoding for CSV file to the preference dialog
(cherry picked from commit 11210b6d8b4584621ef02e7356854ffa9f7f2647)
2019-10-19 23:16:09 +09:00
8e0e1c41c3 update the README.md with the 0.9.2 download link 2019-10-03 21:18:16 +02:00
3ce9ae8edd fixed the main javafx application problem 2019-10-03 21:08:29 +02:00
7c12b7506f upgrade to javafx 13 2019-10-03 18:03:01 +02:00
6fc62006fa upgrade to javafx 12 2019-07-08 20:11:50 +02:00
fdc4f99fd5 updated dependencies 2018-07-08 14:01:13 +02:00
e29d60b9b8 upgraded gradle wrapper 2018-07-08 13:42:43 +02:00
0a4e86c160 fixed the markdown 2018-04-22 09:27:20 +02:00
c07dde8e19 updated the version number and link to the distribution 2018-04-22 09:25:50 +02:00
9b0e3707b7 updated libs and removed fxlauncher as it is not used by customers 2018-04-22 09:18:01 +02:00
a1f6c24bae updatet libraries to the newest versions 2017-03-22 12:00:35 +01:00
c1a671504e added fxlauncher to about dialog 2016-10-06 21:27:09 +02:00
23 changed files with 435 additions and 160 deletions

View File

@@ -1,7 +1,7 @@
The MIT License (MIT)
------------------------------------------------------------------------------------------------------------------------
Copyright (c) 2015-2016 Andreas Billmann <andreas.billmann@javafx.ninja>
Copyright (c) 2015-2019 Andreas Billmann <andreas.billmann@javafx.ninja>

View File

@@ -1,30 +1,29 @@
# SmartCSV.fx
##Description
## Description
A simple JavaFX application to load, save and edit a CSV file and provide a [JSON Table Schema](http://specs.frictionlessdata.io/json-table-schema/) for columns to check the values in the columns.
##Motivation
## Motivation
At work I have the need to fix wrong CSV files from customers. It is hard to find the errors and fix them in a texteditor,
even in a "normal" CSV editor. So I decided to write this simple JavaFX application.
##Video
## Video
[![short video about the application](http://img.youtube.com/vi/eUh_WLx1OwI/0.jpg)](https://youtu.be/eUh_WLx1OwI)
##Links
## Links
[GitHub Page](http://frosch95.github.io/SmartCSV.fx/)
[Wiki & Documentation](https://github.com/frosch95/SmartCSV.fx/wiki)
binary distribution of the [SmartCSV.fx launcher](http://www.javafx.ninja/SmartCSV.fx/SmartCSV.fx.jar)
copy the jar to an appropriate place and start the application with a double click on the jar (or java -jar SmartCSV.fx.jar on command line)
binary distribution of the [latest release (0.9.2)](https://github.com/frosch95/SmartCSV.fx/releases/download/0.9.2/SmartCSV.fx-0.9.2-SNAPSHOT.zip)
##Talks
## Talks
[Introduction](http://javafx.ninja/talks/introduction/)
##License
###The MIT License (MIT)
## License
### The MIT License (MIT)
Copyright (c) 2015-2016 Andreas Billmann <andreas.billmann@javafx.ninja>
Copyright (c) 2015-2019 Andreas Billmann <andreas.billmann@javafx.ninja>

View File

@@ -1,32 +1,9 @@
group 'ninja.javafx'
version '0.9-SNAPSHOT'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'no.tornado:fxlauncher-gradle-plugin:1.0.12'
}
}
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'application'
apply plugin: 'idea'
apply plugin: 'no.tornado.fxlauncher'
sourceCompatibility = 1.8
mainClassName = 'ninja.javafx.smartcsv.fx.SmartCSV'
def fxlauncherPathName = getBuildDir().absolutePath + File.separatorChar + 'fxlauncher' + File.separatorChar
fxlauncher {
applicationVendor 'Andreas Billmann (andreas.billmann@javafx.ninja)'
applicationUrl 'http://javafx.ninja/SmartCSV.fx/'
applicationMainClass mainClassName
acceptDowngrade false
cacheDir 'USERLIB/SmartCSV.fx'
plugins {
id 'idea'
id 'java'
id 'groovy'
id 'application'
id 'org.openjfx.javafxplugin' version '0.0.8'
}
repositories {
@@ -34,40 +11,29 @@ repositories {
jcenter()
}
javafx {
version = "13"
modules = [ 'javafx.controls', 'javafx.fxml' ]
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile group: 'org.hamcrest', name: 'hamcrest-library', version: '1.3'
compile group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.4.7'
compile group: 'org.springframework', name:'spring-context', version: '4.3.1.RELEASE'
compile group: 'org.codehaus.groovy', name: 'groovy-all', version: '3.0.0-beta-3'
compile group: 'org.springframework', name:'spring-context', version: '5.2.0.RELEASE'
compile group: 'net.sf.supercsv', name: 'super-csv', version: '2.4.0'
compile group: 'commons-validator', name: 'commons-validator', version: '1.5.1'
compile group: 'de.jensd', name: 'fontawesomefx-commons', version: '8.12'
compile group: 'de.jensd', name: 'fontawesomefx-fontawesome', version: '4.6.3'
compile group: 'de.jensd', name: 'fontawesomefx-materialdesignfont', version: '1.6.50'
compile group: 'de.jensd', name: 'fontawesomefx-materialicons', version: '2.2.0'
compile group: 'org.controlsfx', name: 'controlsfx', version: '8.40.11'
compile group: 'com.google.code.gson', name: 'gson', version: '2.7'
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.6.2'
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.6.2'
compile group: 'org.fxmisc.richtext', name: 'richtextfx', version: '0.6.10'
compile group: 'commons-validator', name: 'commons-validator', version: '1.6'
compile group: 'de.jensd', name: 'fontawesomefx-commons', version: '11.0'
compile group: 'de.jensd', name: 'fontawesomefx-fontawesome', version: '4.7.0-11'
compile group: 'de.jensd', name: 'fontawesomefx-materialdesignfont', version: '1.7.22-11'
compile group: 'de.jensd', name: 'fontawesomefx-materialicons', version: '2.2.0-11'
compile group: 'org.controlsfx', name: 'controlsfx', version: '11.0.0'
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.11.0'
compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.11.0'
compile group: 'org.fxmisc.richtext', name: 'richtextfx', version: '0.10.2'
}
task wrapper(type: Wrapper) {
gradleVersion = '3.1' //version required
}
task buildSmartCSV(dependsOn: ['clean','embedApplicationManifest']) << {
def file = new File(fxlauncherPathName + 'fxlauncher.jar')
file.renameTo(fxlauncherPathName + 'SmartCSV.fx.jar')
}
task modifyAppXML(dependsOn: 'generateApplicationManifest') << {
String contents = new File( fxlauncherPathName + 'app.xml' ).getText( 'UTF-8' )
contents = contents.replaceAll( 'Updating...', 'Updating SmartCSV.fx ...' )
contents = contents.replaceAll( '-fx-spacing: 10; -fx-padding: 25;', '-fx-spacing: 10; -fx-padding: 25;-fx-font-size: 0.9em;' )
new File( fxlauncherPathName + 'app.xml' ).write( contents, 'UTF-8' )
}
embedApplicationManifest.dependsOn modifyAppXML
defaultTasks 'buildSmartCSV'
group 'ninja.javafx'
version '0.9.2-SNAPSHOT'
mainClassName = 'ninja.javafx.smartcsv.Main'

Binary file not shown.

View File

@@ -1,6 +1,5 @@
#Thu Oct 06 15:00:38 CEST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip

100
gradlew vendored
View File

@@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
##############################################################################
##
@@ -6,42 +6,6 @@
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# 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
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@@ -60,6 +24,46 @@ 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.
@@ -85,7 +89,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
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
@@ -150,11 +154,19 @@ if $cygwin ; then
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
APP_ARGS=$(save "$@")
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
# 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" "$@"

12
gradlew.bat vendored
View File

@@ -8,14 +8,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@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=
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
@@ -49,7 +49,6 @@ goto fail
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +59,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line

View File

@@ -0,0 +1,10 @@
package ninja.javafx.smartcsv;
import ninja.javafx.smartcsv.fx.SmartCSV;
public class Main {
public static void main(String[] args) {
// workaround for module problem
SmartCSV.main(args);
}
}

View File

@@ -35,6 +35,8 @@ public class CSVConfigurable {
protected CsvPreference csvPreference;
protected String fileEncoding;
public CSVConfigurable() {
csvPreference = CsvPreference.EXCEL_NORTH_EUROPE_PREFERENCE;
}
@@ -42,4 +44,9 @@ public class CSVConfigurable {
public void setCsvPreference(CsvPreference csvPreference) {
this.csvPreference = csvPreference;
}
public void setFileEncoding(String fileEncoding) {
this.fileEncoding = fileEncoding;
}
}

View File

@@ -34,6 +34,7 @@ import org.supercsv.io.ICsvMapReader;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Map;
/**
@@ -48,7 +49,8 @@ public class CSVFileReader extends CSVConfigurable implements FileReader<CSVMode
ICsvMapReader mapReader = null;
try {
mapReader = new CsvMapReader(new java.io.FileReader(file.getAbsoluteFile()), csvPreference);
mapReader = new CsvMapReader(new java.io.FileReader(file.getAbsoluteFile(), Charset.forName(fileEncoding)),
csvPreference);
model = new CSVModel();
// the header columns are used as the keys to the Map

View File

@@ -34,6 +34,7 @@ import org.supercsv.io.ICsvMapWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Map;
import static java.util.stream.Collectors.toMap;
@@ -53,7 +54,8 @@ public class CSVFileWriter extends CSVConfigurable implements ninja.javafx.smart
public void write(File filename) throws IOException {
ICsvMapWriter mapWriter = null;
try {
mapWriter = new CsvMapWriter(new FileWriter(filename.getAbsolutePath()), csvPreference);
mapWriter = new CsvMapWriter(new FileWriter(filename.getAbsolutePath(), Charset.forName(fileEncoding)),
csvPreference);
mapWriter.writeHeader(model.getHeader());
for(CSVRow row: model.getRows()) {

View File

@@ -54,8 +54,7 @@ import ninja.javafx.smartcsv.fx.table.model.CSVValue;
import ninja.javafx.smartcsv.fx.util.LoadFileService;
import ninja.javafx.smartcsv.fx.util.SaveFileService;
import ninja.javafx.smartcsv.fx.validation.ValidationEditorController;
import ninja.javafx.smartcsv.preferences.PreferencesFileReader;
import ninja.javafx.smartcsv.preferences.PreferencesFileWriter;
import ninja.javafx.smartcsv.preferences.*;
import ninja.javafx.smartcsv.validation.configuration.ValidationConfiguration;
import ninja.javafx.smartcsv.validation.ValidationError;
import ninja.javafx.smartcsv.validation.ValidationFileReader;
@@ -68,6 +67,7 @@ import org.supercsv.prefs.CsvPreference;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Optional;
import java.util.ResourceBundle;
@@ -93,6 +93,13 @@ public class SmartCSVController extends FXMLController {
".SmartCSV.fx" +
File.separator + "" +
"preferences.json");
private static final File ENCODING_FILE = new File(System.getProperty("user.home") +
File.separator +
".SmartCSV.fx" +
File.separator +
"encoding.json");
public static final String CSV_FILTER_TEXT = "CSV files (*.csv)";
public static final String CSV_FILTER_EXTENSION = "*.csv";
public static final String JSON_FILTER_TEXT = "JSON files (*.json)";
@@ -213,6 +220,7 @@ public class SmartCSVController extends FXMLController {
private FileStorage<CSVModel> currentCsvFile = new FileStorage<>(csvFileReader, csvFileWriter);
private FileStorage<ValidationConfiguration> currentConfigFile = new FileStorage<>(new ValidationFileReader(), new ValidationFileWriter());
private FileStorage<CsvPreference> csvPreferenceFile = new FileStorage<>(new PreferencesFileReader(), new PreferencesFileWriter());
private FileStorage<String> fileEncodingFile = new FileStorage<>(new EncodingFileReader(), new EncodingFileWriter());
private ListChangeListener<ValidationError> errorListListener = c -> tableView.refresh();
private WeakListChangeListener<ValidationError> weakErrorListListener = new WeakListChangeListener<>(errorListListener);
@@ -238,10 +246,25 @@ public class SmartCSVController extends FXMLController {
bindConfigFileName();
csvPreferenceFile.setFile(PREFERENCES_FILE);
fileEncodingFile.setFile(ENCODING_FILE);
loadCsvPreferencesFromFile();
}
private void loadEncodingFromFile() {
if (fileEncodingFile.getFile().exists()) {
useLoadFileService(fileEncodingFile, event -> setFileEncoding(fileEncodingFile.getContent()));
} else {
setFileEncoding(Charset.defaultCharset().name());
}
}
private void setFileEncoding(String content) {
preferencesController.setFileEncoding(content);
csvFileReader.setFileEncoding(content);
csvFileWriter.setFileEncoding(content);
}
private void setupErrorSideBar(ResourceBundle resourceBundle) {
errorSideBar = new ErrorSideBar(resourceBundle);
errorSideBar.selectedValidationErrorProperty().addListener((observable, oldValue, newValue) -> {
@@ -345,8 +368,29 @@ public class SmartCSVController extends FXMLController {
CsvPreference csvPreference = preferencesController.getCsvPreference();
setCsvPreference(csvPreference);
saveCsvPreferences(csvPreference);
String fileEncoding = CharsetHelper.getCharsetName(preferencesController.getFileEncoding());
setFileEncoding(fileEncoding);
saveFileEncoding(fileEncoding);
} else {
preferencesController.setCsvPreference(csvPreferenceFile.getContent());
preferencesController.setFileEncoding(fileEncodingFile.getContent());
}
}
private void saveFileEncoding(String fileEncoding) {
try {
createFileEncodingFile();
fileEncodingFile.setContent(fileEncoding);
useSaveFileService(fileEncodingFile);
} catch (IOException e) {
e.printStackTrace();
}
}
private void createFileEncodingFile() throws IOException {
if (!fileEncodingFile.getFile().exists()) {
createPreferencesFileFolder();
fileEncodingFile.getFile().createNewFile();
}
}
@@ -492,9 +536,13 @@ public class SmartCSVController extends FXMLController {
private void loadCsvPreferencesFromFile() {
if (csvPreferenceFile.getFile().exists()) {
useLoadFileService(csvPreferenceFile, event -> setCsvPreference(csvPreferenceFile.getContent()));
useLoadFileService(csvPreferenceFile, event -> {
setCsvPreference(csvPreferenceFile.getContent());
loadEncodingFromFile();
});
} else {
setCsvPreference(CsvPreference.EXCEL_NORTH_EUROPE_PREFERENCE);
loadEncodingFromFile();
}
}

View File

@@ -39,6 +39,7 @@ import org.springframework.stereotype.Component;
import org.supercsv.prefs.CsvPreference;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ResourceBundle;
import java.util.function.UnaryOperator;
@@ -66,6 +67,9 @@ public class PreferencesController extends FXMLController {
@FXML
private ComboBox<String> quoteMode;
@FXML
private ComboBox<String> fileEncoding;
private String endOfLineSymbols;
private BooleanProperty valid = new SimpleBooleanProperty(true);
@@ -80,6 +84,7 @@ public class PreferencesController extends FXMLController {
@Override
public void initialize(URL location, ResourceBundle resources) {
quoteMode.getItems().addAll("normal", "always", "column");
fileEncoding.getItems().addAll(Charset.availableCharsets().keySet());
UnaryOperator<TextFormatter.Change> allowOnlyOneCharacter = change -> {
if (change.isContentChange()) {
@@ -117,6 +122,14 @@ public class PreferencesController extends FXMLController {
.build();
}
public void setFileEncoding(String fileEncoding) {
this.fileEncoding.setValue(fileEncoding);
}
public String getFileEncoding() {
return fileEncoding.getValue();
}
public boolean getValid() {
return valid.get();
}

View File

@@ -35,8 +35,8 @@ import ninja.javafx.smartcsv.fx.FXMLController;
import ninja.javafx.smartcsv.validation.configuration.*;
import org.fxmisc.richtext.CodeArea;
import org.fxmisc.richtext.LineNumberFactory;
import org.fxmisc.richtext.StyleSpans;
import org.fxmisc.richtext.StyleSpansBuilder;
import org.fxmisc.richtext.model.StyleSpans;
import org.fxmisc.richtext.model.StyleSpansBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

View File

@@ -0,0 +1,44 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.preferences;
import java.nio.charset.Charset;
/**
* Helper class for getting charset's name
*/
public class CharsetHelper {
public static String getCharsetName(String name) {
try {
return Charset.forName(name).name();
} catch (Exception e) {
return Charset.defaultCharset().name();
}
}
}

View File

@@ -0,0 +1,62 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.preferences;
import com.google.gson.GsonBuilder;
import ninja.javafx.smartcsv.FileReader;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
/**
* file reader for the file encoding
*/
public class EncodingFileReader implements FileReader<String> {
private String fileEncoding;
public EncodingFileReader() {
fileEncoding = Charset.defaultCharset().name();
}
@Override
public String getContent() {
return fileEncoding;
}
@Override
public void read(File filename) throws IOException {
Map settings = new GsonBuilder().create().fromJson(new java.io.FileReader(filename), HashMap.class);
if (settings != null) {
fileEncoding = CharsetHelper.getCharsetName(settings.get("fileEncoding").toString());
}
}
}

View File

@@ -0,0 +1,59 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.preferences;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import ninja.javafx.smartcsv.FileWriter;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
/**
* Save the file encoding to configuration file
*/
public class EncodingFileWriter implements FileWriter<String> {
private String fileEncoding;
@Override
public void setContent(String fileEncoding) {
this.fileEncoding = fileEncoding;
}
@Override
public void write(File filename) throws IOException {
Map<String, String> encodings = new HashMap<>();
encodings.put("fileEncoding", CharsetHelper.getCharsetName(fileEncoding));
Gson gson = new GsonBuilder().setPrettyPrinting().create();
Files.write(filename.toPath(), gson.toJson(encodings).getBytes());
}
}

View File

@@ -1,21 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Hyperlink?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="600.0" spacing="4.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1">
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="600.0" spacing="4.0" xmlns="http://javafx.com/javafx/8.0.76-ea" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label text="SmartCSV.fx">
<font>
<Font size="18.0" />
</font>
<VBox.margin>
<Insets top="8.0" />
</VBox.margin>
</Label>
<Label text="A simple JavaFX application to load, save and edit a CSV file and provide a JSON configuration for columns " wrapText="true" />
<Label text="to check the values in the columns." />
<Label text="Thanks for contributions:">
<font>
<Font size="18.0" />
@@ -42,17 +39,17 @@
<ColumnConstraints hgrow="ALWAYS" minWidth="10.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="20.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="20.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="20.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="20.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="20.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="20.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="20.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="20.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="20.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="20.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="20.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="junit" />
@@ -92,7 +89,7 @@
<Font size="18.0" />
</font>
</Label>
<TextArea editable="false" prefHeight="200.0" prefWidth="200.0" text="Copyright (c) 2015-2016 Andreas Billmann &lt;andreas.billmann@javafx.ninja&gt;&#10;&#10;Permission is hereby granted, free of charge, to any person obtaining a copy&#10;of this software and associated documentation files (the &quot;Software&quot;), to deal&#10;in the Software without restriction, including without limitation the rights&#10;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell&#10;copies of the Software, and to permit persons to whom the Software is&#10;furnished to do so, subject to the following conditions:&#10;&#10;The above copyright notice and this permission notice shall be included in&#10;all copies or substantial portions of the Software.&#10;&#10;&#10;&#10;THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR&#10;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,&#10;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE&#10;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER&#10;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,&#10;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN&#10;THE SOFTWARE." wrapText="true" />
<TextArea editable="false" prefHeight="200.0" prefWidth="200.0" text="Copyright (c) 2015-2019 Andreas Billmann &lt;andreas.billmann@javafx.ninja&gt;&#10;&#10;Permission is hereby granted, free of charge, to any person obtaining a copy&#10;of this software and associated documentation files (the &quot;Software&quot;), to deal&#10;in the Software without restriction, including without limitation the rights&#10;to use, copy, modify, merge, publish, distribute, sublicense, and/or sell&#10;copies of the Software, and to permit persons to whom the Software is&#10;furnished to do so, subject to the following conditions:&#10;&#10;The above copyright notice and this permission notice shall be included in&#10;all copies or substantial portions of the Software.&#10;&#10;&#10;&#10;THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR&#10;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,&#10;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE&#10;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER&#10;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,&#10;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN&#10;THE SOFTWARE." wrapText="true" />
</children>
<opaqueInsets>
<Insets />

View File

@@ -1,5 +1,5 @@
application.name = SmartCSV.fx
application.version = 0.9
application.version = 0.9.1
# fxml views
fxml.smartcvs.view = /ninja/javafx/smartcsv/fx/smartcsv.fxml

View File

@@ -14,6 +14,7 @@
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
</rowConstraints>
<children>
<Label text="%preferences.quoteChar" />
@@ -26,6 +27,8 @@
<CheckBox fx:id="ignoreEmptyLines" mnemonicParsing="false" text="" GridPane.columnIndex="1" GridPane.rowIndex="3" />
<Label text="%preferences.quoteMode" GridPane.rowIndex="4" />
<ComboBox fx:id="quoteMode" prefWidth="150.0" GridPane.columnIndex="1" GridPane.rowIndex="4" />
<Label text="%preferences.fileEncoding" GridPane.rowIndex="5" />
<ComboBox fx:id="fileEncoding" editable="true" prefWidth="150.0" GridPane.columnIndex="1" GridPane.rowIndex="5" />
</children>
<padding>
<Insets bottom="8.0" left="8.0" right="8.0" top="8.0" />

View File

@@ -41,6 +41,7 @@ preferences.delimiterChar = Delimiter character:
preferences.ignoreEmptyLines = Ignore empty lines:
preferences.surroundingSpacesNeedQuotes = Surrounding spaces need quotes:
preferences.quoteMode = Quote mode:
preferences.fileEncoding = File encoding:
# validaton messages
validation.message.not.empty = should not be empty

View File

@@ -50,6 +50,7 @@ preferences.delimiterChar = Trennzeichen:
preferences.ignoreEmptyLines = Leere Zeilen ignorieren:
preferences.surroundingSpacesNeedQuotes = Leerzeichen einfassen:
preferences.quoteMode = Einfassungsmodus:
preferences.fileEncoding = Dateicodierung:
# validaton messages
validation.message.not.empty = Darf nicht leer sein.

View File

@@ -0,0 +1,56 @@
/*
The MIT License (MIT)
-----------------------------------------------------------------------------
Copyright (c) 2015-2016 javafx.ninja <info@javafx.ninja>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
package ninja.javafx.smartcsv.preferences;
import org.junit.jupiter.api.Test;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import static org.junit.jupiter.api.Assertions.*;
public class CharsetHelperTest {
@Test
public void getCharsetName_known_charset() {
String result = CharsetHelper.getCharsetName("UTF-16");
assertEquals(StandardCharsets.UTF_16.name(), result);
}
@Test
public void getCharsetName_unknown_charset() {
String result = CharsetHelper.getCharsetName("foobar");
assertEquals(StandardCharsets.UTF_8.name(), result);
}
@Test
public void getCharsetName_null_charset() {
String result = CharsetHelper.getCharsetName(null);
assertEquals(StandardCharsets.UTF_8.name(), result);
}
}