diff --git a/.classpath b/.classpath
index d67069e9013636f5559574bddc8949f675e64448..f23826173add7f3f88b8ef7616a953d76408e784 100644
--- a/.classpath
+++ b/.classpath
@@ -6,6 +6,7 @@
 			<attribute name="maven.pomderived" value="true"/>
 		</attributes>
 	</classpathentry>
+	<classpathentry kind="src" path="tests"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/_Tools"/>
 	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
 		<attributes>
@@ -13,5 +14,6 @@
 		</attributes>
 	</classpathentry>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
 	<classpathentry kind="output" path="target/classes"/>
 </classpath>
diff --git a/.gitignore b/.gitignore
index 1ea7cc20e495b881762a6ac791fbaf3e832c03ef..ba528a19ef3303cd80651c649f8f6fcedbeeb108 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,3 @@
 bin/
 target/
-certs/
-build/screenshots/
\ No newline at end of file
+certs/
\ No newline at end of file
diff --git a/build/BudgetMaster.exe b/build/BudgetMaster.exe
index 1615506ef0305ac54886c178beab441470a73f55..fb7db919eb7a0748bb8e951a1f063a0cce2e6635 100644
Binary files a/build/BudgetMaster.exe and b/build/BudgetMaster.exe differ
diff --git a/build/BudgetMasterClient.jar b/build/BudgetMasterClient.jar
index 9bfc74a6eabb8c5f49012f35e1ebb3efb152a04d..f389bc9c30fed034c82c2fab6bf1ec7f3be75758 100644
Binary files a/build/BudgetMasterClient.jar and b/build/BudgetMasterClient.jar differ
diff --git a/build/BudgetMasterServer.jar b/build/BudgetMasterServer.jar
index 19f220c3abad7970c1e5e5da95e622ac6799259b..73ae6603501f348f03888b3a177074cbbaace775 100644
Binary files a/build/BudgetMasterServer.jar and b/build/BudgetMasterServer.jar differ
diff --git a/build/screenshots/bearbeiten.png b/build/screenshots/bearbeiten.png
new file mode 100644
index 0000000000000000000000000000000000000000..afafb412113723381bc409673ee23ca626ffa9f1
Binary files /dev/null and b/build/screenshots/bearbeiten.png differ
diff --git a/build/screenshots/bericht_1.png b/build/screenshots/bericht_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..792a901381483fd3854599484169330a205da71e
Binary files /dev/null and b/build/screenshots/bericht_1.png differ
diff --git a/build/screenshots/bericht_2.png b/build/screenshots/bericht_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..05f4bfc097a1a669466b9666f8ccdfacb1e92448
Binary files /dev/null and b/build/screenshots/bericht_2.png differ
diff --git a/build/screenshots/buchungen.png b/build/screenshots/buchungen.png
new file mode 100644
index 0000000000000000000000000000000000000000..bfb50e226c3d0dc2090416d3a1a4961570b18182
Binary files /dev/null and b/build/screenshots/buchungen.png differ
diff --git a/build/screenshots/diagramme_1.png b/build/screenshots/diagramme_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..ef4b60804945102d1c4d36e431d0e24ccc6efbb1
Binary files /dev/null and b/build/screenshots/diagramme_1.png differ
diff --git a/build/screenshots/diagramme_2.png b/build/screenshots/diagramme_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..1b971d02dbf81181d3c87d757f8df52923fd06b8
Binary files /dev/null and b/build/screenshots/diagramme_2.png differ
diff --git a/build/screenshots/diagramme_3.png b/build/screenshots/diagramme_3.png
new file mode 100644
index 0000000000000000000000000000000000000000..2054ec5ffa5ca6b5e617092ea6788325b9cad9ef
Binary files /dev/null and b/build/screenshots/diagramme_3.png differ
diff --git a/build/screenshots/einstellungen.png b/build/screenshots/einstellungen.png
new file mode 100644
index 0000000000000000000000000000000000000000..a5ba126f7735637eaa591752aad52a47ac8ae725
Binary files /dev/null and b/build/screenshots/einstellungen.png differ
diff --git a/build/screenshots/filter.png b/build/screenshots/filter.png
new file mode 100644
index 0000000000000000000000000000000000000000..03fcb7deb011302577dfa735d88c874ede461c60
Binary files /dev/null and b/build/screenshots/filter.png differ
diff --git a/build/screenshots/kategorien.png b/build/screenshots/kategorien.png
new file mode 100644
index 0000000000000000000000000000000000000000..522ecf1ac189f72fdb6366e728077a3f82611eb5
Binary files /dev/null and b/build/screenshots/kategorien.png differ
diff --git a/build/screenshots/normal.png b/build/screenshots/normal.png
new file mode 100644
index 0000000000000000000000000000000000000000..c2a984eb78f0dc38d33336780c75362bdf8f3ba3
Binary files /dev/null and b/build/screenshots/normal.png differ
diff --git a/build/screenshots/overbudget.png b/build/screenshots/overbudget.png
new file mode 100644
index 0000000000000000000000000000000000000000..a9bed0d49de77e4ea2c7941fc0761838d8b96c37
Binary files /dev/null and b/build/screenshots/overbudget.png differ
diff --git a/pom.xml b/pom.xml
index 7171a69f22bd6570cca29fa865ec5ae5357aa52d..fee0e286908f96732d52fe82567d1d3f4891e761 100644
--- a/pom.xml
+++ b/pom.xml
@@ -57,5 +57,10 @@
     	<artifactId>joda-time</artifactId>
     	<version>2.9.7</version>
 	</dependency>
+	<dependency>
+	    <groupId>com.itextpdf</groupId>
+	    <artifactId>itextpdf</artifactId>
+    	<version>5.0.6</version>
+	</dependency>
   </dependencies>
 </project>
\ No newline at end of file
diff --git a/settings.json b/settings.json
index b60e9bf038beddea9fb9d43d3543ffa1c2f56898..359fd4076b45a92599d74e446d3aa47a4be9578d 100644
--- a/settings.json
+++ b/settings.json
@@ -5,6 +5,6 @@
 	"databasePassword": "",
 	"serverPort": 9000,
 	"serverSecret": "geheim",
-	"keystorePath": "",
+	"keystorePath": "C:/Programmierung/eclipse/workspace/BudgetMaster/certs/keystore.jks",
 	"keystorePassword": "geheim"
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/Helpers.java b/src/de/deadlocker8/budgetmaster/logic/Helpers.java
deleted file mode 100644
index 9190df3577db8a5f28558da7a167bc9e24489ed6..0000000000000000000000000000000000000000
--- a/src/de/deadlocker8/budgetmaster/logic/Helpers.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package de.deadlocker8.budgetmaster.logic;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.text.DecimalFormat;
-import java.time.LocalDate;
-import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-
-public class Helpers
-{
-	public static final DecimalFormat NUMBER_FORMAT = new DecimalFormat("0.00");
-	
-	public static final String COLOR_INCOME = "#22BAD9";
-	public static final String COLOR_PAYMENT = "#F2612D";
-	public static final String SALT = "ny9/Y+G|WrJ,82|oIYQQ X %i-sq#4,uA-qKPtwFPnw+s(k2`rV)^-a1|t{D3Z>S";
-
-	public static String getURLEncodedString(String input)
-	{
-		try
-		{
-			return URLEncoder.encode(input, "UTF-8");
-		}
-		catch(UnsupportedEncodingException e)
-		{
-			return input;
-		}
-	}
-
-	public static String getDateString(LocalDate date)
-	{
-		if(date == null)
-		{
-			return "";
-		}
-		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-		return date.format(formatter);
-	}
-
-	public static ArrayList<String> getMonthList()
-	{
-		ArrayList<String> monthNames = new ArrayList<>();
-		monthNames.add("Januar");
-		monthNames.add("Februar");
-		monthNames.add("März");
-		monthNames.add("April");
-		monthNames.add("Mai");
-		monthNames.add("Juni");
-		monthNames.add("Juli");
-		monthNames.add("August");
-		monthNames.add("September");
-		monthNames.add("Oktober");
-		monthNames.add("November");
-		monthNames.add("Dezember");
-		return monthNames;
-	}
-
-	public static ArrayList<String> getYearList()
-	{
-		ArrayList<String> years = new ArrayList<>();
-		for(int i = 2000; i < 2100; i++)
-		{
-			years.add(String.valueOf(i));
-		}
-		return years;
-	}
-}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/Settings.java b/src/de/deadlocker8/budgetmaster/logic/Settings.java
index f95ce96203ee507679c9ffb83ebc92efee79183a..0a633663eefc9316b73cdcdea657d440a85dff0b 100644
--- a/src/de/deadlocker8/budgetmaster/logic/Settings.java
+++ b/src/de/deadlocker8/budgetmaster/logic/Settings.java
@@ -4,6 +4,7 @@ import java.util.ArrayList;
 
 public class Settings
 {
+	private String clientSecret;
 	private String url;
 	private String secret;
 	private String currency;
@@ -13,8 +14,18 @@ public class Settings
 	public Settings()
 	{
 		
+	}	
+
+	public String getClientSecret()
+	{
+		return clientSecret;
 	}
 
+	public void setClientSecret(String clientPassword)
+	{
+		this.clientSecret = clientPassword;
+	}
+	
 	public String getUrl()
 	{
 		return url;
@@ -64,10 +75,22 @@ public class Settings
 	{
 		this.trustedHosts = trustedHosts;
 	}
+	
+	public boolean isComplete()
+	{
+		if(url == null)
+			return false;
+		if(secret == null)
+			return false;
+		if(currency == null)
+			return false;
+		
+		return true;
+	}
 
 	@Override
 	public String toString()
 	{
-		return "Settings [url=" + url + ", secret=" + secret + ", currency=" + currency + ", restActivated=" + restActivated + ", trustedHosts=" + trustedHosts + "]";
+		return "Settings [clientSecret=" + clientSecret + ", url=" + url + ", secret=" + secret + ", currency=" + currency + ", restActivated=" + restActivated + ", trustedHosts=" + trustedHosts + "]";
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/BarChartGenerator.java b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/BarChartGenerator.java
deleted file mode 100644
index c3276887a3f8d70f7770ac4acf9f0b54c1e0fcb3..0000000000000000000000000000000000000000
--- a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/BarChartGenerator.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package de.deadlocker8.budgetmaster.logic.chartGenerators;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Set;
-
-import de.deadlocker8.budgetmaster.logic.Helpers;
-import de.deadlocker8.budgetmaster.logic.MonthInOutSum;
-import javafx.event.EventHandler;
-import javafx.geometry.Point2D;
-import javafx.scene.Node;
-import javafx.scene.chart.BarChart;
-import javafx.scene.chart.CategoryAxis;
-import javafx.scene.chart.NumberAxis;
-import javafx.scene.chart.XYChart;
-import javafx.scene.control.Label;
-import javafx.scene.control.Tooltip;
-import javafx.scene.input.MouseEvent;
-
-@Deprecated
-public class BarChartGenerator
-{
-	private ArrayList<MonthInOutSum> monthInOutSums;
-	private String currency;
-
-	public BarChartGenerator(ArrayList<MonthInOutSum> monthInOutSums, String currency)
-	{
-		this.monthInOutSums = monthInOutSums;
-		this.currency = currency;
-	}
-
-	public BarChart<String, Number> generate()
-	{
-		final CategoryAxis xAxis = new CategoryAxis();
-		final NumberAxis yAxis = new NumberAxis();
-		final BarChart<String, Number> generatedChart = new BarChart<>(xAxis, yAxis);
-		generatedChart.setTitle(null);
-
-		xAxis.setLabel("");
-		yAxis.setLabel("Summe in " + currency);
-
-		XYChart.Series<String, Number> seriesIN = new XYChart.Series<String, Number>();
-		seriesIN.setName("Einnahmen");
-		XYChart.Series<String, Number> seriesOUT = new XYChart.Series<String, Number>();
-		seriesOUT.setName("Ausgaben");
-
-		for(MonthInOutSum currentItem : monthInOutSums)
-		{
-			String label = currentItem.getDate().toString("MMMM YY");
-
-			seriesIN.getData().add(new XYChart.Data<String, Number>(label, currentItem.getBudgetIN()/100.0));
-			seriesOUT.getData().add(new XYChart.Data<String, Number>(label, currentItem.getBudgetOUT()/100.0));
-		}
-
-		generatedChart.getData().add(seriesIN);
-		generatedChart.getData().add(seriesOUT);
-
-		generatedChart.setLegendVisible(true);
-		
-		// add tooltip to every segment
-		generatedChart.getData().stream().forEach(tool -> {
-			for(XYChart.Data<String, Number> data : tool.getData())
-			{
-				Tooltip tooltip = new Tooltip();
-
-				tooltip.setText(Helpers.NUMBER_FORMAT.format(data.getYValue()).replace(".", ",") + currency);
-				Tooltip.install(tool.getNode(), tooltip);
-				Node node = data.getNode();
-				node.setOnMouseEntered(new EventHandler<MouseEvent>()
-				{
-					@Override
-					public void handle(MouseEvent event)
-					{
-						Point2D p = node.localToScreen(event.getX() + 5, event.getY() + 7);
-						tooltip.show(node, p.getX(), p.getY());
-					}
-				});
-				node.setOnMouseExited(new EventHandler<MouseEvent>()
-				{
-
-					@Override
-					public void handle(MouseEvent event)
-					{
-						tooltip.hide();
-					}
-				});
-			}
-		});
-		
-		// style bar for incomes
-		for(Node n : generatedChart.lookupAll(".default-color0.chart-bar"))
-		{
-			n.setStyle("-fx-bar-fill: " + Helpers.COLOR_INCOME + ";");
-		}		
-		
-		// style bar for payments
-		for(Node n : generatedChart.lookupAll(".default-color1.chart-bar"))
-		{
-			n.setStyle("-fx-bar-fill: " + Helpers.COLOR_PAYMENT + ";");
-		}
-		
-		 //style legend item according to color
-		Set<Node> nodes = generatedChart.lookupAll(".chart-legend-item");
-		if(nodes.size() > 0)
-		{        	
-			Iterator<Node> iterator = nodes.iterator();
-			int counter = 0;
-			while(iterator.hasNext())
-			{
-    			Node node = iterator.next();	        			
-    			if(node instanceof Label)
-    			{
-    				Label labelLegendItem = (Label)node;     
-    				if(counter == 0)
-    				{
-    					labelLegendItem.getGraphic().setStyle("-fx-background-color: " + Helpers.COLOR_INCOME + ";");
-    				}
-    				else
-    				{
-    					labelLegendItem.getGraphic().setStyle("-fx-background-color: " + Helpers.COLOR_PAYMENT + ";");
-    				}
-    			}
-    			counter++;
-			}
-		}
-
-		return generatedChart;
-	}
-}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/CategoriesChartGenerator.java b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/CategoriesChartGenerator.java
deleted file mode 100644
index 77efcd715afaed985db53c936ea3e37041b3d6fc..0000000000000000000000000000000000000000
--- a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/CategoriesChartGenerator.java
+++ /dev/null
@@ -1,154 +0,0 @@
-package de.deadlocker8.budgetmaster.logic.chartGenerators;
-
-import java.util.ArrayList;
-
-import de.deadlocker8.budgetmaster.logic.CategoryInOutSum;
-import de.deadlocker8.budgetmaster.logic.Helpers;
-import javafx.geometry.Insets;
-import javafx.geometry.Pos;
-import javafx.scene.control.Label;
-import javafx.scene.control.Tooltip;
-import javafx.scene.layout.GridPane;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.VBox;
-import javafx.scene.paint.Color;
-import tools.ConvertTo;
-
-public class CategoriesChartGenerator
-{
-	private String title;
-	private ArrayList<CategoryInOutSum> categoryInOutSums;
-	private boolean useBudgetIN;
-	private String currency;
-	private double total;
-
-	public CategoriesChartGenerator(String title, ArrayList<CategoryInOutSum> categoryInOutSums, boolean useBudgetIN, String currency)
-	{
-		this.title = title;
-		if(categoryInOutSums == null)
-		{
-			this.categoryInOutSums = new ArrayList<>();
-		}
-		else
-		{
-			this.categoryInOutSums = categoryInOutSums;
-		}		
-		this.useBudgetIN = useBudgetIN;
-		this.currency = currency;
-		this.total = getTotal(this.categoryInOutSums, useBudgetIN);
-	}	
-
-	public VBox generate()
-	{
-		VBox generatedChart = new VBox();
-		HBox chart = new HBox();
-		chart.setMinHeight(30);
-
-		Label labelTitle = new Label(title);
-		labelTitle.setStyle("-fx-font-size: 16; -fx-font-weight: bold;");
-		generatedChart.getChildren().add(labelTitle);
-		VBox.setMargin(labelTitle, new Insets(0, 0, 10, 0));
-
-		for(CategoryInOutSum currentItem : categoryInOutSums)
-		{
-			Label currentPart = new Label();
-			currentPart.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(currentItem.getColor()));
-			currentPart.prefHeightProperty().bind(chart.heightProperty());
-			chart.getChildren().add(currentPart);
-
-			double value;
-			if(useBudgetIN)
-			{
-				value = currentItem.getBudgetIN() / 100.0;
-			}
-			else
-			{
-				value = -currentItem.getBudgetOUT() / 100.0;
-			}
-
-			double percentage = value / total;
-
-			currentPart.prefWidthProperty().bind(chart.widthProperty().multiply(percentage));
-
-			Tooltip tooltip = new Tooltip();
-			tooltip.setText(currentItem.getName() + "\n" + Helpers.NUMBER_FORMAT.format(percentage*100) + " %\n" + Helpers.NUMBER_FORMAT.format(value).replace(".", ",") + currency);//
-			currentPart.setTooltip(tooltip);
-		}
-
-		generatedChart.getChildren().add(chart);
-
-		return generatedChart;
-	}
-
-	public GridPane generateLegend()
-	{
-		GridPane legend = new GridPane();
-		legend.setPadding(new Insets(10));
-		legend.setHgap(20);
-		legend.setVgap(10);
-		legend.setAlignment(Pos.CENTER);
-		legend.setStyle("-fx-background-color: #EEEEEE; -fx-border-color: #212121; -fx-border-width: 1; -fx-border-radius: 5;");
-
-		if(categoryInOutSums.size() == 0)
-		{
-			return legend;
-		}	
-		
-		ArrayList<HBox> legendItems = new ArrayList<>();
-		for(CategoryInOutSum currentItem : categoryInOutSums)
-		{
-			String label = currentItem.getName();
-			if(label.equals("NONE"))
-			{
-				label = "Keine Kategorie";
-			}
-			legendItems.add(getLegendItem(label, currentItem.getColor()));
-		}
-
-		int legendWidth = (int)Math.ceil(Math.sqrt(legendItems.size()));
-		
-		for(int i = 0; i < legendItems.size(); i++)
-		{
-			int columnIndex = i % legendWidth;
-			int rowIndex = i / 4;
-			legend.add(legendItems.get(i), columnIndex, rowIndex);
-		}
-
-		return legend;
-	}
-
-	private HBox getLegendItem(String name, Color color)
-	{
-		HBox legendItem = new HBox();
-		Label labelCircle = new Label();
-		labelCircle.setMinWidth(20);
-		labelCircle.setMinHeight(20);
-		labelCircle.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(color) + "; -fx-background-radius: 50%; -fx-border-width: 1; -fx-border-color: black - fx-border-radius: 50%");
-
-		Label labelText = new Label(name);
-		labelText.setStyle("-fx-font-weight: bold;");
-
-		legendItem.getChildren().add(labelCircle);
-		legendItem.getChildren().add(labelText);
-		HBox.setMargin(labelText, new Insets(0, 0, 0, 5));
-
-		return legendItem;
-	}
-
-	private double getTotal(ArrayList<CategoryInOutSum> categoryInOutSums, boolean useBudgetIN)
-	{		
-		double total = 0;
-		for(CategoryInOutSum currentItem : categoryInOutSums)
-		{
-			if(useBudgetIN)
-			{
-				total += currentItem.getBudgetIN() / 100.0;
-			}
-			else
-			{
-				total += -currentItem.getBudgetOUT() / 100.0;
-			}
-		}
-		return total;
-	}
-}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/PieChartGenerator.java b/src/de/deadlocker8/budgetmaster/logic/chartGenerators/PieChartGenerator.java
deleted file mode 100644
index 382d0a77dfede19bc254cfa0f3f40387c2af5c5f..0000000000000000000000000000000000000000
--- a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/PieChartGenerator.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package de.deadlocker8.budgetmaster.logic.chartGenerators;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Set;
-
-import de.deadlocker8.budgetmaster.logic.CategoryInOutSum;
-import de.deadlocker8.budgetmaster.logic.Helpers;
-import javafx.collections.FXCollections;
-import javafx.collections.ObservableList;
-import javafx.event.EventHandler;
-import javafx.geometry.Point2D;
-import javafx.scene.Node;
-import javafx.scene.chart.PieChart;
-import javafx.scene.control.Label;
-import javafx.scene.control.Tooltip;
-import javafx.scene.input.MouseEvent;
-import tools.ConvertTo;
-
-@Deprecated
-public class PieChartGenerator
-{
-    private String title;
-    private ArrayList<CategoryInOutSum> categoryInOutSums;
-    private boolean useBudgetIN;
-    private String currency;
-
-    public PieChartGenerator(String title, ArrayList<CategoryInOutSum> categoryInOutSums, boolean useBudgetIN, String currency)
-    {
-        this.title = title;
-        this.categoryInOutSums = categoryInOutSums;
-        this.useBudgetIN = useBudgetIN;
-        this.currency = currency;
-    }
-  
-    public PieChart generate()
-    {
-        ArrayList<PieChart.Data> data = new ArrayList<>();
-        
-        for(CategoryInOutSum currentItem : categoryInOutSums)
-        {        	
-        	String label = currentItem.getName(); 
-        	if(label.equals("NONE"))
-        	{
-        		label = "Keine Kategorie";
-        	}
-        	
-        	if(useBudgetIN)
-        	{
-        		data.add(new PieChart.Data(label, currentItem.getBudgetIN()/100.0));
-        	}
-        	else
-        	{
-        		data.add(new PieChart.Data(label, -currentItem.getBudgetOUT()/100.0));
-        	}
-        }
-        
-        ObservableList<PieChart.Data> pieChartData = FXCollections.observableArrayList(data);
-
-        final PieChart chart = new PieChart(pieChartData);
-        chart.setTitle(title);
-
-        //add tooltip to every segment that shows percentage as double value
-        chart.getData().stream().forEach(tool ->
-        {
-            Tooltip tooltip = new Tooltip();
-
-            double total = 0;
-            for(int i = 0; i < chart.getData().size(); i++)
-            {
-            	PieChart.Data currentData = chart.getData().get(i);
-                total += currentData.getPieValue();
-                String currentColor = ConvertTo.toRGBHexWithoutOpacity(categoryInOutSums.get(i).getColor());
-                currentData.getNode().setStyle("-fx-pie-color: " + currentColor + ";");
-            }    
-            
-            //style legend item according to color
-    		Set<Node> nodes = chart.lookupAll(".chart-legend-item");
-    		if(nodes.size() > 0)
-    		{        	
-    			Iterator<Node> iterator = nodes.iterator();
-    			int counter = 0;
-    			while(iterator.hasNext())
-    			{
-        			Node node = iterator.next();	        			
-        			if(node instanceof Label)
-        			{
-        				Label labelLegendItem = (Label)node;        				
-        				labelLegendItem.getGraphic().setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(categoryInOutSums.get(counter).getColor()) + ";");
-        			}
-        			counter++;
-    			}
-    		}
-
-            double pieValue = tool.getPieValue();
-            double percentage = (pieValue / total) * 100;
-            String percent = String.valueOf(percentage);
-            percent = percent.substring(0, percent.indexOf(".") + 2);
-
-            tooltip.setText(percent + " %\n" + Helpers.NUMBER_FORMAT.format(pieValue).replace(".", ",") + currency);
-            Tooltip.install(tool.getNode(), tooltip);
-            Node node = tool.getNode();
-            node.setOnMouseEntered(new EventHandler<MouseEvent>()
-            {
-                @Override
-                public void handle(MouseEvent event)
-                {
-                    Point2D p = node.localToScreen(event.getX() + 5, event.getY() + 7);
-                    tooltip.show(node, p.getX(), p.getY());
-                }
-            });
-            node.setOnMouseExited(new EventHandler<MouseEvent>()
-            {
-
-                @Override
-                public void handle(MouseEvent event)
-                {
-                    tooltip.hide();
-                }
-            });
-        });
-
-        return chart;
-    }
-}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/charts/CategoriesChart.java b/src/de/deadlocker8/budgetmaster/logic/charts/CategoriesChart.java
new file mode 100644
index 0000000000000000000000000000000000000000..37c153d1a0d288ea42667e610b50dee9864f58c0
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/charts/CategoriesChart.java
@@ -0,0 +1,334 @@
+package de.deadlocker8.budgetmaster.logic.charts;
+
+import java.util.ArrayList;
+
+import de.deadlocker8.budgetmaster.logic.CategoryInOutSum;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Scene;
+import javafx.scene.SnapshotParameters;
+import javafx.scene.control.Label;
+import javafx.scene.control.Tooltip;
+import javafx.scene.image.WritableImage;
+import javafx.scene.layout.GridPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.Region;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javafx.scene.transform.Transform;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import tools.ConvertTo;
+
+public class CategoriesChart extends VBox implements ChartExportable
+{
+	private String titleIncomes;
+	private String titlePayments;
+	private ArrayList<CategoryInOutSum> categoryInOutSums;
+	private String currency;
+	private double totalIncomes;
+	private double totalPayments;
+	private LegendType legendType;
+	
+
+	public CategoriesChart(String titleIncomes, String titlePayments, ArrayList<CategoryInOutSum> categoryInOutSums, String currency, LegendType legendType)
+	{
+		this.titleIncomes = titleIncomes;
+		this.titlePayments = titlePayments;
+		if(categoryInOutSums == null)
+		{
+			this.categoryInOutSums = new ArrayList<>();
+		}
+		else
+		{
+			this.categoryInOutSums = categoryInOutSums;
+		}
+		
+		this.currency = currency;
+		this.totalIncomes = getTotal(this.categoryInOutSums, true);
+		this.totalPayments = getTotal(categoryInOutSums, false);
+		this.legendType = legendType;
+		
+		this.setSpacing(10);
+		
+		this.getChildren().add(generate(titleIncomes, true));
+		this.getChildren().add(generate(titlePayments, false));
+		
+		Region spacer = new Region();
+		this.getChildren().add(spacer);
+		VBox.setVgrow(spacer, Priority.ALWAYS);
+		
+		if(this.legendType == LegendType.NORMAL)
+		{
+			this.getChildren().add(generateLegend());
+		}
+		else if(this.legendType == LegendType.FULL)
+		{
+			this.getChildren().add(generateFullLegend());		
+		}
+	}	
+
+	private VBox generate(String title, boolean useIncomes)
+	{
+		VBox generatedChart = new VBox();
+		HBox chart = new HBox();
+		chart.setMinHeight(50);
+
+		Label labelTitle = new Label(title);
+		labelTitle.setStyle("-fx-font-size: 16; -fx-font-weight: bold;");
+		generatedChart.getChildren().add(labelTitle);
+		VBox.setMargin(labelTitle, new Insets(0, 0, 10, 0));
+
+		for(CategoryInOutSum currentItem : categoryInOutSums)
+		{
+			Label currentPart = new Label();
+			currentPart.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(currentItem.getColor()));
+			currentPart.prefHeightProperty().bind(chart.heightProperty());
+			chart.getChildren().add(currentPart);
+
+			double value;
+			double percentage;
+			if(useIncomes)
+			{
+				value = currentItem.getBudgetIN() / 100.0;
+				percentage = value / totalIncomes;
+			}
+			else
+			{
+				value = -currentItem.getBudgetOUT() / 100.0;
+				percentage = value / totalPayments;
+			}
+
+			currentPart.prefWidthProperty().bind(chart.widthProperty().multiply(percentage));
+			
+			String categoryName = currentItem.getName();
+			if(categoryName.equals("NONE"))
+			{
+				categoryName = "Keine Kategorie";
+			}
+			
+			Tooltip tooltip = new Tooltip();
+			tooltip.setText(categoryName + "\n" + Helpers.NUMBER_FORMAT.format(percentage*100) + " %\n" + Helpers.getCurrencyString(value, currency));//
+			currentPart.setTooltip(tooltip);
+		}
+
+		generatedChart.getChildren().add(chart);
+
+		return generatedChart;
+	}
+
+	private GridPane generateLegend()
+	{
+		GridPane legend = new GridPane();
+		legend.setPadding(new Insets(10));
+		legend.setHgap(20);
+		legend.setVgap(10);
+		legend.setAlignment(Pos.CENTER);
+		legend.setStyle("-fx-background-color: #EEEEEE; -fx-border-color: #212121; -fx-border-width: 1; -fx-border-radius: 5;");
+
+		if(categoryInOutSums.size() == 0)
+		{
+			return legend;
+		}	
+		
+		ArrayList<HBox> legendItems = new ArrayList<>();
+		for(CategoryInOutSum currentItem : categoryInOutSums)
+		{
+			String label = currentItem.getName();
+			if(label.equals("NONE"))
+			{
+				label = "Keine Kategorie";
+			}
+			legendItems.add(getLegendItem(label, currentItem.getColor()));
+		}
+
+		int legendWidth;
+		int numberOfItems = legendItems.size();
+		if(numberOfItems <= 3)
+		{
+			legendWidth = numberOfItems;
+		}
+		else
+		{
+			legendWidth = (int)Math.ceil(Math.sqrt(numberOfItems));
+		}
+		
+		for(int i = 0; i < numberOfItems; i++)
+		{
+			int columnIndex = i % legendWidth;
+			int rowIndex = i / legendWidth;			
+			legend.add(legendItems.get(i), columnIndex, rowIndex);
+		}
+
+		return legend;
+	}
+	
+	private VBox generateFullLegend()
+	{
+		VBox legend = new VBox();
+		legend.setPadding(new Insets(10));
+		legend.setSpacing(10);
+		legend.setStyle("-fx-background-color: #EEEEEE; -fx-border-color: #212121; -fx-border-width: 1; -fx-border-radius: 5;");
+
+		if(categoryInOutSums.size() == 0)
+		{
+			return legend;
+		}
+		
+		double totalIn = getTotal(categoryInOutSums, true);
+		double totalOut = getTotal(categoryInOutSums, false);
+				
+		HBox hboxLegend = new HBox();
+		hboxLegend.setSpacing(10);
+
+		VBox vboxCircles = new VBox();
+		vboxCircles.setSpacing(10);	
+		VBox vboxNames = new VBox();
+		vboxNames.setSpacing(10);
+		VBox vboxIn = new VBox();
+		vboxIn.setSpacing(10);
+		VBox vboxOut = new VBox();
+		vboxOut.setSpacing(10);
+		
+		Label labelHeaderSpacer = new Label();
+		labelHeaderSpacer.setMinWidth(20);
+		labelHeaderSpacer.setMinHeight(20);
+		vboxCircles.getChildren().add(labelHeaderSpacer);
+		
+		Label labelHeaderName = new Label("Kategorie");
+		labelHeaderName.setStyle("-fx-font-weight: bold; -fx-underline: true;");
+		labelHeaderName.setMinHeight(20);
+		vboxNames.getChildren().add(labelHeaderName);	
+		
+		Label labelHeaderIn = new Label("Einnahmen");
+		labelHeaderIn.setStyle("-fx-font-weight: bold; -fx-underline: true;");
+		labelHeaderIn.setMinHeight(20);
+		vboxIn.getChildren().add(labelHeaderIn);		
+		
+		Label labelHeaderOut = new Label("Ausgaben");
+		labelHeaderOut.setStyle("-fx-font-weight: bold; -fx-underline: true;");
+		labelHeaderOut.setMinHeight(20);
+		vboxOut.getChildren().add(labelHeaderOut);		
+		
+		for(CategoryInOutSum currentItem : categoryInOutSums)
+		{
+			String name = currentItem.getName();
+			if(name.equals("NONE"))
+			{
+				name = "Keine Kategorie";
+			}
+			
+			Label labelCircle = new Label();
+			labelCircle.setMinWidth(20);
+			labelCircle.setMinHeight(20);
+			labelCircle.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(currentItem.getColor()) + "; -fx-background-radius: 50%; -fx-border-width: 1; -fx-border-color: black - fx-border-radius: 50%");
+			vboxCircles.getChildren().add(labelCircle);
+
+			Label labelName = new Label(name);
+			labelName.setStyle("-fx-font-weight: bold;");
+			labelName.setMinHeight(20);
+			vboxNames.getChildren().add(labelName);
+			
+			String percentageIn = Helpers.NUMBER_FORMAT.format((currentItem.getBudgetIN() / totalIn));
+			Label labelInSum = new Label("+" + Helpers.getCurrencyString(currentItem.getBudgetIN(), currency) + " (" + percentageIn + "%)");
+			labelInSum.setStyle("-fx-font-weight: bold;");
+			labelInSum.setMinHeight(20);
+			vboxIn.getChildren().add(labelInSum);
+			
+			String percentageOut = Helpers.NUMBER_FORMAT.format((currentItem.getBudgetOUT() / totalOut));
+			Label labelOutSum = new Label(Helpers.getCurrencyString(currentItem.getBudgetOUT(), currency) + " (" + percentageOut + "%)");
+			labelOutSum.setStyle("-fx-font-weight: bold;");
+			labelOutSum.setMinHeight(20);
+			vboxOut.getChildren().add(labelOutSum);
+		}
+		
+		hboxLegend.getChildren().add(vboxCircles);
+		hboxLegend.getChildren().add(vboxNames);
+		HBox.setHgrow(vboxNames, Priority.ALWAYS);
+		hboxLegend.getChildren().add(vboxIn);
+		HBox.setHgrow(vboxIn, Priority.ALWAYS);
+		hboxLegend.getChildren().add(vboxOut);
+		HBox.setHgrow(vboxOut, Priority.ALWAYS);			
+		legend.getChildren().add(hboxLegend);		
+		
+		return legend;
+	}
+
+	private HBox getLegendItem(String name, Color color)
+	{
+		HBox legendItem = new HBox();
+		Label labelCircle = new Label();
+		labelCircle.setMinWidth(20);
+		labelCircle.setMinHeight(20);
+		labelCircle.setStyle("-fx-background-color: " + ConvertTo.toRGBHexWithoutOpacity(color) + "; -fx-background-radius: 50%; -fx-border-width: 1; -fx-border-color: black - fx-border-radius: 50%");
+
+		Label labelText = new Label(name);
+		labelText.setStyle("-fx-font-weight: bold;");
+
+		legendItem.getChildren().add(labelCircle);
+		legendItem.getChildren().add(labelText);
+		HBox.setMargin(labelText, new Insets(0, 0, 0, 5));
+
+		return legendItem;
+	}
+
+	private double getTotal(ArrayList<CategoryInOutSum> categoryInOutSums, boolean useIncomes)
+	{		
+		double total = 0;
+		for(CategoryInOutSum currentItem : categoryInOutSums)
+		{
+			if(useIncomes)
+			{
+				total += currentItem.getBudgetIN() / 100.0;
+			}
+			else
+			{
+				total += -currentItem.getBudgetOUT() / 100.0;
+			}
+		}
+		return total;
+	}
+
+	@Override
+	public WritableImage export(int width, int height)
+	{
+		VBox root = new VBox();
+		root.setStyle("-fx-background-color: transparent;");
+		root.setPadding(new Insets(25));
+		
+		root.getChildren().add(generate(titleIncomes, true));
+		root.getChildren().add(generate(titlePayments, false));
+		
+		Region spacer = new Region();
+		root.getChildren().add(spacer);
+		VBox.setVgrow(spacer, Priority.ALWAYS);
+		
+		root.getChildren().add(generateFullLegend());		
+		
+		Stage newStage = new Stage();
+		newStage.initModality(Modality.NONE);
+		newStage.setScene(new Scene(root, width, height));
+		newStage.setResizable(false);		
+		newStage.show();
+		
+		SnapshotParameters sp = new SnapshotParameters();
+		sp.setTransform(Transform.scale(width / root.getWidth(), height / root.getHeight()));
+		newStage.close();
+		
+		return root.snapshot(sp, null);
+	}
+	
+	@Override
+	public double getSuggestedWidth()
+	{
+		return getWidth() + 50;
+	}
+
+	@Override
+	public double getSuggestedHeight()
+	{
+		return getHeight() + 100;
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/charts/ChartExportable.java b/src/de/deadlocker8/budgetmaster/logic/charts/ChartExportable.java
new file mode 100644
index 0000000000000000000000000000000000000000..d5516e19c0d8e96c4c32e025251938c566a0e3c2
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/charts/ChartExportable.java
@@ -0,0 +1,16 @@
+package de.deadlocker8.budgetmaster.logic.charts;
+
+import javafx.scene.image.WritableImage;
+
+public interface ChartExportable
+{
+	WritableImage export(int width, int height);
+	
+	double getWidth();
+	
+	double getHeight();
+	
+	double getSuggestedWidth();
+	
+	double getSuggestedHeight();
+}
diff --git a/src/de/deadlocker8/budgetmaster/logic/charts/LegendType.java b/src/de/deadlocker8/budgetmaster/logic/charts/LegendType.java
new file mode 100644
index 0000000000000000000000000000000000000000..d9f8e6a41912883961dcfc25fc07a0739b236ff1
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/charts/LegendType.java
@@ -0,0 +1,6 @@
+package de.deadlocker8.budgetmaster.logic.charts;
+
+public enum LegendType
+{
+	NONE, NORMAL, FULL;
+}
diff --git a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/MonthChartGenerator.java b/src/de/deadlocker8/budgetmaster/logic/charts/MonthBarChart.java
similarity index 59%
rename from src/de/deadlocker8/budgetmaster/logic/chartGenerators/MonthChartGenerator.java
rename to src/de/deadlocker8/budgetmaster/logic/charts/MonthBarChart.java
index 35ae4150cb591b96c5bab30029a588107b5f55d3..6251812423272a5e189beb9be99c40f92dcb19d3 100644
--- a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/MonthChartGenerator.java
+++ b/src/de/deadlocker8/budgetmaster/logic/charts/MonthBarChart.java
@@ -1,30 +1,40 @@
-package de.deadlocker8.budgetmaster.logic.chartGenerators;
+package de.deadlocker8.budgetmaster.logic.charts;
 
 import java.util.ArrayList;
 
 import de.deadlocker8.budgetmaster.logic.CategoryInOutSum;
-import de.deadlocker8.budgetmaster.logic.Helpers;
 import de.deadlocker8.budgetmaster.logic.MonthInOutSum;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
 import javafx.geometry.Insets;
 import javafx.geometry.Orientation;
 import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.SnapshotParameters;
 import javafx.scene.control.Label;
+import javafx.scene.control.ScrollPane;
+import javafx.scene.control.ScrollPane.ScrollBarPolicy;
 import javafx.scene.control.Separator;
 import javafx.scene.control.Tooltip;
+import javafx.scene.image.WritableImage;
 import javafx.scene.layout.GridPane;
 import javafx.scene.layout.HBox;
 import javafx.scene.layout.Priority;
+import javafx.scene.layout.Region;
 import javafx.scene.layout.VBox;
 import javafx.scene.paint.Color;
 import javafx.scene.text.TextAlignment;
+import javafx.scene.transform.Transform;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
 import tools.ConvertTo;
 
-public class MonthChartGenerator
+public class MonthBarChart extends VBox implements ChartExportable
 {
 	private ArrayList<MonthInOutSum> monthInOutSums;
 	private String currency;
 
-	public MonthChartGenerator(ArrayList<MonthInOutSum> monthInOutSums, String currency)
+	public MonthBarChart(ArrayList<MonthInOutSum> monthInOutSums, String currency)
 	{
 		if(monthInOutSums == null)
 		{
@@ -34,10 +44,24 @@ public class MonthChartGenerator
 		{
 			this.monthInOutSums = monthInOutSums;
 		}
-		this.currency = currency;
+		this.currency = currency;	
+		
+		ScrollPane scrollPane = new ScrollPane();
+        scrollPane.setVbarPolicy(ScrollBarPolicy.NEVER);
+        scrollPane.setFocusTraversable(false);
+        scrollPane.setStyle("-fx-background-color: transparent; -fx-background-insets: 0; -fx-border-color: transparent; -fx-border-width: 0; -fx-border-insets: 0;");
+        scrollPane.setPadding(new Insets(0, 0, 10, 0));
+       
+        HBox generatedChart = generate();              
+        scrollPane.setContent(generatedChart);
+        generatedChart.prefHeightProperty().bind(scrollPane.heightProperty().subtract(30));
+        this.getChildren().add(scrollPane);
+        VBox.setVgrow(scrollPane, Priority.ALWAYS);
+        
+        this.getChildren().add(generateLegend());
 	}
 
-	public HBox generate()
+	private HBox generate()
 	{
 		HBox generatedChart = new HBox();
 		generatedChart.setAlignment(Pos.TOP_CENTER);
@@ -78,8 +102,9 @@ public class MonthChartGenerator
 
 	private VBox generateChart(ArrayList<CategoryInOutSum> categoryInOutSums, double total, boolean useBudgetIN)
 	{
-		VBox result = new VBox();									
-		Label labelAmount = new Label(Helpers.NUMBER_FORMAT.format(getTotal(categoryInOutSums, useBudgetIN)).replace(".", ",") + currency);
+		VBox result = new VBox();		
+		
+		Label labelAmount = new Label(Helpers.getCurrencyString(getTotal(categoryInOutSums, useBudgetIN), currency));
 		labelAmount.setStyle("-fx-font-size: 12; -fx-font-weight: bold;");
 		result.getChildren().add(labelAmount);
 		VBox.setMargin(labelAmount, new Insets(0, 0, 10, 0));
@@ -109,8 +134,14 @@ public class MonthChartGenerator
 			currentPart.setMinHeight(0);
 			currentPart.prefHeightProperty().bind(chart.heightProperty().multiply(percentage));	
 
+			String categoryName = currentItem.getName();
+			if(categoryName.equals("NONE"))
+			{
+				categoryName = "Keine Kategorie";
+			}
+			
 			Tooltip tooltip = new Tooltip();
-			tooltip.setText(currentItem.getName() + "\n"+ Helpers.NUMBER_FORMAT.format(percentage * 100) + " %\n" + Helpers.NUMBER_FORMAT.format(value).replace(".", ",") + currency);//
+			tooltip.setText(categoryName + "\n"+ Helpers.NUMBER_FORMAT.format(percentage * 100) + " %\n" + Helpers.NUMBER_FORMAT.format(value).replace(".", ",") + currency);//
 			currentPart.setTooltip(tooltip);
 		}
 
@@ -120,7 +151,7 @@ public class MonthChartGenerator
 		return result;
 	}
 
-	public GridPane generateLegend()
+	private GridPane generateLegend()
 	{
 		GridPane legend = new GridPane();
 		legend.setPadding(new Insets(10));
@@ -145,12 +176,21 @@ public class MonthChartGenerator
 			legendItems.add(getLegendItem(label, currentItem.getColor()));
 		}
 
-		int legendWidth = (int)Math.ceil(Math.sqrt(legendItems.size()));		
-
-		for(int i = 0; i < legendItems.size(); i++)
+		int legendWidth;
+		int numberOfItems = legendItems.size();
+		if(numberOfItems <= 3)
+		{
+			legendWidth = numberOfItems;
+		}
+		else
+		{
+			legendWidth = (int)Math.ceil(Math.sqrt(numberOfItems));
+		}
+		
+		for(int i = 0; i < numberOfItems; i++)
 		{
 			int columnIndex = i % legendWidth;
-			int rowIndex = i / 4;
+			int rowIndex = i / legendWidth;			
 			legend.add(legendItems.get(i), columnIndex, rowIndex);
 		}
 
@@ -209,4 +249,65 @@ public class MonthChartGenerator
 		}
 		return maximum / 100.0;
 	}
+
+    @Override
+    public WritableImage export(int width, int height) 
+    {
+        VBox root = new VBox();
+        root.setStyle("-fx-background-color: transparent;");
+        root.setPadding(new Insets(25));
+        
+        HBox generatedChart = generate();
+        root.getChildren().add(generatedChart);        
+        VBox.setVgrow(generatedChart, Priority.ALWAYS);
+        
+        Region spacer = new Region();
+        spacer.setMinHeight(30);
+		root.getChildren().add(spacer);
+        
+        root.getChildren().add(generateLegend());       
+        
+        Stage newStage = new Stage();
+        newStage.initModality(Modality.NONE);
+        newStage.setScene(new Scene(root, width, height));
+        newStage.setResizable(false);       
+        newStage.show();
+        
+        SnapshotParameters sp = new SnapshotParameters();
+        sp.setTransform(Transform.scale(width / root.getWidth(), height / root.getHeight()));
+        newStage.close();
+        
+        return root.snapshot(sp, null);
+    }
+    
+    @Override
+	public double getSuggestedWidth()
+	{
+    	if(this.getChildren().size() < 2)
+    	{
+    		return 0;
+    	}
+    	
+    	Node currentNode = this.getChildren().get(0);
+    	
+    	if(!(currentNode instanceof ScrollPane))
+    	{
+    		return 0;
+    	}
+    	
+    	ScrollPane scrollPane = (ScrollPane)currentNode; 
+    	Node content = scrollPane.getContent();
+    	if(content == null)
+    	{
+    		return 0;
+    	}    	
+    	
+    	return ((Region)content).getWidth() + 50;
+	}
+
+	@Override
+	public double getSuggestedHeight()
+	{
+		return getHeight() + 50;
+	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/LineChartGenerator.java b/src/de/deadlocker8/budgetmaster/logic/charts/MonthLineChart.java
similarity index 68%
rename from src/de/deadlocker8/budgetmaster/logic/chartGenerators/LineChartGenerator.java
rename to src/de/deadlocker8/budgetmaster/logic/charts/MonthLineChart.java
index 8888a5bd140f83f962677215f344645f5326de5f..af5152f69354a666eb8f4993bf29bddbbff8a88e 100644
--- a/src/de/deadlocker8/budgetmaster/logic/chartGenerators/LineChartGenerator.java
+++ b/src/de/deadlocker8/budgetmaster/logic/charts/MonthLineChart.java
@@ -1,39 +1,51 @@
-package de.deadlocker8.budgetmaster.logic.chartGenerators;
+package de.deadlocker8.budgetmaster.logic.charts;
 
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.Set;
 
-import de.deadlocker8.budgetmaster.logic.Helpers;
 import de.deadlocker8.budgetmaster.logic.MonthInOutSum;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
 import javafx.event.EventHandler;
+import javafx.geometry.Insets;
 import javafx.geometry.Point2D;
 import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.SnapshotParameters;
 import javafx.scene.chart.CategoryAxis;
 import javafx.scene.chart.LineChart;
 import javafx.scene.chart.NumberAxis;
 import javafx.scene.chart.XYChart;
 import javafx.scene.control.Label;
 import javafx.scene.control.Tooltip;
+import javafx.scene.image.WritableImage;
 import javafx.scene.input.MouseEvent;
+import javafx.scene.layout.VBox;
+import javafx.scene.transform.Transform;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
 
-public class LineChartGenerator
+public class MonthLineChart extends VBox implements ChartExportable
 {
 	private ArrayList<MonthInOutSum> monthInOutSums;
 	private String currency;
 
-	public LineChartGenerator(ArrayList<MonthInOutSum> monthInOutSums, String currency)
+	public MonthLineChart(ArrayList<MonthInOutSum> monthInOutSums, String currency)
 	{
 		this.monthInOutSums = monthInOutSums;
 		this.currency = currency;
+		
+		this.setSpacing(10);
+		this.getChildren().add(generate(true));
 	}
 
-	public LineChart<String, Number> generate()
+	private LineChart<String, Number> generate(boolean animated)
 	{
 		final CategoryAxis xAxis = new CategoryAxis();
 		final NumberAxis yAxis = new NumberAxis();
 		final LineChart<String, Number> generatedChart = new LineChart<>(xAxis, yAxis);
 		generatedChart.setTitle(null);
+		generatedChart.setAnimated(animated);
 
 		xAxis.setLabel("");
 		yAxis.setLabel("Summe in " + currency);
@@ -62,7 +74,7 @@ public class LineChartGenerator
 			{
 				Tooltip tooltip = new Tooltip();
 
-				tooltip.setText(Helpers.NUMBER_FORMAT.format(data.getYValue()).replace(".", ",") + currency);
+				tooltip.setText(Helpers.getCurrencyString(data.getYValue().doubleValue(), currency));
 				Tooltip.install(tool.getNode(), tooltip);
 				Node node = data.getNode();
 				node.setOnMouseEntered(new EventHandler<MouseEvent>()
@@ -136,4 +148,37 @@ public class LineChartGenerator
 
 		return generatedChart;
 	}
+
+    @Override
+    public WritableImage export(int width, int height) {
+        VBox root = new VBox();
+        root.setStyle("-fx-background-color: transparent;");
+        root.setPadding(new Insets(25));
+        
+        root.getChildren().add(generate(false));         
+        
+        Stage newStage = new Stage();
+        newStage.initModality(Modality.NONE);
+        newStage.setScene(new Scene(root, width, height));
+        newStage.setResizable(false);       
+        newStage.show();
+        
+        SnapshotParameters sp = new SnapshotParameters();
+        sp.setTransform(Transform.scale(width / root.getWidth(), height / root.getHeight()));
+        newStage.close();
+        
+        return root.snapshot(sp, null);
+    }
+
+	@Override
+	public double getSuggestedWidth()
+	{
+		return getWidth() + 50;
+	}
+
+	@Override
+	public double getSuggestedHeight()
+	{
+		return getHeight() + 50;
+	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/comparators/DateComparator.java b/src/de/deadlocker8/budgetmaster/logic/comparators/DateComparator.java
new file mode 100644
index 0000000000000000000000000000000000000000..7ae06eda2bf3ff56ca0d847ac9abec97e2a520a9
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/comparators/DateComparator.java
@@ -0,0 +1,18 @@
+package de.deadlocker8.budgetmaster.logic.comparators;
+
+import java.util.Comparator;
+
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+
+public class DateComparator implements Comparator<String> 
+{
+    @Override
+    public int compare(String o1, String o2) 
+    {
+        DateTime a = DateTime.parse(o1, DateTimeFormat.forPattern("dd.MM.YYYY"));
+        DateTime b = DateTime.parse(o2, DateTimeFormat.forPattern("dd.MM.YYYY"));
+       
+        return a.compareTo(b);
+    }
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/comparators/RatingComparator.java b/src/de/deadlocker8/budgetmaster/logic/comparators/RatingComparator.java
new file mode 100644
index 0000000000000000000000000000000000000000..76b69cc5a9623089571a3e2f892d4ca16b19ebb4
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/comparators/RatingComparator.java
@@ -0,0 +1,15 @@
+package de.deadlocker8.budgetmaster.logic.comparators;
+
+import java.util.Comparator;
+
+public class RatingComparator implements Comparator<Integer> 
+{
+    @Override
+    public int compare(Integer o1, Integer o2) 
+    {
+        Integer a = o1 > 0 ? 1 : 0;        
+        Integer b = o2 > 0 ? 1 : 0;
+       
+        return a.compareTo(b);
+    }
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/report/AmountType.java b/src/de/deadlocker8/budgetmaster/logic/report/AmountType.java
new file mode 100644
index 0000000000000000000000000000000000000000..a114ffd7c1c5aaf362a0499818a285b4266075bc
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/report/AmountType.java
@@ -0,0 +1,6 @@
+package de.deadlocker8.budgetmaster.logic.report;
+
+public enum AmountType
+{
+	INCOME, PAYMENT, BOTH
+}
diff --git a/src/de/deadlocker8/budgetmaster/logic/report/ColumnFilter.java b/src/de/deadlocker8/budgetmaster/logic/report/ColumnFilter.java
new file mode 100644
index 0000000000000000000000000000000000000000..cf722850917b0d79e28735d4763cf26981940fff
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/report/ColumnFilter.java
@@ -0,0 +1,45 @@
+package de.deadlocker8.budgetmaster.logic.report;
+
+import java.util.HashSet;
+
+public class ColumnFilter
+{
+	private HashSet<ColumnType> columns;
+
+	public ColumnFilter()
+	{
+		columns = new HashSet<ColumnType>();
+	}
+	
+	public void addColumn(ColumnType column)
+	{
+		columns.add(column);
+	}
+	
+	public void removeColumn(ColumnType column)
+	{
+		columns.remove(column);
+	}
+	
+	public void toggleColumn(ColumnType column, boolean add)
+	{
+		if(add)
+		{
+			columns.add(column);
+		}
+		else
+		{
+			columns.remove(column);
+		}
+	}
+	
+	public HashSet<ColumnType> getColumns()
+	{
+		return columns;
+	}
+	
+	public boolean containsColumn(ColumnType column)
+	{
+		return columns.contains(column);
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/report/ColumnOrder.java b/src/de/deadlocker8/budgetmaster/logic/report/ColumnOrder.java
new file mode 100644
index 0000000000000000000000000000000000000000..62aaeb9e254c5237a0ea5cb2b1a88d1eba435ef7
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/report/ColumnOrder.java
@@ -0,0 +1,23 @@
+package de.deadlocker8.budgetmaster.logic.report;
+
+import java.util.ArrayList;
+
+public class ColumnOrder
+{
+	private ArrayList<ColumnType> columns;
+
+	public ColumnOrder()
+	{
+		columns = new ArrayList<ColumnType>();
+	}
+
+	public ArrayList<ColumnType> getColumns()
+	{
+		return columns;
+	}
+	
+	public void addColumn(ColumnType column)
+	{
+		columns.add(column);
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/report/ColumnType.java b/src/de/deadlocker8/budgetmaster/logic/report/ColumnType.java
new file mode 100644
index 0000000000000000000000000000000000000000..b7503a80ce55a7b2d0da8699c98f17edf4f022c4
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/report/ColumnType.java
@@ -0,0 +1,25 @@
+package de.deadlocker8.budgetmaster.logic.report;
+
+public enum ColumnType
+{
+	POSITION("Nr."),
+	DATE("Datum"),
+	REPEATING("Wiederholend"),
+	CATEGORY("Kategorie"),
+	NAME("Name"),
+	DESCRIPTION("Notiz"), 
+	RATING("Bewertung"), 
+	AMOUNT("Betrag");
+	
+	private String name;
+
+	private ColumnType(String name)
+	{
+		this.name = name;
+	}
+
+	public String getName()
+	{
+		return name;
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/report/HeaderFooterPageEvent.java b/src/de/deadlocker8/budgetmaster/logic/report/HeaderFooterPageEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..5eff761741caa39d961e6e88c15df86b0e56328a
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/report/HeaderFooterPageEvent.java
@@ -0,0 +1,30 @@
+package de.deadlocker8.budgetmaster.logic.report;
+
+import org.joda.time.DateTime;
+
+import com.itextpdf.text.Document;
+import com.itextpdf.text.Element;
+import com.itextpdf.text.Font;
+import com.itextpdf.text.Phrase;
+import com.itextpdf.text.Font.FontFamily;
+import com.itextpdf.text.pdf.ColumnText;
+import com.itextpdf.text.pdf.GrayColor;
+import com.itextpdf.text.pdf.PdfPageEventHelper;
+import com.itextpdf.text.pdf.PdfWriter;
+
+public class HeaderFooterPageEvent extends PdfPageEventHelper
+{
+	public void onStartPage(PdfWriter writer, Document document)
+	{
+		
+	}
+
+	public void onEndPage(PdfWriter writer, Document document)
+	{
+		Font font = new Font(FontFamily.HELVETICA, 8, Font.NORMAL, GrayColor.BLACK);
+
+		ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_CENTER, new Phrase("BudgetMaster Monatsbericht", font), 100, 25, 0);
+		ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_CENTER, new Phrase("Seite " + document.getPageNumber(), font), 300, 25, 0);
+		ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_CENTER, new Phrase(DateTime.now().toString("dd.MM.YYYY"), font), 500, 25, 0);
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/report/ReportGenerator.java b/src/de/deadlocker8/budgetmaster/logic/report/ReportGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..9ad46eb9572e7f72a2c5b635cf47819cc0e9a928
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/report/ReportGenerator.java
@@ -0,0 +1,270 @@
+package de.deadlocker8.budgetmaster.logic.report;
+
+import java.awt.Color;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.util.ArrayList;
+
+import org.joda.time.DateTime;
+
+import com.itextpdf.text.BaseColor;
+import com.itextpdf.text.Chapter;
+import com.itextpdf.text.Chunk;
+import com.itextpdf.text.Document;
+import com.itextpdf.text.DocumentException;
+import com.itextpdf.text.Element;
+import com.itextpdf.text.Font;
+import com.itextpdf.text.Font.FontFamily;
+import com.itextpdf.text.Paragraph;
+import com.itextpdf.text.Phrase;
+import com.itextpdf.text.pdf.GrayColor;
+import com.itextpdf.text.pdf.PdfPCell;
+import com.itextpdf.text.pdf.PdfPTable;
+import com.itextpdf.text.pdf.PdfWriter;
+
+import de.deadlocker8.budgetmaster.logic.CategoryBudget;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
+
+public class ReportGenerator
+{
+	private ArrayList<ReportItem> reportItems;
+	private ArrayList<CategoryBudget> categoryBudgets;
+	private ColumnOrder columnOrder;
+	private boolean splitTable;
+	private boolean includeCategoryBudgets;
+	private File savePath;
+	private String currency;
+	private DateTime date;
+
+	public ReportGenerator(ArrayList<ReportItem> reportItems, ArrayList<CategoryBudget> categoryBudgets, ColumnOrder columnOrder, boolean splitTable, boolean includeCategoryBudgets, File savePath, String currency, DateTime date)
+	{	
+		this.reportItems = reportItems;
+		this.categoryBudgets = categoryBudgets;
+		this.columnOrder = columnOrder;
+		this.splitTable = splitTable;
+		this.includeCategoryBudgets = includeCategoryBudgets;
+		this.savePath = savePath;
+		this.currency = currency;
+		this.date = date;
+	}
+
+	private Chapter generateHeader()
+	{
+		Font chapterFont = new Font(FontFamily.HELVETICA, 16, Font.BOLDITALIC);
+		Font paragraphFont = new Font(FontFamily.HELVETICA, 12, Font.NORMAL);
+		Chunk chunk = new Chunk("Monatsbericht - " + date.toString("MMMM yyyy"), chapterFont);
+		Chapter chapter = new Chapter(new Paragraph(chunk), 1);
+		chapter.setNumberDepth(0);
+		chapter.add(Chunk.NEWLINE);
+		chapter.add(new Paragraph("Buchungsübersicht", paragraphFont));
+		return chapter;
+	}
+
+	private PdfPTable generateTable(int tableWidth, AmountType amountType)
+	{
+		int numberOfColumns = columnOrder.getColumns().size();
+		int totalIncome = 0;
+		int totalPayment = 0;
+
+		if(numberOfColumns > 0)
+		{
+			PdfPTable table = new PdfPTable(numberOfColumns);
+			table.setWidthPercentage(tableWidth);
+			Font font = new Font(FontFamily.HELVETICA, 8, Font.NORMAL, GrayColor.BLACK);
+
+			for(ColumnType column : columnOrder.getColumns())
+			{
+				PdfPCell cell = new PdfPCell(new Phrase(column.getName(), font));
+				cell.setBackgroundColor(GrayColor.LIGHT_GRAY);
+				cell.setHorizontalAlignment(Element.ALIGN_CENTER);
+				table.addCell(cell);
+			}
+
+			for(ReportItem currentItem : reportItems)
+			{
+				if(currentItem.getAmount() > 0)
+				{
+					totalIncome += currentItem.getAmount();
+					if(amountType == AmountType.PAYMENT)
+					{
+						continue;
+					}
+				}
+				else
+				{
+					totalPayment += currentItem.getAmount();
+					if(amountType == AmountType.INCOME)
+					{
+						continue;
+					}
+				}
+
+				for(ColumnType column : columnOrder.getColumns())
+				{
+					PdfPCell cell = new PdfPCell(new Phrase(getProperty(currentItem, column), font));
+					cell.setBackgroundColor(new BaseColor(Color.WHITE));
+					cell.setHorizontalAlignment(Element.ALIGN_CENTER);
+					table.addCell(cell);
+				}
+			}
+
+			PdfPCell cellTotal;
+			String total = "";
+			switch(amountType)
+			{
+				case BOTH:
+					String totalIncomeString = Helpers.getCurrencyString(totalIncome, currency);
+					String totalPaymentString = Helpers.getCurrencyString(totalPayment, currency);
+					total = "Einnahmen: " + totalIncomeString + " / Ausgaben: " + totalPaymentString;
+					break;
+				case INCOME:
+					total = "Summe: " + Helpers.getCurrencyString(totalIncome, currency);
+					break;
+				case PAYMENT:
+					total = "Summe: " + Helpers.getCurrencyString(totalPayment, currency);
+					break;
+				default:
+					break;
+			}
+
+			cellTotal = new PdfPCell(new Phrase(total, font));
+			cellTotal.setBackgroundColor(new BaseColor(Color.WHITE));
+			cellTotal.setColspan(numberOfColumns);
+			cellTotal.setHorizontalAlignment(Element.ALIGN_RIGHT);
+			table.addCell(cellTotal);
+
+			return table;
+		}
+		return null;
+	}
+
+	public void generate() throws FileNotFoundException, DocumentException
+	{
+		Document document = new Document();
+		PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(savePath));
+		writer.setPageEvent(new HeaderFooterPageEvent());
+		document.open();
+		document.setMargins(50, 45, 50, 70);
+		Font paragraphFont = new Font(FontFamily.HELVETICA, 12, Font.NORMAL);
+
+		document.add(generateHeader());
+		document.add(Chunk.NEWLINE);
+
+		if(splitTable)
+		{
+			document.add(new Paragraph("Einnahmen", paragraphFont));
+			document.add(Chunk.NEWLINE);
+			PdfPTable table = generateTable(100, AmountType.INCOME);
+			if(table != null)
+			{
+				document.add(table);
+			}
+
+			document.add(Chunk.NEWLINE);
+			document.add(new Paragraph("Ausgaben", paragraphFont));
+			document.add(Chunk.NEWLINE);
+			table = generateTable(100, AmountType.PAYMENT);
+			if(table != null)
+			{
+				document.add(table);
+			}
+		}
+		else
+		{
+			PdfPTable table = generateTable(100, AmountType.BOTH);
+			if(table != null)
+			{
+				document.add(table);
+			}
+		}
+
+		if(includeCategoryBudgets)
+		{
+			document.add(Chunk.NEWLINE);
+			document.add(new Paragraph("Verbrauch nach Kategorien", paragraphFont));
+			document.add(Chunk.NEWLINE);
+			PdfPTable table = generateCategoryBudgets();
+			if(table != null)
+			{
+				document.add(table);
+			}
+		}
+
+		document.close();
+	}
+
+	private PdfPTable generateCategoryBudgets()
+	{
+		PdfPTable table = new PdfPTable(2);
+		table.setWidthPercentage(100);
+		Font font = new Font(FontFamily.HELVETICA, 8, Font.NORMAL, GrayColor.BLACK);
+		
+		//header cells
+		PdfPCell cellHeaderCategory = new PdfPCell(new Phrase("Kategorie", font));
+		cellHeaderCategory.setBackgroundColor(GrayColor.LIGHT_GRAY);
+		cellHeaderCategory.setHorizontalAlignment(Element.ALIGN_CENTER);
+		table.addCell(cellHeaderCategory);
+		PdfPCell cellHeaderAmount = new PdfPCell(new Phrase("Betrag", font));
+		cellHeaderAmount.setBackgroundColor(GrayColor.LIGHT_GRAY);
+		cellHeaderAmount.setHorizontalAlignment(Element.ALIGN_CENTER);
+		table.addCell(cellHeaderAmount);		
+
+		for(CategoryBudget budget : categoryBudgets)
+		{			
+			String name = budget.getName();
+			if(name.equals("NONE"))
+			{
+				name = "Keine Kategorie";
+			}			
+			PdfPCell cellName = new PdfPCell(new Phrase(name, font));
+			cellName.setBackgroundColor(new BaseColor(Color.WHITE));
+			cellName.setHorizontalAlignment(Element.ALIGN_CENTER);
+			table.addCell(cellName);
+			
+			PdfPCell cellAmount = new PdfPCell(new Phrase(Helpers.getCurrencyString(budget.getBudget() / 100.0, currency), font));
+			cellAmount.setBackgroundColor(new BaseColor(Color.WHITE));
+			cellAmount.setHorizontalAlignment(Element.ALIGN_CENTER);
+			table.addCell(cellAmount);
+		}
+		
+		return table;
+	}
+
+	private String getProperty(ReportItem reportItem, ColumnType columnType)
+	{
+		switch(columnType)
+		{
+			case AMOUNT:
+				return Helpers.getCurrencyString(reportItem.getAmount(), currency);
+			case CATEGORY:
+				String name = reportItem.getCategory().getName();
+				if(name.equals("NONE"))
+				{
+					name = "Keine Kategorie";
+				}			
+				return name;
+			case DATE:
+				return reportItem.getDate();
+			case DESCRIPTION:
+				return reportItem.getDescription();
+			case NAME:
+				return reportItem.getName();
+			case POSITION:
+				return String.valueOf(reportItem.getPosition());
+			case RATING:
+				return reportItem.getAmount() > 0 ? "+" : "-";
+			case REPEATING:	
+				if(reportItem.getRepeating())
+				{
+					return "Ja";
+				}
+				else
+				{
+					return "Nein";
+				}				
+			default:
+				return null;
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/report/ReportItem.java b/src/de/deadlocker8/budgetmaster/logic/report/ReportItem.java
new file mode 100644
index 0000000000000000000000000000000000000000..d155a69481267a722b24355ae233374f3acc8ea1
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/report/ReportItem.java
@@ -0,0 +1,95 @@
+package de.deadlocker8.budgetmaster.logic.report;
+
+import de.deadlocker8.budgetmaster.logic.Category;
+
+public class ReportItem
+{
+	private int position;
+	private int amount;
+	private String date;
+	private Category category;
+	private String name;
+	private String description;
+	private boolean repeating;
+
+	public ReportItem()
+	{
+		
+	}
+
+	public int getPosition()
+	{
+		return position;
+	}
+
+	public void setPosition(int position)
+	{
+		this.position = position;
+	}
+
+	public int getAmount()
+	{
+		return amount;
+	}
+
+	public void setAmount(int amount)
+	{
+		this.amount = amount;
+	}
+
+	public String getDate()
+	{
+		return date;
+	}
+
+	public void setDate(String date)
+	{
+		this.date = date;
+	}
+
+	public Category getCategory()
+	{
+		return category;
+	}
+
+	public void setCategory(Category category)
+	{
+		this.category = category;
+	}
+
+	public String getName()
+	{
+		return name;
+	}
+
+	public void setName(String name)
+	{
+		this.name = name;
+	}
+
+	public String getDescription()
+	{
+		return description;
+	}
+
+	public void setDescription(String description)
+	{
+		this.description = description;
+	}
+
+	public boolean getRepeating()
+	{
+		return repeating;
+	}
+
+	public void setRepeating(boolean repeating)
+	{
+		this.repeating = repeating;
+	}
+
+	@Override
+	public String toString()
+	{
+		return "ReportItem [position=" + position + ", amount=" + amount + ", date=" + date + ", category=" + category + ", name=" + name + ", description=" + description + ", isRepeating=" + repeating + "]";
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/logic/ExceptionHandler.java b/src/de/deadlocker8/budgetmaster/logic/serverconnection/ExceptionHandler.java
similarity index 84%
rename from src/de/deadlocker8/budgetmaster/logic/ExceptionHandler.java
rename to src/de/deadlocker8/budgetmaster/logic/serverconnection/ExceptionHandler.java
index 40aa9bbc3f3b3087a356a9f710e16c893d4fd6a3..171a7b68a4c2f1bd054950581c29802589249054 100644
--- a/src/de/deadlocker8/budgetmaster/logic/ExceptionHandler.java
+++ b/src/de/deadlocker8/budgetmaster/logic/serverconnection/ExceptionHandler.java
@@ -1,4 +1,6 @@
-package de.deadlocker8.budgetmaster.logic;
+package de.deadlocker8.budgetmaster.logic.serverconnection;
+
+import java.net.UnknownHostException;
 
 public class ExceptionHandler
 {
@@ -9,6 +11,11 @@ public class ExceptionHandler
 			return handleServerConnectionException(e);
 		}			
 		
+		if(e instanceof UnknownHostException)
+		{
+			return "Es konnte keine Verbindung mit dem Internet hergestellt werden.";
+		}
+		
 		if(e.getMessage() == null)
 		{
 			return "Unbekannter Fehler (" + e.getClass() + ")";
diff --git a/src/de/deadlocker8/budgetmaster/logic/ServerConnection.java b/src/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnection.java
similarity index 96%
rename from src/de/deadlocker8/budgetmaster/logic/ServerConnection.java
rename to src/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnection.java
index 8443d3fe84ee30432e7aa18f0aef4b840e1e7cd6..a7edd958d9496f077f0854b01f9f9b5072fdf4c2 100644
--- a/src/de/deadlocker8/budgetmaster/logic/ServerConnection.java
+++ b/src/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnection.java
@@ -1,4 +1,4 @@
-package de.deadlocker8.budgetmaster.logic;
+package de.deadlocker8.budgetmaster.logic.serverconnection;
 
 import java.io.BufferedReader;
 import java.io.InputStream;
@@ -19,6 +19,15 @@ import org.joda.time.DateTime;
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
 
+import de.deadlocker8.budgetmaster.logic.Category;
+import de.deadlocker8.budgetmaster.logic.CategoryBudget;
+import de.deadlocker8.budgetmaster.logic.CategoryInOutSum;
+import de.deadlocker8.budgetmaster.logic.MonthInOutSum;
+import de.deadlocker8.budgetmaster.logic.NormalPayment;
+import de.deadlocker8.budgetmaster.logic.RepeatingPayment;
+import de.deadlocker8.budgetmaster.logic.RepeatingPaymentEntry;
+import de.deadlocker8.budgetmaster.logic.Settings;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
 import de.deadlocker8.budgetmasterserver.logic.Database;
 import tools.ConvertTo;
 import tools.Read;
@@ -29,7 +38,7 @@ public class ServerConnection
 	private Gson gson;
 
 	public ServerConnection(Settings settings) throws Exception
-	{
+	{		
 		this.settings = settings;
 		this.gson = new Gson();
 
diff --git a/src/de/deadlocker8/budgetmaster/logic/ServerConnectionException.java b/src/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnectionException.java
similarity index 91%
rename from src/de/deadlocker8/budgetmaster/logic/ServerConnectionException.java
rename to src/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnectionException.java
index c18a1663b3a6774129233997db6a08d99535f9e4..4415d8625928515f62717b77cfa8ed93228a029a 100644
--- a/src/de/deadlocker8/budgetmaster/logic/ServerConnectionException.java
+++ b/src/de/deadlocker8/budgetmaster/logic/serverconnection/ServerConnectionException.java
@@ -1,4 +1,4 @@
-package de.deadlocker8.budgetmaster.logic;
+package de.deadlocker8.budgetmaster.logic.serverconnection;
 
 public class ServerConnectionException extends Exception
 {
diff --git a/src/de/deadlocker8/budgetmaster/logic/Utils.java b/src/de/deadlocker8/budgetmaster/logic/utils/FileHelper.java
similarity index 93%
rename from src/de/deadlocker8/budgetmaster/logic/Utils.java
rename to src/de/deadlocker8/budgetmaster/logic/utils/FileHelper.java
index c9af40da56e4e6360256674d42ee8d139343969e..2e6766f7dcbab1a416fd8db16f770706feaeb38e 100644
--- a/src/de/deadlocker8/budgetmaster/logic/Utils.java
+++ b/src/de/deadlocker8/budgetmaster/logic/utils/FileHelper.java
@@ -1,4 +1,4 @@
-package de.deadlocker8.budgetmaster.logic;
+package de.deadlocker8.budgetmaster.logic.utils;
 
 import java.io.File;
 import java.io.IOException;
@@ -12,10 +12,11 @@ import java.util.ResourceBundle;
 
 import com.google.gson.Gson;
 
+import de.deadlocker8.budgetmaster.logic.Settings;
 import de.deadlocker8.budgetmasterserver.logic.Database;
 import tools.PathUtils;
 
-public class Utils
+public class FileHelper
 {
 	private static final ResourceBundle bundle = ResourceBundle.getBundle("de/deadlocker8/budgetmaster/main/", Locale.GERMANY);
 	
diff --git a/src/de/deadlocker8/budgetmaster/logic/utils/Helpers.java b/src/de/deadlocker8/budgetmaster/logic/utils/Helpers.java
new file mode 100644
index 0000000000000000000000000000000000000000..1933a2fe17a7f8f23c0b1511f5d8fc4c8d4420bb
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/logic/utils/Helpers.java
@@ -0,0 +1,148 @@
+package de.deadlocker8.budgetmaster.logic.utils;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.text.DecimalFormat;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+
+import de.deadlocker8.budgetmaster.ui.controller.ModalController;
+import fontAwesome.FontIcon;
+import fontAwesome.FontIconType;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.image.Image;
+import javafx.scene.paint.Color;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import logger.Logger;
+
+public class Helpers
+{
+	public static final DecimalFormat NUMBER_FORMAT = new DecimalFormat("0.00");
+	
+	public static final String COLOR_INCOME = "#22BAD9";
+	public static final String COLOR_PAYMENT = "#F2612D";
+	public static final String SALT = "ny9/Y+G|WrJ,82|oIYQQ X %i-sq#4,uA-qKPtwFPnw+s(k2`rV)^-a1|t{D3Z>S";
+	
+	public static String getCurrencyString(int amount, String currency)
+	{
+		return String.valueOf(NUMBER_FORMAT.format(amount / 100.0).replace(".", ",")) + " " + currency;
+	}
+
+	public static String getCurrencyString(double amount, String currency)
+	{
+		return String.valueOf(NUMBER_FORMAT.format(amount).replace(".", ",")) + " " + currency;
+	}
+	
+	public static String getURLEncodedString(String input)
+	{
+		try
+		{
+			return URLEncoder.encode(input, "UTF-8");
+		}
+		catch(UnsupportedEncodingException e)
+		{
+			return input;
+		}
+	}
+
+	public static String getDateString(LocalDate date)
+	{
+		if(date == null)
+		{
+			return "";
+		}
+		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+		return date.format(formatter);
+	}
+
+	public static ArrayList<String> getMonthList()
+	{
+		ArrayList<String> monthNames = new ArrayList<>();
+		monthNames.add("Januar");
+		monthNames.add("Februar");
+		monthNames.add("März");
+		monthNames.add("April");
+		monthNames.add("Mai");
+		monthNames.add("Juni");
+		monthNames.add("Juli");
+		monthNames.add("August");
+		monthNames.add("September");
+		monthNames.add("Oktober");
+		monthNames.add("November");
+		monthNames.add("Dezember");
+		return monthNames;
+	}
+
+	public static ArrayList<String> getYearList()
+	{
+		ArrayList<String> years = new ArrayList<>();
+		for(int i = 2000; i < 2100; i++)
+		{
+			years.add(String.valueOf(i));
+		}
+		return years;
+	}
+	
+	public static ArrayList<Color> getCategoryColorList()
+	{
+	    ArrayList<Color> colors = new ArrayList<>();       
+        //grey (light to dark)      
+        colors.add(Color.web("#CCCCCC"));   
+        colors.add(Color.web("#888888"));       
+        colors.add(Color.web("#333333"));   
+        colors.add(Color.rgb(255, 241, 119));   //lighyellow    
+        colors.add(Color.rgb(255, 204, 0));     //yellow
+        colors.add(Color.rgb(255, 149, 0));     //orange
+        colors.add(Color.rgb(255, 59, 48));     //red
+        colors.add(Color.rgb(169, 3, 41));      //darkred   
+        colors.add(Color.rgb(255, 81, 151));    //pink
+        colors.add(Color.rgb(155, 89, 182));    //purple
+        colors.add(Color.rgb(88, 86, 214));     //darkpurple
+        colors.add(Color.rgb(0, 122, 250));     //blue      
+        colors.add(Color.rgb(90, 200, 250));    //lightblue
+        colors.add(Color.rgb(76, 217, 100));    //lightgreen
+        colors.add(Color.rgb(46, 124, 43));     //darkgreen
+        
+        return colors;
+	}
+	
+	public static FontIcon getFontIcon(FontIconType type, int size, Color color)
+	{
+	    FontIcon icon = new FontIcon(type);
+	    icon.setSize(size);
+	    icon.setColor(color);
+	    
+	    return icon;
+	}
+	
+	public static Stage showModal(String title, String message, Stage owner, Image icon)
+	{
+		try
+		{
+			FXMLLoader fxmlLoader = new FXMLLoader(Helpers.class.getResource("/de/deadlocker8/budgetmaster/ui/fxml/Modal.fxml"));
+			Parent root = (Parent)fxmlLoader.load();
+			Stage newStage = new Stage();
+			newStage.initOwner(owner);
+			newStage.initModality(Modality.APPLICATION_MODAL);
+			newStage.setTitle(title);
+			newStage.setScene(new Scene(root));
+			newStage.getIcons().add(icon);
+			newStage.setResizable(false);
+			ModalController newController = fxmlLoader.getController();
+			newController.init(newStage, message);
+			newStage.show();
+
+			return newStage;
+		}
+		catch(IOException e)
+		{
+			Logger.error(e);
+			return null;
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/main/Main.java b/src/de/deadlocker8/budgetmaster/main/Main.java
index a2a24cf7e5355bfad397ae5afdc5b0ef628d1023..30857a6e29f8b1a3de8bbae3e3ebd062199ef5b9 100644
--- a/src/de/deadlocker8/budgetmaster/main/Main.java
+++ b/src/de/deadlocker8/budgetmaster/main/Main.java
@@ -4,7 +4,7 @@ import java.io.File;
 import java.util.Locale;
 import java.util.ResourceBundle;
 
-import de.deadlocker8.budgetmaster.ui.Controller;
+import de.deadlocker8.budgetmaster.ui.controller.SplashScreenController;
 import javafx.application.Application;
 import javafx.fxml.FXMLLoader;
 import javafx.scene.Parent;
@@ -24,20 +24,18 @@ public class Main extends Application
 	{
 		try
 		{
-			FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().getResource("de/deadlocker8/budgetmaster/ui/GUI.fxml"));
+		    Image icon = new Image("/de/deadlocker8/budgetmaster/resources/icon.png");
+			FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().getResource("de/deadlocker8/budgetmaster/ui/fxml/SplashScreen.fxml"));
 			Parent root = (Parent)loader.load();
+			
+			Scene scene = new Scene(root, 450, 230);
 
-			Scene scene = new Scene(root, 650, 650);	
+			((SplashScreenController)loader.getController()).init(stage, icon, bundle);
 
-			((Controller)loader.getController()).init(stage);
-
-			stage.setResizable(true);
-			stage.setMinHeight(650);
-			stage.setMinWidth(610);
-			stage.getIcons().add(new Image("/de/deadlocker8/budgetmaster/resources/icon.png"));
+			stage.setResizable(false);			
+			stage.getIcons().add(icon);
 			stage.setTitle(bundle.getString("app.name"));
-			stage.setScene(scene);
-			stage.getScene().getStylesheets().add("/de/deadlocker8/budgetmaster/ui/style.css");
+			stage.setScene(scene);			
 			stage.show();
 		}
 		catch(Exception e)
diff --git a/src/de/deadlocker8/budgetmaster/main/_de.properties b/src/de/deadlocker8/budgetmaster/main/_de.properties
index 888ab9545116e080a8d428638a00977aa0605ebd..d82abed3111911a5cf8458a12db8f1427b0437b9 100644
--- a/src/de/deadlocker8/budgetmaster/main/_de.properties
+++ b/src/de/deadlocker8/budgetmaster/main/_de.properties
@@ -1,7 +1,7 @@
 app.name=BudgetMaster
-version.code=3
-version.name=1.2.0
-version.date=25.05.17
+version.code=4
+version.name=1.3.0
+version.date=10.08.17
 author=Robert Goldmann
 
 folder=Deadlocker/BudgetMaster
diff --git a/src/de/deadlocker8/budgetmaster/ui/ChartController.java b/src/de/deadlocker8/budgetmaster/ui/ChartController.java
deleted file mode 100644
index 6f9e336ddcd7a7a27f4a9e367f14103874b7e9b8..0000000000000000000000000000000000000000
--- a/src/de/deadlocker8/budgetmaster/ui/ChartController.java
+++ /dev/null
@@ -1,228 +0,0 @@
-package de.deadlocker8.budgetmaster.ui;
-
-import java.time.LocalDate;
-import java.util.ArrayList;
-
-import org.joda.time.DateTime;
-import org.joda.time.format.DateTimeFormat;
-
-import de.deadlocker8.budgetmaster.logic.CategoryInOutSum;
-import de.deadlocker8.budgetmaster.logic.ExceptionHandler;
-import de.deadlocker8.budgetmaster.logic.Helpers;
-import de.deadlocker8.budgetmaster.logic.MonthInOutSum;
-import de.deadlocker8.budgetmaster.logic.ServerConnection;
-import de.deadlocker8.budgetmaster.logic.chartGenerators.CategoriesChartGenerator;
-import de.deadlocker8.budgetmaster.logic.chartGenerators.LineChartGenerator;
-import de.deadlocker8.budgetmaster.logic.chartGenerators.MonthChartGenerator;
-import fontAwesome.FontIcon;
-import fontAwesome.FontIconType;
-import javafx.collections.FXCollections;
-import javafx.fxml.FXML;
-import javafx.geometry.Insets;
-import javafx.scene.chart.LineChart;
-import javafx.scene.control.Accordion;
-import javafx.scene.control.Alert.AlertType;
-import javafx.scene.control.Button;
-import javafx.scene.control.ComboBox;
-import javafx.scene.control.DateCell;
-import javafx.scene.control.DatePicker;
-import javafx.scene.control.RadioButton;
-import javafx.scene.control.ScrollPane;
-import javafx.scene.control.ScrollPane.ScrollBarPolicy;
-import javafx.scene.control.ToggleGroup;
-import javafx.scene.layout.AnchorPane;
-import javafx.scene.layout.HBox;
-import javafx.scene.layout.Priority;
-import javafx.scene.layout.Region;
-import javafx.scene.layout.VBox;
-import javafx.scene.paint.Color;
-import javafx.util.Callback;
-import logger.Logger;
-import tools.AlertGenerator;
-
-public class ChartController implements Refreshable
-{
-	@FXML private AnchorPane anchorPaneMain;
-	@FXML private Accordion accordion;
-	@FXML private DatePicker datePickerStart;
-	@FXML private VBox vboxChartCategories;
-	@FXML private DatePicker datePickerEnd;
-	@FXML private VBox vboxChartMonth;
-	@FXML private Button buttonChartCategoriesShow;
-	@FXML private ComboBox<String> comboBoxStartMonth;
-	@FXML private ComboBox<String> comboBoxStartYear;
-	@FXML private ComboBox<String> comboBoxEndMonth;
-	@FXML private ComboBox<String> comboBoxEndYear;
-	@FXML private Button buttonChartMonthShow;
-	@FXML private RadioButton radioButtonBars;
-	@FXML private RadioButton radioButtonLines;
-
-	private Controller controller;
-
-	public void init(Controller controller)
-	{
-		this.controller = controller;
-
-		anchorPaneMain.setStyle("-fx-background-color: #F4F4F4;");
-		vboxChartCategories.setStyle("-fx-background-color: #F4F4F4;");
-		vboxChartCategories.setSpacing(20);
-		vboxChartMonth.setStyle("-fx-background-color: #F4F4F4;");
-		FontIcon iconShow = new FontIcon(FontIconType.CHECK);
-		iconShow.setSize(16);
-		iconShow.setColor(Color.WHITE);
-		buttonChartCategoriesShow.setStyle("-fx-background-color: #2E79B9;");
-		buttonChartCategoriesShow.setGraphic(iconShow);
-		
-		FontIcon iconShow2 = new FontIcon(FontIconType.CHECK);
-		iconShow2.setSize(16);
-		iconShow2.setColor(Color.WHITE);
-		buttonChartMonthShow.setStyle("-fx-background-color: #2E79B9;");
-		buttonChartMonthShow.setGraphic(iconShow2);		
-		
-		datePickerEnd.setDayCellFactory(new Callback<DatePicker, DateCell>()
-		{
-			@Override
-			public DateCell call(DatePicker param)
-			{
-				return new DateCell()
-				{
-					@Override
-					public void updateItem(LocalDate item, boolean empty)
-					{
-						super.updateItem(item, empty);
-						if(item.isBefore(datePickerStart.getValue().plusDays(1)))
-						{
-							setDisable(true);
-							setStyle("-fx-background-color: #ffc0cb;");
-						}
-					}
-				};
-			}
-		});
-
-		comboBoxStartMonth.setItems(FXCollections.observableArrayList(Helpers.getMonthList()));
-		comboBoxStartMonth.setValue(controller.getCurrentDate().minusMonths(5).toString("MMMM"));
-		
-		comboBoxStartYear.setItems(FXCollections.observableArrayList(Helpers.getYearList()));
-		comboBoxStartYear.setValue(String.valueOf(controller.getCurrentDate().minusMonths(5).getYear()));
-		
-		comboBoxEndMonth.setItems(FXCollections.observableArrayList(Helpers.getMonthList()));
-		comboBoxEndMonth.setValue(controller.getCurrentDate().plusMonths(6).toString("MMMM"));
-		
-		comboBoxEndYear.setItems(FXCollections.observableArrayList(Helpers.getYearList()));
-		comboBoxEndYear.setValue(String.valueOf(controller.getCurrentDate().plusMonths(6).getYear()));
-
-		final ToggleGroup toggleGroup = new ToggleGroup();
-		radioButtonBars.setToggleGroup(toggleGroup);
-		radioButtonBars.setSelected(true);
-		radioButtonLines.setToggleGroup(toggleGroup);
-		
-		accordion.setExpandedPane(accordion.getPanes().get(0));
-		vboxChartMonth.setSpacing(15);
-	}
-
-	public void chartCategoriesShow()
-	{
-		DateTime startDate = DateTime.parse(datePickerStart.getValue().toString());
-		DateTime endDate = DateTime.parse(datePickerEnd.getValue().toString());
-
-		try
-		{
-			ServerConnection connection = new ServerConnection(controller.getSettings());
-			ArrayList<CategoryInOutSum> sums = connection.getCategoryInOutSumForMonth(startDate, endDate);
-
-			vboxChartCategories.getChildren().clear();
-			
-			CategoriesChartGenerator generator = new CategoriesChartGenerator("Einnahmen nach Kategorien", sums, true, controller.getSettings().getCurrency());			
-			vboxChartCategories.getChildren().add(generator.generate());
-			generator = new CategoriesChartGenerator("Ausgaben nach Kategorien", sums, false, controller.getSettings().getCurrency());
-			vboxChartCategories.getChildren().add(generator.generate());
-			
-			Region spacer = new Region();
-			vboxChartCategories.getChildren().add(spacer);
-			VBox.setVgrow(spacer, Priority.ALWAYS);
-			
-			vboxChartCategories.getChildren().add(generator.generateLegend());
-		}
-		catch(Exception e)
-		{
-			Logger.error(e);
-			controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
-		}
-	}
-
-	public void chartMonthShow()
-	{
-		vboxChartMonth.getChildren().clear();
-		
-		String startMonth = comboBoxStartMonth.getValue();
-		String startYear = comboBoxStartYear.getValue();
-		String endMonth = comboBoxEndMonth.getValue();
-		String endYear = comboBoxEndYear.getValue();		
-		
-		String startDateString = "01-" + startMonth + "-" + startYear;		
-		DateTime startDate = DateTime.parse(startDateString, DateTimeFormat.forPattern("dd-MMMM-YYYY"));
-		
-		String endDateString = "01-" + endMonth + "-" + endYear;		
-		DateTime endDate = DateTime.parse(endDateString, DateTimeFormat.forPattern("dd-MMMM-YYYY"));	
-			
-		if(endDate.isBefore(startDate))
-		{
-			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Enddatum darf nicht vor dem Startdatum liegen.", controller.getIcon(), controller.getStage(), null, false);
-			return;
-		}
-		
-		try
-		{			
-			ServerConnection connection = new ServerConnection(controller.getSettings());
-			ArrayList<MonthInOutSum> sums = connection.getMonthInOutSum(startDate, endDate);
-		
-			vboxChartMonth.getChildren().clear();
-			
-			if(radioButtonBars.isSelected())
-			{
-				ScrollPane scrollPane = new ScrollPane();				
-				scrollPane.setVbarPolicy(ScrollBarPolicy.NEVER);
-				scrollPane.setFocusTraversable(false);
-				scrollPane.setStyle("-fx-background-color: transparent; -fx-background-insets: 0; -fx-border-color: transparent; -fx-border-width: 0; -fx-border-insets: 0;");
-				scrollPane.setPadding(new Insets(0, 0, 10, 0));
-				
-				MonthChartGenerator generator = new MonthChartGenerator(sums, controller.getSettings().getCurrency());
-				HBox generatedChart = generator.generate();
-				scrollPane.setContent(generatedChart);				
-				generatedChart.prefHeightProperty().bind(scrollPane.heightProperty().subtract(30));
-				vboxChartMonth.getChildren().add(scrollPane);
-				VBox.setVgrow(scrollPane, Priority.ALWAYS);
-				vboxChartMonth.getChildren().add(generator.generateLegend());
-			}
-			else
-			{				
-				LineChartGenerator generator = new LineChartGenerator(sums, controller.getSettings().getCurrency());
-				LineChart<String, Number> chartMonth = generator.generate();
-				vboxChartMonth.getChildren().add(chartMonth);	
-				VBox.setVgrow(chartMonth, Priority.ALWAYS);
-			}
-		}
-		catch(Exception e)
-		{
-			Logger.error(e);
-			controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
-		}
-	}
-
-	@Override
-	public void refresh()
-	{
-		// chart categories
-		LocalDate startDate = LocalDate.parse(controller.getCurrentDate().withDayOfMonth(1).toString("yyyy-MM-dd"));
-		LocalDate endDate = LocalDate.parse(controller.getCurrentDate().dayOfMonth().withMaximumValue().toString("yyy-MM-dd"));
-
-		datePickerStart.setValue(startDate);
-		datePickerEnd.setValue(endDate);
-
-		chartCategoriesShow();
-
-		// chart month
-		chartMonthShow();
-	}
-}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/cells/CategoryBudgetCell.java b/src/de/deadlocker8/budgetmaster/ui/cells/CategoryBudgetCell.java
index ff09b4a5e7224bc504fba1904b9d0a1a083afb83..11296797f1be9efd9bf0b607b8f7cf746fe5e4c9 100644
--- a/src/de/deadlocker8/budgetmaster/ui/cells/CategoryBudgetCell.java
+++ b/src/de/deadlocker8/budgetmaster/ui/cells/CategoryBudgetCell.java
@@ -1,8 +1,8 @@
 package de.deadlocker8.budgetmaster.ui.cells;
 
 import de.deadlocker8.budgetmaster.logic.CategoryBudget;
-import de.deadlocker8.budgetmaster.logic.Helpers;
-import de.deadlocker8.budgetmaster.ui.HomeController;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
+import de.deadlocker8.budgetmaster.ui.controller.HomeController;
 import javafx.geometry.Insets;
 import javafx.geometry.Pos;
 import javafx.scene.control.Label;
@@ -59,9 +59,17 @@ public class CategoryBudgetCell extends ListCell<CategoryBudget>
 			hbox.getChildren().add(r);
 			HBox.setHgrow(r, Priority.ALWAYS);
 
-			Label labelBudget = new Label(String.valueOf(Helpers.NUMBER_FORMAT.format(item.getBudget() / 100.0)).replace(".", ",") + " " + homeController.getController().getSettings().getCurrency());
+			Label labelBudget = new Label(Helpers.getCurrencyString(item.getBudget() / 100.0, homeController.getController().getSettings().getCurrency()));
+			labelBudget.setStyle("-fx-font-weight: bold; -fx-font-size: 16; -fx-text-fill: #247A2D;");
+			if(item.getBudget() > 0)
+			{
+				labelBudget.setText("+" + labelBudget.getText());
+			}
+			else
+			{				
+				labelBudget.setStyle("-fx-font-weight: bold; -fx-font-size: 16; -fx-text-fill: #CC0000");
+			}
 			labelBudget.setPrefHeight(HEIGHT);
-			labelBudget.setStyle("-fx-font-weight: bold; -fx-font-size: 16; -fx-text-fill: #212121;");
 			labelBudget.setAlignment(Pos.CENTER);
 			labelBudget.getStyleClass().add("greylabel");
 			hbox.getChildren().add(labelBudget);
diff --git a/src/de/deadlocker8/budgetmaster/ui/cells/CategoryCell.java b/src/de/deadlocker8/budgetmaster/ui/cells/CategoryCell.java
index c81345ed20c85813d0377eec1a6dd407cb1a8c64..3d4b91854244fe5ded12664c68f2ae55e72797a0 100644
--- a/src/de/deadlocker8/budgetmaster/ui/cells/CategoryCell.java
+++ b/src/de/deadlocker8/budgetmaster/ui/cells/CategoryCell.java
@@ -3,8 +3,8 @@ package de.deadlocker8.budgetmaster.ui.cells;
 import java.util.Optional;
 
 import de.deadlocker8.budgetmaster.logic.Category;
-import de.deadlocker8.budgetmaster.ui.CategoryController;
-import fontAwesome.FontIcon;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
+import de.deadlocker8.budgetmaster.ui.controller.CategoryController;
 import fontAwesome.FontIconType;
 import javafx.geometry.Insets;
 import javafx.geometry.Pos;
@@ -16,6 +16,7 @@ import javafx.scene.control.ListCell;
 import javafx.scene.layout.HBox;
 import javafx.scene.layout.Priority;
 import javafx.scene.layout.Region;
+import javafx.scene.paint.Color;
 import javafx.stage.Stage;
 import tools.ConvertTo;
 
@@ -60,10 +61,8 @@ public class CategoryCell extends ListCell<Category>
 			hbox.getChildren().add(r);
 			HBox.setHgrow(r, Priority.ALWAYS);
 			
-			Button buttonEdit = new Button();
-			FontIcon iconEdit = new FontIcon(FontIconType.PENCIL);
-			iconEdit.setSize(16);
-			buttonEdit.setGraphic(iconEdit);
+			Button buttonEdit = new Button();			
+			buttonEdit.setGraphic(Helpers.getFontIcon(FontIconType.PENCIL, 16, Color.web("#212121")));
 			buttonEdit.setPrefHeight(HEIGHT);					
 			buttonEdit.getStyleClass().add("greylabel");
 			buttonEdit.setStyle("-fx-background-color: transparent");
@@ -73,10 +72,8 @@ public class CategoryCell extends ListCell<Category>
 			hbox.getChildren().add(buttonEdit);
 			HBox.setMargin(buttonEdit, new Insets(0, 0, 0, 25));
 			
-			Button buttonDelete = new Button();
-			FontIcon iconDelete = new FontIcon(FontIconType.TRASH);
-			iconDelete.setSize(16);
-			buttonDelete.setGraphic(iconDelete);
+			Button buttonDelete = new Button();			
+			buttonDelete.setGraphic(Helpers.getFontIcon(FontIconType.TRASH, 16, Color.web("#212121")));
 			buttonDelete.setPrefHeight(HEIGHT);					
 			buttonDelete.getStyleClass().add("greylabel");
 			buttonDelete.setStyle("-fx-background-color: transparent");
diff --git a/src/de/deadlocker8/budgetmaster/ui/cells/PaymentCell.java b/src/de/deadlocker8/budgetmaster/ui/cells/PaymentCell.java
index e096c9a72a0c14fdabd8972136b64e235e739ac2..ce02969c7f592b4da63f44009aeaebe7f97fcd45 100644
--- a/src/de/deadlocker8/budgetmaster/ui/cells/PaymentCell.java
+++ b/src/de/deadlocker8/budgetmaster/ui/cells/PaymentCell.java
@@ -7,12 +7,11 @@ import java.util.Date;
 import java.util.Optional;
 
 import de.deadlocker8.budgetmaster.logic.Category;
-import de.deadlocker8.budgetmaster.logic.Helpers;
 import de.deadlocker8.budgetmaster.logic.NormalPayment;
 import de.deadlocker8.budgetmaster.logic.Payment;
 import de.deadlocker8.budgetmaster.logic.RepeatingPaymentEntry;
-import de.deadlocker8.budgetmaster.ui.PaymentController;
-import fontAwesome.FontIcon;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
+import de.deadlocker8.budgetmaster.ui.controller.PaymentController;
 import fontAwesome.FontIconType;
 import javafx.geometry.Insets;
 import javafx.geometry.Pos;
@@ -28,6 +27,7 @@ import javafx.scene.layout.Priority;
 import javafx.scene.layout.Region;
 import javafx.scene.paint.Color;
 import javafx.stage.Stage;
+import logger.Logger;
 import tools.ConvertTo;
 
 public class PaymentCell extends ListCell<Payment>
@@ -62,7 +62,7 @@ public class PaymentCell extends ListCell<Payment>
 			}
 			catch(ParseException e)
 			{
-				e.printStackTrace();
+				Logger.error(e);
 			}
 			Label labelDate = new Label(dateString);
 			labelDate.setPrefHeight(HEIGHT);
@@ -72,18 +72,15 @@ public class PaymentCell extends ListCell<Payment>
 			labelDate.setMinWidth(75);
 			hbox.getChildren().add(labelDate);
 
-			FontIcon iconRepeating = new FontIcon(FontIconType.CALENDAR);
-			iconRepeating.setSize(20);
+			Label labelRepeating = new Label();
 			if(item instanceof RepeatingPaymentEntry)
-			{
-				iconRepeating.setColor(Color.web("#212121"));
+			{				
+				labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.CALENDAR, 20, Color.web("#212121")));
 			}
 			else
 			{
-				iconRepeating.setColor(Color.TRANSPARENT);
+			    labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.CALENDAR, 20, Color.TRANSPARENT));
 			}
-			Label labelRepeating = new Label();
-			labelRepeating.setGraphic(iconRepeating);
 			labelRepeating.setPrefHeight(HEIGHT);
 			labelRepeating.setStyle("-fx-font-weight: bold; -fx-font-size: 16; -fx-text-fill: #212121");
 			labelRepeating.setAlignment(Pos.CENTER);
@@ -121,7 +118,7 @@ public class PaymentCell extends ListCell<Payment>
 			hbox.getChildren().add(r);
 			HBox.setHgrow(r, Priority.ALWAYS);
 
-			Label labelBudget = new Label(String.valueOf(Helpers.NUMBER_FORMAT.format(item.getAmount() / 100.0)).replace(".", ",") + " " + paymentController.getController().getSettings().getCurrency());
+			Label labelBudget = new Label(Helpers.getCurrencyString(item.getAmount(), paymentController.getController().getSettings().getCurrency()));
 			labelBudget.setPrefHeight(HEIGHT);
 			labelBudget.setStyle("-fx-font-weight: bold; -fx-font-size: 16; -fx-text-fill: #247A2D");
 			labelBudget.setAlignment(Pos.CENTER);
@@ -140,10 +137,8 @@ public class PaymentCell extends ListCell<Payment>
 				labelBudget.setStyle("-fx-font-weight: bold; -fx-font-size: 16; -fx-text-fill: #CC0000");
 			}
 
-			Button buttonDelete = new Button();
-			FontIcon iconDelete = new FontIcon(FontIconType.TRASH);
-			iconDelete.setSize(16);
-			buttonDelete.setGraphic(iconDelete);
+			Button buttonDelete = new Button();			
+			buttonDelete.setGraphic(Helpers.getFontIcon(FontIconType.TRASH, 16, Color.web("#212121")));
 			buttonDelete.setPrefHeight(HEIGHT);
 			buttonDelete.getStyleClass().add("greylabel");
 			buttonDelete.setStyle("-fx-background-color: transparent");			
diff --git a/src/de/deadlocker8/budgetmaster/ui/ColorView.java b/src/de/deadlocker8/budgetmaster/ui/colorPick/ColorView.java
similarity index 97%
rename from src/de/deadlocker8/budgetmaster/ui/ColorView.java
rename to src/de/deadlocker8/budgetmaster/ui/colorPick/ColorView.java
index 9abaf1f94b172651e662746390f93c0a160417cc..a633cbe1e4b163f6b33772a4e9ffecdc6acef516 100644
--- a/src/de/deadlocker8/budgetmaster/ui/ColorView.java
+++ b/src/de/deadlocker8/budgetmaster/ui/colorPick/ColorView.java
@@ -1,9 +1,9 @@
-package de.deadlocker8.budgetmaster.ui;
+package de.deadlocker8.budgetmaster.ui.colorPick;
 
 import java.util.ArrayList;
 import java.util.function.Consumer;
 
-import de.deadlocker8.budgetmaster.ui.colorPick.ColorPickController;
+import de.deadlocker8.budgetmaster.ui.controller.NewCategoryController;
 import fontAwesome.FontIcon;
 import fontAwesome.FontIconType;
 import javafx.fxml.FXMLLoader;
diff --git a/src/de/deadlocker8/budgetmaster/ui/CategoryController.java b/src/de/deadlocker8/budgetmaster/ui/controller/CategoryController.java
similarity index 89%
rename from src/de/deadlocker8/budgetmaster/ui/CategoryController.java
rename to src/de/deadlocker8/budgetmaster/ui/controller/CategoryController.java
index 8a86686a8d5455a544882ddc0253e741c337d537..5a03fcc229c5f70451d3e7c966c239398b062acf 100644
--- a/src/de/deadlocker8/budgetmaster/ui/CategoryController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/controller/CategoryController.java
@@ -1,14 +1,15 @@
-package de.deadlocker8.budgetmaster.ui;
+package de.deadlocker8.budgetmaster.ui.controller;
 
 
 import java.io.IOException;
 import java.util.ArrayList;
 
 import de.deadlocker8.budgetmaster.logic.Category;
-import de.deadlocker8.budgetmaster.logic.ExceptionHandler;
-import de.deadlocker8.budgetmaster.logic.ServerConnection;
+import de.deadlocker8.budgetmaster.logic.serverconnection.ExceptionHandler;
+import de.deadlocker8.budgetmaster.logic.serverconnection.ServerConnection;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
+import de.deadlocker8.budgetmaster.ui.Refreshable;
 import de.deadlocker8.budgetmaster.ui.cells.CategoryCell;
-import fontAwesome.FontIcon;
 import fontAwesome.FontIconType;
 import javafx.application.Platform;
 import javafx.beans.value.ChangeListener;
@@ -24,6 +25,7 @@ import javafx.scene.control.ListCell;
 import javafx.scene.control.ListView;
 import javafx.scene.input.MouseEvent;
 import javafx.scene.layout.AnchorPane;
+import javafx.scene.paint.Color;
 import javafx.stage.Modality;
 import javafx.stage.Stage;
 import javafx.util.Callback;
@@ -86,10 +88,7 @@ public class CategoryController implements Refreshable
 		labelPlaceholder.setStyle("-fx-font-size: 16");
 		listView.setPlaceholder(labelPlaceholder);
 
-		FontIcon iconCategory = new FontIcon(FontIconType.PLUS);
-		iconCategory.setSize(18);
-		iconCategory.setStyle("-fx-text-fill: white");
-		buttonCategory.setGraphic(iconCategory);
+		buttonCategory.setGraphic(Helpers.getFontIcon(FontIconType.PLUS, 18, Color.WHITE));
 
 		//apply theme
 		anchorPaneMain.setStyle("-fx-background-color: #F4F4F4;");
@@ -123,7 +122,7 @@ public class CategoryController implements Refreshable
 	{
 		try
 		{
-			FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/NewCategoryGUI.fxml"));
+			FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/NewCategoryGUI.fxml"));
 			Parent root = (Parent)fxmlLoader.load();
 			Stage newStage = new Stage();
 			newStage.initOwner(controller.getStage());
diff --git a/src/de/deadlocker8/budgetmaster/ui/controller/ChartController.java b/src/de/deadlocker8/budgetmaster/ui/controller/ChartController.java
new file mode 100644
index 0000000000000000000000000000000000000000..ddd9882794e82ad3ac4b51db0cf6069e19bfd8db
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/ui/controller/ChartController.java
@@ -0,0 +1,319 @@
+package de.deadlocker8.budgetmaster.ui.controller;
+
+import java.io.File;
+import java.io.IOException;
+import java.time.LocalDate;
+import java.util.ArrayList;
+
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+
+import de.deadlocker8.budgetmaster.logic.CategoryInOutSum;
+import de.deadlocker8.budgetmaster.logic.MonthInOutSum;
+import de.deadlocker8.budgetmaster.logic.charts.CategoriesChart;
+import de.deadlocker8.budgetmaster.logic.charts.ChartExportable;
+import de.deadlocker8.budgetmaster.logic.charts.LegendType;
+import de.deadlocker8.budgetmaster.logic.charts.MonthBarChart;
+import de.deadlocker8.budgetmaster.logic.charts.MonthLineChart;
+import de.deadlocker8.budgetmaster.logic.serverconnection.ExceptionHandler;
+import de.deadlocker8.budgetmaster.logic.serverconnection.ServerConnection;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
+import de.deadlocker8.budgetmaster.ui.Refreshable;
+import fontAwesome.FontIconType;
+import javafx.application.Platform;
+import javafx.collections.FXCollections;
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Accordion;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.DateCell;
+import javafx.scene.control.DatePicker;
+import javafx.scene.control.RadioButton;
+import javafx.scene.control.ToggleGroup;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.util.Callback;
+import logger.Logger;
+import tools.AlertGenerator;
+import tools.Worker;
+
+public class ChartController implements Refreshable
+{
+	@FXML private AnchorPane anchorPaneMain;
+	@FXML private Accordion accordion;
+	@FXML private DatePicker datePickerStart;
+	@FXML private VBox vboxChartCategories;
+	@FXML private DatePicker datePickerEnd;
+	@FXML private VBox vboxChartMonth;
+	@FXML private Button buttonChartCategoriesShow;
+	@FXML private Button buttonChartCategoriesExport;
+	@FXML private ComboBox<String> comboBoxStartMonth;
+	@FXML private ComboBox<String> comboBoxStartYear;
+	@FXML private ComboBox<String> comboBoxEndMonth;
+	@FXML private ComboBox<String> comboBoxEndYear;
+	@FXML private Button buttonChartMonthShow;
+	@FXML private Button buttonChartMonthExport;
+	@FXML private RadioButton radioButtonBars;
+	@FXML private RadioButton radioButtonLines;
+
+	private Controller controller;
+	private File lastExportPath;
+	
+	private CategoriesChart categoriesChart;
+	private MonthLineChart monthLineChart;
+	private MonthBarChart monthBarChart;
+
+	public void init(Controller controller)
+	{
+		this.controller = controller;
+
+		anchorPaneMain.setStyle("-fx-background-color: #F4F4F4;");
+		vboxChartCategories.setStyle("-fx-background-color: #F4F4F4;");
+		vboxChartCategories.setSpacing(20);
+		vboxChartMonth.setStyle("-fx-background-color: #F4F4F4;");
+		
+		buttonChartCategoriesShow.setStyle("-fx-background-color: #2E79B9;");
+		buttonChartCategoriesShow.setGraphic(Helpers.getFontIcon(FontIconType.CHECK, 16, Color.WHITE));
+
+		buttonChartCategoriesExport.setStyle("-fx-background-color: #2E79B9;");
+		buttonChartCategoriesExport.setGraphic(Helpers.getFontIcon(FontIconType.SAVE, 16, Color.WHITE));
+
+		buttonChartMonthShow.setStyle("-fx-background-color: #2E79B9;");
+		buttonChartMonthShow.setGraphic(Helpers.getFontIcon(FontIconType.CHECK, 16, Color.WHITE));
+
+		buttonChartMonthExport.setStyle("-fx-background-color: #2E79B9;");
+		buttonChartMonthExport.setGraphic(Helpers.getFontIcon(FontIconType.SAVE, 16, Color.WHITE));		
+	
+		datePickerEnd.setDayCellFactory(new Callback<DatePicker, DateCell>()
+		{
+			@Override
+			public DateCell call(DatePicker param)
+			{
+				return new DateCell()
+				{
+					@Override
+					public void updateItem(LocalDate item, boolean empty)
+					{
+						super.updateItem(item, empty);
+						if(item.isBefore(datePickerStart.getValue().plusDays(1)))
+						{
+							setDisable(true);
+							setStyle("-fx-background-color: #ffc0cb;");
+						}
+					}
+				};
+			}
+		});
+
+		comboBoxStartMonth.setItems(FXCollections.observableArrayList(Helpers.getMonthList()));
+		comboBoxStartYear.setItems(FXCollections.observableArrayList(Helpers.getYearList()));
+		comboBoxEndMonth.setItems(FXCollections.observableArrayList(Helpers.getMonthList()));
+		comboBoxEndYear.setItems(FXCollections.observableArrayList(Helpers.getYearList()));
+
+		final ToggleGroup toggleGroup = new ToggleGroup();
+		radioButtonBars.setToggleGroup(toggleGroup);
+		radioButtonBars.setSelected(true);
+		radioButtonLines.setToggleGroup(toggleGroup);
+
+		accordion.setExpandedPane(accordion.getPanes().get(0));
+		vboxChartMonth.setSpacing(15);
+	}
+
+	public void buttonChartCategoriesShow()
+	{
+		chartCategoriesShow(LegendType.NORMAL);
+	}
+
+	public void chartCategoriesShow(LegendType legendType)
+	{
+		DateTime startDate = DateTime.parse(datePickerStart.getValue().toString());
+		DateTime endDate = DateTime.parse(datePickerEnd.getValue().toString());
+		try
+		{
+			ServerConnection connection = new ServerConnection(controller.getSettings());
+			ArrayList<CategoryInOutSum> sums = connection.getCategoryInOutSumForMonth(startDate, endDate);
+
+			Platform.runLater(()->{;
+				vboxChartCategories.getChildren().clear();
+				categoriesChart = new CategoriesChart("Einnahmen nach Kategorien", 
+																	  "Ausgaben nach Kategorien",
+																	  sums,
+																	  controller.getSettings().getCurrency(),
+																	  legendType);
+				vboxChartCategories.getChildren().add(categoriesChart);
+				VBox.setVgrow(categoriesChart, Priority.ALWAYS);
+			});
+		}
+		catch(Exception e)
+		{
+			Logger.error(e);
+			Platform.runLater(() -> {
+				controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
+			});
+		}
+	}
+	
+	public void chartCategoriesExport()
+	{
+		if(categoriesChart != null)
+		{
+			export(categoriesChart);
+		}
+	}
+	
+	public void chartMonthExport()
+	{
+	    if(radioButtonLines.isSelected())
+        {
+            if(monthLineChart != null)
+            {
+                export(monthLineChart);
+            }
+        }
+        else
+        {
+            if(monthBarChart != null)
+            {
+                export(monthBarChart);
+            }
+        }
+	}
+
+	public void export(ChartExportable chart)
+	{
+		Worker.runLater(() -> {
+			Platform.runLater(() -> {
+				try
+				{
+					FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/ExportChartGUI.fxml"));
+					Parent root = (Parent)fxmlLoader.load();
+					Stage newStage = new Stage();
+					newStage.initOwner(controller.getStage());
+					newStage.initModality(Modality.APPLICATION_MODAL);
+					newStage.setTitle("Diagramm exportieren");
+					newStage.setScene(new Scene(root));
+					newStage.getIcons().add(controller.getIcon());
+					newStage.setResizable(false);
+					ExportChartController newController = fxmlLoader.getController();
+					newController.init(newStage, this, chart);
+					newStage.show();
+				}
+				catch(IOException e)
+				{
+					Logger.error(e);
+				}
+			});
+		});
+	}
+
+	public void chartMonthShow()
+	{
+		Platform.runLater(() -> {
+			vboxChartMonth.getChildren().clear();
+		});
+
+		String startMonth = comboBoxStartMonth.getValue();
+		String startYear = comboBoxStartYear.getValue();
+		String endMonth = comboBoxEndMonth.getValue();
+		String endYear = comboBoxEndYear.getValue();
+
+		String startDateString = "01-" + startMonth + "-" + startYear;
+		DateTime startDate = DateTime.parse(startDateString, DateTimeFormat.forPattern("dd-MMMM-YYYY"));
+
+		String endDateString = "01-" + endMonth + "-" + endYear;
+		DateTime endDate = DateTime.parse(endDateString, DateTimeFormat.forPattern("dd-MMMM-YYYY"));
+
+		if(endDate.isBefore(startDate))
+		{
+			Platform.runLater(() -> {
+				AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Enddatum darf nicht vor dem Startdatum liegen.", controller.getIcon(), controller.getStage(), null, false);
+			});
+			return;
+		}
+
+		try
+		{
+			ServerConnection connection = new ServerConnection(controller.getSettings());
+			ArrayList<MonthInOutSum> sums = connection.getMonthInOutSum(startDate, endDate);
+
+			Platform.runLater(() -> {
+				vboxChartMonth.getChildren().clear();
+
+				if(radioButtonBars.isSelected())
+				{
+				    monthBarChart = new MonthBarChart(sums, controller.getSettings().getCurrency());
+				    vboxChartMonth.getChildren().add(monthBarChart);
+				    VBox.setVgrow(monthBarChart, Priority.ALWAYS);
+				}
+				else
+				{
+					monthLineChart = new MonthLineChart(sums, controller.getSettings().getCurrency());					
+					vboxChartMonth.getChildren().add(monthLineChart);
+					VBox.setVgrow(monthLineChart, Priority.ALWAYS);
+				}
+			});
+		}
+		catch(Exception e)
+		{
+			Logger.error(e);
+			Platform.runLater(() -> {
+				controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
+			});
+		}
+	}
+
+	public Controller getControlle()
+	{
+		return controller;
+	}
+
+	public void setLastExportPath(File lastExportPath)
+	{
+		this.lastExportPath = lastExportPath;
+	}
+
+	public File getLastExportPath()
+	{
+		return lastExportPath;
+	}
+
+	@Override
+	public void refresh()
+	{
+		Stage modalStage = Helpers.showModal("Vorgang läuft", "Lade Diagramme...", controller.getStage(), controller.getIcon());
+
+		// prepare chart categories
+		LocalDate startDate = LocalDate.parse(controller.getCurrentDate().withDayOfMonth(1).toString("yyyy-MM-dd"));
+		LocalDate endDate = LocalDate.parse(controller.getCurrentDate().dayOfMonth().withMaximumValue().toString("yyy-MM-dd"));
+
+		datePickerStart.setValue(startDate);
+		datePickerEnd.setValue(endDate);
+
+		// chart month
+		comboBoxStartMonth.setValue(controller.getCurrentDate().minusMonths(5).toString("MMMM"));
+		comboBoxStartYear.setValue(String.valueOf(controller.getCurrentDate().minusMonths(5).getYear()));
+
+		comboBoxEndMonth.setValue(controller.getCurrentDate().plusMonths(6).toString("MMMM"));
+		comboBoxEndYear.setValue(String.valueOf(controller.getCurrentDate().plusMonths(6).getYear()));
+
+		Worker.runLater(() -> {
+			chartCategoriesShow(LegendType.NORMAL);
+			chartMonthShow();
+
+			Platform.runLater(() -> {
+				if(modalStage != null)
+				{
+					modalStage.close();
+				}
+			});
+		});
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/Controller.java b/src/de/deadlocker8/budgetmaster/ui/controller/Controller.java
similarity index 67%
rename from src/de/deadlocker8/budgetmaster/ui/Controller.java
rename to src/de/deadlocker8/budgetmaster/ui/controller/Controller.java
index 408d23943441fc9ab15b41c4f58e3cae847b9362..5d78940b58085a2e06211f3fa5c9ac6e17bd384e 100644
--- a/src/de/deadlocker8/budgetmaster/ui/Controller.java
+++ b/src/de/deadlocker8/budgetmaster/ui/controller/Controller.java
@@ -1,22 +1,20 @@
-package de.deadlocker8.budgetmaster.ui;
+package de.deadlocker8.budgetmaster.ui.controller;
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Locale;
 import java.util.ResourceBundle;
 
 import org.joda.time.DateTime;
 
 import de.deadlocker8.budgetmaster.logic.CategoryBudget;
 import de.deadlocker8.budgetmaster.logic.CategoryHandler;
-import de.deadlocker8.budgetmaster.logic.ExceptionHandler;
 import de.deadlocker8.budgetmaster.logic.FilterSettings;
 import de.deadlocker8.budgetmaster.logic.NormalPayment;
 import de.deadlocker8.budgetmaster.logic.PaymentHandler;
-import de.deadlocker8.budgetmaster.logic.ServerConnection;
 import de.deadlocker8.budgetmaster.logic.Settings;
-import de.deadlocker8.budgetmaster.logic.Utils;
-import fontAwesome.FontIcon;
+import de.deadlocker8.budgetmaster.logic.serverconnection.ExceptionHandler;
+import de.deadlocker8.budgetmaster.logic.serverconnection.ServerConnection;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
 import fontAwesome.FontIconType;
 import javafx.animation.FadeTransition;
 import javafx.animation.SequentialTransition;
@@ -32,10 +30,12 @@ import javafx.scene.control.Tab;
 import javafx.scene.control.TabPane;
 import javafx.scene.image.Image;
 import javafx.scene.layout.AnchorPane;
+import javafx.scene.paint.Color;
 import javafx.stage.Stage;
 import javafx.util.Duration;
 import logger.Logger;
 import tools.AlertGenerator;
+import tools.Worker;
 
 public class Controller
 {
@@ -44,11 +44,13 @@ public class Controller
 	@FXML private Button buttonLeft;
 	@FXML private Button buttonRight;
 	@FXML private Button buttonToday;
+	@FXML private Button buttonAbout;
 	@FXML private TabPane tabPane;
 	@FXML private Tab tabHome;
 	@FXML private Tab tabPayments;
 	@FXML private Tab tabCategories;
 	@FXML private Tab tabCharts;
+	@FXML private Tab tabReports;
 	@FXML private Tab tabSettings;
 	@FXML private Label labelNotification;
 
@@ -56,11 +58,12 @@ public class Controller
 	private PaymentController paymentController;
 	private CategoryController categoryController;
 	private ChartController chartController;
+	private ReportController reportController;
 	private SettingsController settingsController;
 
 	private Stage stage;
 	private Image icon = new Image("de/deadlocker8/budgetmaster/resources/icon.png");
-	private final ResourceBundle bundle = ResourceBundle.getBundle("de/deadlocker8/budgetmaster/main/", Locale.GERMANY);
+	private ResourceBundle bundle;
 	private Settings settings;
 	private DateTime currentDate;
 	private ArrayList<CategoryBudget> categoryBudgets;
@@ -70,44 +73,62 @@ public class Controller
 
 	private boolean alertIsShowing = false;
 
-	public void init(Stage stage)
+	public void init(Stage stage, ResourceBundle bundle, Settings settings)
 	{
 		this.stage = stage;
+		this.bundle = bundle;
+		this.settings = settings;
+		
+		stage.setOnCloseRequest((event)->{
+			Worker.shutdown();
+			System.exit(0);
+		});
+		
 		currentDate = DateTime.now();
 		labelMonth.setText(currentDate.toString("MMMM yyyy"));
 		
 		filterSettings = new FilterSettings();
 		paymentHandler = new PaymentHandler();
 
-		settings = Utils.loadSettings();
-
 		try
 		{
-			FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/HomeTab.fxml"));
+			FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/HomeTab.fxml"));
 			Parent nodeTabHome = (Parent)fxmlLoader.load();
 			homeController = fxmlLoader.getController();
 			homeController.init(this);
 			tabHome.setContent(nodeTabHome);
 
-			fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/PaymentTab.fxml"));
+			fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/PaymentTab.fxml"));
 			Parent nodeTabPayment = (Parent)fxmlLoader.load();
 			paymentController = fxmlLoader.getController();
 			paymentController.init(this);
 			tabPayments.setContent(nodeTabPayment);
 
-			fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/CategoryTab.fxml"));
+			fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/CategoryTab.fxml"));
 			Parent nodeTabCategory = (Parent)fxmlLoader.load();
 			categoryController = fxmlLoader.getController();
 			categoryController.init(this);
 			tabCategories.setContent(nodeTabCategory);
 
-			fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/ChartTab.fxml"));
+			fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/ChartTab.fxml"));
 			Parent nodeTabChart = (Parent)fxmlLoader.load();
 			chartController = fxmlLoader.getController();
 			chartController.init(this);
-			tabCharts.setContent(nodeTabChart);			
+			tabCharts.setContent(nodeTabChart);
+			tabCharts.selectedProperty().addListener((a,b,c)->{
+				if(c)
+				{
+					chartController.refresh();
+				}
+			});
+			
+			fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/ReportTab.fxml"));
+			Parent nodeTabReport = (Parent)fxmlLoader.load();
+			reportController = fxmlLoader.getController();
+			reportController.init(this);
+			tabReports.setContent(nodeTabReport);
 
-			fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/SettingsTab.fxml"));
+			fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/SettingsTab.fxml"));
 			Parent nodeTabSettings = (Parent)fxmlLoader.load();
 			settingsController = fxmlLoader.getController();
 			settingsController.init(this);
@@ -120,16 +141,11 @@ public class Controller
 				AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Beim Erstellen der Benutzeroberfläche ist ein Fehler aufgetreten", icon, stage, null, false);
 			});			
 		}
-
-		FontIcon iconPrevious = new FontIcon(FontIconType.CHEVRON_LEFT);
-		iconPrevious.setSize(20);
-		buttonLeft.setGraphic(iconPrevious);
-		FontIcon iconNext = new FontIcon(FontIconType.CHEVRON_RIGHT);
-		iconNext.setSize(20);
-		buttonRight.setGraphic(iconNext);
-		FontIcon iconToday = new FontIcon(FontIconType.CALENDAR_ALT);
-		iconToday.setSize(20);
-		buttonToday.setGraphic(iconToday);
+		
+		buttonLeft.setGraphic(Helpers.getFontIcon(FontIconType.CHEVRON_LEFT, 20, Color.web(bundle.getString("color.text"))));		
+		buttonRight.setGraphic(Helpers.getFontIcon(FontIconType.CHEVRON_RIGHT, 20, Color.web(bundle.getString("color.text"))));		
+		buttonToday.setGraphic(Helpers.getFontIcon(FontIconType.CALENDAR_ALT, 20, Color.web(bundle.getString("color.text"))));		
+		buttonAbout.setGraphic(Helpers.getFontIcon(FontIconType.INFO, 20, Color.web(bundle.getString("color.text"))));
 
 		// apply theme
 		anchorPaneMain.setStyle("-fx-background-color: #DDDDDD");
@@ -138,13 +154,14 @@ public class Controller
 		buttonLeft.setStyle("-fx-background-color: transparent;");
 		buttonRight.setStyle("-fx-background-color: transparent;");
 		buttonToday.setStyle("-fx-background-color: transparent;");
+		buttonAbout.setStyle("-fx-background-color: transparent;");
 		
-		if(settings == null)
+		if(!settings.isComplete())
 		{			
 			Platform.runLater(() -> {
-				AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Bitte gibt zuerst deine Serverdaten ein!", icon, stage, null, false);
 				toggleAllTabsExceptSettings(true);
 				tabPane.getSelectionModel().select(tabSettings);
+				AlertGenerator.showAlert(AlertType.INFORMATION, "Hinweis", "", "Vor der ersten Benutzung musst du deine Serverdaten eingeben.", icon, stage, null, false);
 			});
 		}
 		else
@@ -265,7 +282,11 @@ public class Controller
 		homeController.refresh();
 		paymentController.refresh();
 		categoryController.refresh();
-		chartController.refresh();
+		reportController.refresh();
+		if(tabCharts.isSelected())
+		{
+			chartController.refresh();
+		}
 	}
 	
 	public ArrayList<CategoryBudget> getCategoryBudgets()
@@ -298,7 +319,11 @@ public class Controller
 		tabHome.setDisable(disable);
 		tabPayments.setDisable(disable);
 		tabCategories.setDisable(disable);
-		tabCharts.setDisable(disable);	
+		tabCharts.setDisable(disable);
+		tabReports.setDisable(disable);
+		buttonLeft.setDisable(disable);
+		buttonRight.setDisable(disable);
+		buttonToday.setDisable(disable);
 	}
 
 	public void about()
@@ -308,35 +333,53 @@ public class Controller
 	
 	public void refresh(FilterSettings newFilterSettings)
 	{
-		try
-		{
-			ServerConnection connection = new ServerConnection(settings);
-			
-			paymentHandler = new PaymentHandler();
-			paymentHandler.getPayments().addAll(connection.getPayments(currentDate.getYear(), currentDate.getMonthOfYear()));
-			paymentHandler.getPayments().addAll(connection.getRepeatingPayments(currentDate.getYear(), currentDate.getMonthOfYear()));			
-			paymentHandler.sort();
-			if(settings.isRestActivated())
+		Stage modalStage = Helpers.showModal("Vorgang läuft", "Lade Daten...", stage, icon);
+
+		Worker.runLater(() -> {
+			try
 			{
-				int rest = connection.getRestForAllPreviousMonths(currentDate.getYear(), currentDate.getMonthOfYear());
-				//categoryID 2 = Rest
-				paymentHandler.getPayments().add(new NormalPayment(-1, rest, currentDate.withDayOfMonth(1).toString("yyyy-MM-dd"), 2, "Übertrag", ""));				
-			}
-			
-			categoryHandler = new CategoryHandler(connection.getCategories());
-			
-			categoryBudgets = connection.getCategoryBudgets(currentDate.getYear(), currentDate.getMonthOfYear());	
-			paymentHandler.filter(newFilterSettings);
-			
-			toggleAllTabsExceptSettings(false);
-		}
-		catch(Exception e)
-		{
-			Logger.error(e);
-			categoryHandler = new CategoryHandler(null);	
-			showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
-		}
+				ServerConnection connection = new ServerConnection(settings);
+				
+				paymentHandler = new PaymentHandler();
+				paymentHandler.getPayments().addAll(connection.getPayments(currentDate.getYear(), currentDate.getMonthOfYear()));
+				paymentHandler.getPayments().addAll(connection.getRepeatingPayments(currentDate.getYear(), currentDate.getMonthOfYear()));			
+				paymentHandler.sort();
+				if(settings.isRestActivated())
+				{
+					int rest = connection.getRestForAllPreviousMonths(currentDate.getYear(), currentDate.getMonthOfYear());
+					//categoryID 2 = Rest
+					paymentHandler.getPayments().add(new NormalPayment(-1, rest, currentDate.withDayOfMonth(1).toString("yyyy-MM-dd"), 2, "Übertrag", ""));				
+				}
+				
+				categoryHandler = new CategoryHandler(connection.getCategories());
+				
+				categoryBudgets = connection.getCategoryBudgets(currentDate.getYear(), currentDate.getMonthOfYear());	
+				paymentHandler.filter(newFilterSettings);
+				
 
-		refreshAllTabs();		
+				Platform.runLater(() -> {
+					if(modalStage != null)
+					{
+						modalStage.close();
+					}
+					toggleAllTabsExceptSettings(false);
+					refreshAllTabs();
+				});
+			}
+			catch(Exception e)
+			{
+				Logger.error(e);
+				Platform.runLater(() -> {
+					if(modalStage != null)
+					{
+						modalStage.close();
+					}
+					Logger.error(e);
+					categoryHandler = new CategoryHandler(null);	
+					showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
+					refreshAllTabs();
+				});
+			}
+		});	
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/controller/ExportChartController.java b/src/de/deadlocker8/budgetmaster/ui/controller/ExportChartController.java
new file mode 100644
index 0000000000000000000000000000000000000000..14e7cc02eacbf9a44b792f27d0fb4f24eaa1c910
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/ui/controller/ExportChartController.java
@@ -0,0 +1,232 @@
+package de.deadlocker8.budgetmaster.ui.controller;
+
+import java.awt.Desktop;
+import java.io.File;
+import java.io.IOException;
+import java.util.Optional;
+
+import javax.imageio.ImageIO;
+
+import de.deadlocker8.budgetmaster.logic.charts.ChartExportable;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
+import fontAwesome.FontIconType;
+import javafx.embed.swing.SwingFXUtils;
+import javafx.fxml.FXML;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.Label;
+import javafx.scene.control.TextField;
+import javafx.scene.control.TextFormatter;
+import javafx.scene.image.WritableImage;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.paint.Color;
+import javafx.stage.FileChooser;
+import javafx.stage.Stage;
+import logger.Logger;
+import tools.AlertGenerator;
+
+public class ExportChartController
+{
+	@FXML private AnchorPane anchorPaneMain;
+	@FXML private TextField textFieldWidth;
+	@FXML private TextField textFieldHeight;
+	@FXML private Label labelSavePath;
+	@FXML private Button buttonChooseFile;
+	@FXML private Button buttonExport;
+	@FXML private Button buttonCancel;
+	
+	private ChartController controller;
+	private Stage stage;
+	private ChartExportable chart;
+	private File savePath;
+
+	public void init(Stage stage, ChartController controller, ChartExportable chart)
+	{
+		this.controller = controller;
+		this.stage = stage;
+		this.chart = chart;
+		
+		this.savePath = controller.getLastExportPath();
+		if(savePath != null)
+		{
+			labelSavePath.setText(savePath.getAbsolutePath());
+		}
+		
+		textFieldWidth.setText(String.valueOf((int)chart.getSuggestedWidth()));
+		textFieldHeight.setText(String.valueOf((int)chart.getSuggestedHeight()));
+
+		anchorPaneMain.setStyle("-fx-background-color: #F4F4F4;");		
+	
+		buttonChooseFile.setStyle("-fx-background-color: #2E79B9; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;");
+		buttonChooseFile.setGraphic(Helpers.getFontIcon(FontIconType.FOLDER_OPEN, 14, Color.WHITE));
+		
+		buttonExport.setStyle("-fx-background-color: #2E79B9; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;");
+		buttonExport.setGraphic(Helpers.getFontIcon(FontIconType.SAVE, 14, Color.WHITE));
+
+		buttonCancel.setStyle("-fx-background-color: #2E79B9; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 14;");
+		buttonCancel.setGraphic(Helpers.getFontIcon(FontIconType.TIMES, 14, Color.WHITE));		
+		
+		textFieldWidth.setTextFormatter(new TextFormatter<>(c -> {
+			if(c.getControlNewText().isEmpty())
+			{
+				return c;
+			}
+
+			if(c.getControlNewText().matches("[0-9]*"))
+			{
+				return c;
+			}
+			else
+			{
+				return null;
+			}
+		}));
+		
+		textFieldHeight.setTextFormatter(new TextFormatter<>(c -> {
+			if(c.getControlNewText().isEmpty())
+			{
+				return c;
+			}
+
+			if(c.getControlNewText().matches("[0-9]*"))
+			{
+				return c;
+			}
+			else
+			{
+				return null;
+			}
+		}));
+	}	
+
+	public void chooseFile()
+	{
+		FileChooser fileChooser = new FileChooser();
+		fileChooser.setTitle("Diagramm exportieren");
+		FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("PNG (*.png)", "*.png");
+		if(savePath != null)
+		{
+			fileChooser.setInitialDirectory(savePath.getParentFile());
+			fileChooser.setInitialFileName(savePath.getName());
+		}
+		fileChooser.getExtensionFilters().add(extFilter);
+		File file = fileChooser.showSaveDialog(stage);		
+		if(file != null)
+		{		
+			savePath = file;
+			labelSavePath.setText(file.getAbsolutePath());
+		}
+	}
+
+	public void export()
+	{
+		String widthText = textFieldWidth.getText();
+		if(widthText == null || widthText.equals(""))
+		{
+			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Bitte gib eine Breite in Pixeln an.", controller.getControlle().getIcon(), stage, null, false);
+			return;
+		}
+		
+		int width = 0;
+		try 
+		{
+			width = Integer.parseInt(widthText);
+		}
+		catch(Exception e)
+		{
+			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Nur ganzahlige Werte sind für das Feld Breite erlaubt.", controller.getControlle().getIcon(), stage, null, false);
+			return;
+		}
+		
+		String heightText = textFieldHeight.getText();
+		if(heightText == null || heightText.equals(""))
+		{
+			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Bitte gib eine Höhe in Pixeln an.", controller.getControlle().getIcon(), stage, null, false);
+			return;
+		}
+		
+		int height = 0;
+		try 
+		{
+			height = Integer.parseInt(heightText);
+		}
+		catch(Exception e)
+		{
+			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Nur ganzahlige Werte sind für das Feld Höhe erlaubt.", controller.getControlle().getIcon(), stage, null, false);
+			return;
+		}
+
+		if(savePath == null)
+		{
+			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Wähle einen Speicherort für das Diagramm aus.", controller.getControlle().getIcon(), stage, null, false);
+			return;
+		}
+		
+		WritableImage image = chart.export(width, height);		
+		
+		try
+		{
+			ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", savePath);
+			controller.getControlle().showNotification("Diagramm erfolgreich exportiert");	
+			
+			stage.close();			
+			
+			Alert alert = new Alert(AlertType.INFORMATION);
+			alert.setTitle("Erfolgreich erstellt");
+			alert.setHeaderText("");
+			alert.setContentText("Das Diagramm wurde erfolgreich exportiert");			
+			Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow();
+			dialogStage.getIcons().add(controller.getControlle().getIcon());						
+			
+			ButtonType buttonTypeOne = new ButtonType("Ordner öffnen");
+			ButtonType buttonTypeTwo = new ButtonType("Diagramm öffnen");
+			ButtonType buttonTypeThree = new ButtonType("OK");						
+			alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo, buttonTypeThree);
+			
+			Optional<ButtonType> result = alert.showAndWait();						
+			if (result.get() == buttonTypeOne)
+			{
+				try
+				{
+					Desktop.getDesktop().open(new File(savePath.getParent().replace("\\", "/")));
+				}
+				catch(IOException e1)
+				{
+					Logger.error(e1);
+					AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Der Ordner konnte nicht geöffnet werden\n\n" + e1.getMessage(), controller.getControlle().getIcon(), stage, null, false);
+				}
+			}
+			else if (result.get() == buttonTypeTwo)
+			{
+				try
+				{
+					Desktop.getDesktop().open(new File(savePath.getAbsolutePath().replace("\\", "/")));
+				}
+				catch(IOException e1)
+				{
+					Logger.error(e1);
+					AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Das Diagramm konnte nicht geöffnet werden\n\n" + e1.getMessage(), controller.getControlle().getIcon(), stage, null, false);
+				}
+			}
+			else
+			{
+				alert.close();
+			}
+		}
+		catch(IOException e)
+		{
+			Logger.error(e);
+			AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Beim Exportieren des Diagramms ist ein Fehler aufgetreten:\n\n" + e.getMessage(), controller.getControlle().getIcon(), stage, null, false);
+		}
+		
+		stage.close();	
+		controller.setLastExportPath(savePath);
+	}
+	
+	public void cancel()
+	{
+		stage.close();
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/FilterController.java b/src/de/deadlocker8/budgetmaster/ui/controller/FilterController.java
similarity index 82%
rename from src/de/deadlocker8/budgetmaster/ui/FilterController.java
rename to src/de/deadlocker8/budgetmaster/ui/controller/FilterController.java
index 49b2a1505ffed5d3cb1363c181fcc66bb0015d05..c264a28baa2f8bd6bf014f9eff8f3a3acdc75545 100644
--- a/src/de/deadlocker8/budgetmaster/ui/FilterController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/controller/FilterController.java
@@ -1,10 +1,10 @@
-package de.deadlocker8.budgetmaster.ui;
+package de.deadlocker8.budgetmaster.ui.controller;
 
 import java.util.ArrayList;
 
 import de.deadlocker8.budgetmaster.logic.Category;
 import de.deadlocker8.budgetmaster.logic.FilterSettings;
-import fontAwesome.FontIcon;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
 import fontAwesome.FontIconType;
 import javafx.fxml.FXML;
 import javafx.scene.Node;
@@ -12,6 +12,7 @@ import javafx.scene.control.Button;
 import javafx.scene.control.CheckBox;
 import javafx.scene.control.TextField;
 import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
 import javafx.stage.Stage;
 
 public class FilterController
@@ -31,28 +32,17 @@ public class FilterController
 
 	private Stage stage;
 	private Controller controller;
-	private PaymentController paymentController;
 	private FilterSettings filterSetttings;
 
-	public void init(Stage stage, Controller controller, PaymentController paymentController, FilterSettings filterSettings)
+	public void init(Stage stage, Controller controller, FilterSettings filterSettings)
 	{
 		this.stage = stage;
 		this.controller = controller;
-		this.paymentController = paymentController;
 		this.filterSetttings = filterSettings;
 
-		FontIcon iconCancel = new FontIcon(FontIconType.TIMES);
-		iconCancel.setSize(17);
-		iconCancel.setStyle("-fx-text-fill: white");
-		buttonCancel.setGraphic(iconCancel);
-		FontIcon iconReset = new FontIcon(FontIconType.UNDO);
-		iconReset.setSize(17);
-		iconReset.setStyle("-fx-text-fill: white");
-		buttonReset.setGraphic(iconReset);
-		FontIcon iconSave = new FontIcon(FontIconType.FILTER);
-		iconSave.setSize(17);
-		iconSave.setStyle("-fx-text-fill: white");
-		buttonFilter.setGraphic(iconSave);
+		buttonCancel.setGraphic(Helpers.getFontIcon(FontIconType.TIMES, 17, Color.WHITE));
+		buttonReset.setGraphic(Helpers.getFontIcon(FontIconType.UNDO, 17, Color.WHITE));		
+		buttonFilter.setGraphic(Helpers.getFontIcon(FontIconType.FILTER, 17, Color.WHITE));
 
 		buttonCancel.setStyle("-fx-background-color: #2E79B9; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;");
 		buttonReset.setStyle("-fx-background-color: #2E79B9; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;");
@@ -124,16 +114,10 @@ public class FilterController
 			name = null;
 		}
 
-		// get new unfiltered list from server
-		controller.refresh(new FilterSettings());
-
 		FilterSettings newFilterSettings = new FilterSettings(isIncomeAllowed, isPaymentAllowed, isNoRepeatingAllowed, isMonthlyRepeatingAllowed, isRepeatingEveryXDaysAllowed, allowedCategoryIDs, name);
-
 		controller.setFilterSettings(newFilterSettings);
-		controller.getPaymentHandler().filter(newFilterSettings);
-
+		controller.refresh(newFilterSettings);		
 		stage.close();
-		paymentController.getController().refreshAllTabs();
 	}
 
 	public void reset()
diff --git a/src/de/deadlocker8/budgetmaster/ui/HomeController.java b/src/de/deadlocker8/budgetmaster/ui/controller/HomeController.java
similarity index 84%
rename from src/de/deadlocker8/budgetmaster/ui/HomeController.java
rename to src/de/deadlocker8/budgetmaster/ui/controller/HomeController.java
index a17c5d1effb508eaa3c5b2fafacf6e9ca34024ed..5a8dcb30e95b48de692afc4a55dc37ddd4652b2b 100644
--- a/src/de/deadlocker8/budgetmaster/ui/HomeController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/controller/HomeController.java
@@ -1,10 +1,11 @@
-package de.deadlocker8.budgetmaster.ui;
+package de.deadlocker8.budgetmaster.ui.controller;
 
 import java.util.ArrayList;
 
 import de.deadlocker8.budgetmaster.logic.Budget;
 import de.deadlocker8.budgetmaster.logic.CategoryBudget;
-import de.deadlocker8.budgetmaster.logic.Helpers;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
+import de.deadlocker8.budgetmaster.ui.Refreshable;
 import de.deadlocker8.budgetmaster.ui.cells.CategoryBudgetCell;
 import javafx.application.Platform;
 import javafx.beans.value.ChangeListener;
@@ -40,6 +41,10 @@ public class HomeController implements Refreshable
 				return new CategoryBudgetCell(thisController);
 			}
 		});
+		
+		Label labelPlaceholder = new Label("Keine Daten verfügbar");          
+        labelPlaceholder.setStyle("-fx-font-size: 16");
+        listView.setPlaceholder(labelPlaceholder);
 
 		listView.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>()
 		{
@@ -82,7 +87,7 @@ public class HomeController implements Refreshable
 			{
 				currency = controller.getSettings().getCurrency();
 			}
-			labelBudget.setText(String.valueOf(Helpers.NUMBER_FORMAT.format(remaining).replace(".", ",")) + " " + currency);
+			labelBudget.setText(Helpers.getCurrencyString(remaining, currency));
 			if(remaining <= 0)
 			{
 				labelBudget.setStyle("-fx-text-fill: #CC0000");
@@ -91,7 +96,7 @@ public class HomeController implements Refreshable
 			{
 				labelBudget.setStyle("-fx-text-fill: " + controller.getBundle().getString("color.text"));
 			}
-			labelStartBudget.setText("von " + String.valueOf(Helpers.NUMBER_FORMAT.format(budget.getIncomeSum()).replace(".", ",")) + " " + currency + " verbleibend");
+			labelStartBudget.setText("von " + Helpers.getCurrencyString(budget.getIncomeSum(), currency) + " verbleibend");
 			
 			double factor = remaining / budget.getIncomeSum();
 			if(factor < 0)
@@ -112,9 +117,5 @@ public class HomeController implements Refreshable
 	{
 		refreshListView();	
 		refreshCounter();
-		
-		Label labelPlaceholder = new Label("Keine Daten verfügbar");			
-		labelPlaceholder.setStyle("-fx-font-size: 16");
-		listView.setPlaceholder(labelPlaceholder);
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/ModalController.java b/src/de/deadlocker8/budgetmaster/ui/controller/ModalController.java
similarity index 85%
rename from src/de/deadlocker8/budgetmaster/ui/ModalController.java
rename to src/de/deadlocker8/budgetmaster/ui/controller/ModalController.java
index 042c7345a46f1f688df26dc19bf4eaf82a317c42..d86c8cbc3cccfbcb48d12a916d012bdab5c0e31d 100644
--- a/src/de/deadlocker8/budgetmaster/ui/ModalController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/controller/ModalController.java
@@ -1,4 +1,4 @@
-package de.deadlocker8.budgetmaster.ui;
+package de.deadlocker8.budgetmaster.ui.controller;
 
 import javafx.fxml.FXML;
 import javafx.scene.control.Label;
diff --git a/src/de/deadlocker8/budgetmaster/ui/NewCategoryController.java b/src/de/deadlocker8/budgetmaster/ui/controller/NewCategoryController.java
similarity index 76%
rename from src/de/deadlocker8/budgetmaster/ui/NewCategoryController.java
rename to src/de/deadlocker8/budgetmaster/ui/controller/NewCategoryController.java
index d0ab8dd13f7a575c5765ed274ec99d023d3b1534..6b08ff5dfb10bf6e97afb7d54d813a5dfd30d7f8 100644
--- a/src/de/deadlocker8/budgetmaster/ui/NewCategoryController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/controller/NewCategoryController.java
@@ -1,4 +1,4 @@
-package de.deadlocker8.budgetmaster.ui;
+package de.deadlocker8.budgetmaster.ui.controller;
 
 import java.util.ArrayList;
 
@@ -6,9 +6,10 @@ import org.controlsfx.control.PopOver;
 import org.controlsfx.control.PopOver.ArrowLocation;
 
 import de.deadlocker8.budgetmaster.logic.Category;
-import de.deadlocker8.budgetmaster.logic.ExceptionHandler;
-import de.deadlocker8.budgetmaster.logic.ServerConnection;
-import fontAwesome.FontIcon;
+import de.deadlocker8.budgetmaster.logic.serverconnection.ExceptionHandler;
+import de.deadlocker8.budgetmaster.logic.serverconnection.ServerConnection;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
+import de.deadlocker8.budgetmaster.ui.colorPick.ColorView;
 import fontAwesome.FontIconType;
 import javafx.fxml.FXML;
 import javafx.scene.control.Alert.AlertType;
@@ -44,15 +45,9 @@ public class NewCategoryController
 		this.edit = edit;
 		this.color = null;
 		this.category = category;
-
-		FontIcon iconCancel = new FontIcon(FontIconType.TIMES);
-		iconCancel.setSize(17);
-		iconCancel.setStyle("-fx-text-fill: white");
-		buttonCancel.setGraphic(iconCancel);
-		FontIcon iconSave = new FontIcon(FontIconType.SAVE);
-		iconSave.setSize(17);
-		iconSave.setStyle("-fx-text-fill: white");
-		buttonSave.setGraphic(iconSave);
+	
+		buttonCancel.setGraphic(Helpers.getFontIcon(FontIconType.TIMES, 17, Color.WHITE));		
+		buttonSave.setGraphic(Helpers.getFontIcon(FontIconType.SAVE, 17, Color.WHITE));
 
 		buttonCancel.setStyle("-fx-background-color: #2E79B9; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;");
 		buttonSave.setStyle("-fx-background-color: #2E79B9; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;");
@@ -60,23 +55,7 @@ public class NewCategoryController
 		
 		buttonColor.prefWidthProperty().bind(textFieldName.widthProperty());
 		
-		ArrayList<Color> colors = new ArrayList<>();		
-		//grey (light to dark)
-		colors.add(Color.web("#ecf0f1"));
-		colors.add(Color.web("#CCCCCC"));	
-		colors.add(Color.web("#888888"));		
-		colors.add(Color.web("#333333"));				
-		colors.add(Color.rgb(255, 204, 0));		//yellow
-		colors.add(Color.rgb(255, 149, 0)); 	//orange
-		colors.add(Color.rgb(255, 59, 48));		//red
-		colors.add(Color.rgb(169, 3, 41));		//darkred	
-		colors.add(Color.rgb(255, 81, 151));	//pink
-		colors.add(Color.rgb(155, 89, 182));	//purple
-		colors.add(Color.rgb(88, 86, 214));		//darkpurple
-		colors.add(Color.rgb(0, 122, 250));		//blue		
-		colors.add(Color.rgb(90, 200, 250));	//lightblue
-		colors.add(Color.rgb(76, 217, 100));	//lightgreen
-		colors.add(Color.rgb(46, 124, 43));		//darkgreen
+		ArrayList<Color> colors = Helpers.getCategoryColorList();
 		
 		buttonColor.setOnMouseClicked((e) -> {
 
diff --git a/src/de/deadlocker8/budgetmaster/ui/NewPaymentController.java b/src/de/deadlocker8/budgetmaster/ui/controller/NewPaymentController.java
similarity index 87%
rename from src/de/deadlocker8/budgetmaster/ui/NewPaymentController.java
rename to src/de/deadlocker8/budgetmaster/ui/controller/NewPaymentController.java
index 1cdd2f05dc59b1c6400127ab386abcfa60e34f2b..51031c0f7d10537ed92d4cc1e1dca19bf7b97d62 100644
--- a/src/de/deadlocker8/budgetmaster/ui/NewPaymentController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/controller/NewPaymentController.java
@@ -1,4 +1,4 @@
-package de.deadlocker8.budgetmaster.ui;
+package de.deadlocker8.budgetmaster.ui.controller;
 
 import java.time.LocalDate;
 import java.util.ArrayList;
@@ -6,17 +6,16 @@ import java.util.ArrayList;
 import org.joda.time.DateTime;
 
 import de.deadlocker8.budgetmaster.logic.Category;
-import de.deadlocker8.budgetmaster.logic.ExceptionHandler;
-import de.deadlocker8.budgetmaster.logic.Helpers;
 import de.deadlocker8.budgetmaster.logic.NormalPayment;
 import de.deadlocker8.budgetmaster.logic.Payment;
 import de.deadlocker8.budgetmaster.logic.RepeatingPayment;
 import de.deadlocker8.budgetmaster.logic.RepeatingPaymentEntry;
-import de.deadlocker8.budgetmaster.logic.ServerConnection;
+import de.deadlocker8.budgetmaster.logic.serverconnection.ExceptionHandler;
+import de.deadlocker8.budgetmaster.logic.serverconnection.ServerConnection;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
 import de.deadlocker8.budgetmaster.ui.cells.ButtonCategoryCell;
 import de.deadlocker8.budgetmaster.ui.cells.RepeatingDayCell;
 import de.deadlocker8.budgetmaster.ui.cells.SmallCategoryCell;
-import fontAwesome.FontIcon;
 import fontAwesome.FontIconType;
 import javafx.fxml.FXML;
 import javafx.scene.control.Alert.AlertType;
@@ -71,15 +70,9 @@ public class NewPaymentController
 		this.isPayment = isPayment;
 		this.edit = edit;
 		this.payment = payment;
-
-		FontIcon iconCancel = new FontIcon(FontIconType.TIMES);
-		iconCancel.setSize(17);
-		iconCancel.setStyle("-fx-text-fill: white");
-		buttonCancel.setGraphic(iconCancel);
-		FontIcon iconSave = new FontIcon(FontIconType.SAVE);
-		iconSave.setSize(17);
-		iconSave.setStyle("-fx-text-fill: white");
-		buttonSave.setGraphic(iconSave);
+		
+		buttonCancel.setGraphic(Helpers.getFontIcon(FontIconType.TIMES, 17, Color.WHITE));
+		buttonSave.setGraphic(Helpers.getFontIcon(FontIconType.SAVE, 17, Color.WHITE));
 
 		buttonCancel.setStyle("-fx-background-color: #2E79B9; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;");
 		buttonSave.setStyle("-fx-background-color: #2E79B9; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 15;");
@@ -177,26 +170,39 @@ public class NewPaymentController
 			
 			if(payment instanceof RepeatingPaymentEntry)
 			{
-				RepeatingPaymentEntry currentPayment = (RepeatingPaymentEntry)payment;
-				//repeates every x days
-				if(currentPayment.getRepeatInterval() != 0)
+				try
 				{					
-					checkBoxRepeat.setSelected(true);
-					radioButtonPeriod.setSelected(true);
-					toggleRepeatingArea(true);
-					spinnerRepeatingPeriod.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(0, 1000, currentPayment.getRepeatInterval()));
-				}
-				//repeat every month on day x
-				else
-				{
-					checkBoxRepeat.setSelected(true);
-					radioButtonDay.setSelected(true);
-					toggleRepeatingArea(true);
-					comboBoxRepeatingDay.getSelectionModel().select(currentPayment.getRepeatMonthDay());
+					RepeatingPaymentEntry currentPayment = (RepeatingPaymentEntry)payment;
+					
+					ServerConnection connection = new ServerConnection(controller.getSettings());
+					RepeatingPayment repeatingPayment = connection.getRepeatingPayment(currentPayment.getRepeatingPaymentID());
+					datePicker.setValue(LocalDate.parse(repeatingPayment.getDate()));
+					
+					//repeates every x days
+					if(currentPayment.getRepeatInterval() != 0)
+					{					
+						checkBoxRepeat.setSelected(true);
+						radioButtonPeriod.setSelected(true);
+						toggleRepeatingArea(true);
+						spinnerRepeatingPeriod.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(0, 1000, currentPayment.getRepeatInterval()));
+					}
+					//repeat every month on day x
+					else
+					{
+						checkBoxRepeat.setSelected(true);
+						radioButtonDay.setSelected(true);
+						toggleRepeatingArea(true);
+						comboBoxRepeatingDay.getSelectionModel().select(currentPayment.getRepeatMonthDay()-1);
+					}
+					if(currentPayment.getRepeatEndDate() != null)
+					{
+						datePickerEnddate.setValue(LocalDate.parse(currentPayment.getRepeatEndDate()));
+					}
 				}
-				if(currentPayment.getRepeatEndDate() != null)
+				catch(Exception e)
 				{
-					datePickerEnddate.setValue(LocalDate.parse(currentPayment.getRepeatEndDate()));
+					Logger.error(e);
+					controller.showConnectionErrorAlert(ExceptionHandler.getMessageForException(e));
 				}
 			}	
 			else
@@ -223,10 +229,10 @@ public class NewPaymentController
 			LocalDate currentLocalDate = LocalDate.now().withYear(currentDate.getYear())
 			.withMonth(currentDate.getMonthOfYear())
 			.withDayOfMonth(currentDate.getDayOfMonth());
-			datePicker.setValue(currentLocalDate);
-			datePicker.setEditable(false);			
-			//Platform.runLater(()->{datePicker.getEditor().clear();});
+			datePicker.setValue(currentLocalDate);			
 		}
+		
+		datePicker.setEditable(false);
 	}
 
 	public void save()
diff --git a/src/de/deadlocker8/budgetmaster/ui/PaymentController.java b/src/de/deadlocker8/budgetmaster/ui/controller/PaymentController.java
similarity index 82%
rename from src/de/deadlocker8/budgetmaster/ui/PaymentController.java
rename to src/de/deadlocker8/budgetmaster/ui/controller/PaymentController.java
index c4b7cc52c7d3ea25d3030b59c9c2c4c165637487..634a08e0e6cbf62d42436177f6a349709ba379a9 100644
--- a/src/de/deadlocker8/budgetmaster/ui/PaymentController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/controller/PaymentController.java
@@ -1,19 +1,19 @@
-package de.deadlocker8.budgetmaster.ui;
+package de.deadlocker8.budgetmaster.ui.controller;
 
 import java.io.IOException;
 import java.util.ArrayList;
 
 import de.deadlocker8.budgetmaster.logic.Budget;
-import de.deadlocker8.budgetmaster.logic.ExceptionHandler;
 import de.deadlocker8.budgetmaster.logic.FilterSettings;
-import de.deadlocker8.budgetmaster.logic.Helpers;
 import de.deadlocker8.budgetmaster.logic.NormalPayment;
 import de.deadlocker8.budgetmaster.logic.Payment;
 import de.deadlocker8.budgetmaster.logic.RepeatingPayment;
 import de.deadlocker8.budgetmaster.logic.RepeatingPaymentEntry;
-import de.deadlocker8.budgetmaster.logic.ServerConnection;
+import de.deadlocker8.budgetmaster.logic.serverconnection.ExceptionHandler;
+import de.deadlocker8.budgetmaster.logic.serverconnection.ServerConnection;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
+import de.deadlocker8.budgetmaster.ui.Refreshable;
 import de.deadlocker8.budgetmaster.ui.cells.PaymentCell;
-import fontAwesome.FontIcon;
 import fontAwesome.FontIconType;
 import javafx.application.Platform;
 import javafx.beans.value.ChangeListener;
@@ -29,6 +29,7 @@ import javafx.scene.control.ListCell;
 import javafx.scene.control.ListView;
 import javafx.scene.input.MouseEvent;
 import javafx.scene.layout.AnchorPane;
+import javafx.scene.paint.Color;
 import javafx.stage.Modality;
 import javafx.stage.Stage;
 import javafx.util.Callback;
@@ -79,6 +80,10 @@ public class PaymentController implements Refreshable
 				return cell;
 			}
 		});
+		
+		Label labelPlaceholder = new Label("Keine Daten verfügbar");      
+        labelPlaceholder.setStyle("-fx-font-size: 16");
+        listView.setPlaceholder(labelPlaceholder);
 
 		listView.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>()
 		{
@@ -95,23 +100,10 @@ public class PaymentController implements Refreshable
 			}
 		});
 
-		FontIcon iconIncome = new FontIcon(FontIconType.DOWNLOAD);
-		iconIncome.setSize(18);
-		iconIncome.setStyle("-fx-text-fill: white");
-		buttonNewIncome.setGraphic(iconIncome);
-		FontIcon iconFilter = new FontIcon(FontIconType.FILTER);
-		iconFilter.setSize(18);
-		iconFilter.setStyle("-fx-text-fill: white");
-		buttonFilter.setGraphic(iconFilter);
-		FontIcon iconPayment = new FontIcon(FontIconType.UPLOAD);
-		iconPayment.setSize(18);
-		iconPayment.setStyle("-fx-text-fill: white");
-		buttonNewPayment.setGraphic(iconPayment);
-		
-		FontIcon iconWarning = new FontIcon(FontIconType.WARNING);
-		iconWarning.setSize(13);
-		iconWarning.setStyle("-fx-text-fill: " + controller.getBundle().getString("color.text"));
-		labelFilterActive.setGraphic(iconWarning);
+		buttonNewIncome.setGraphic(Helpers.getFontIcon(FontIconType.DOWNLOAD, 18, Color.WHITE));
+		buttonFilter.setGraphic(Helpers.getFontIcon(FontIconType.FILTER, 18, Color.WHITE));
+		buttonNewPayment.setGraphic(Helpers.getFontIcon(FontIconType.UPLOAD, 18, Color.WHITE));
+		labelFilterActive.setGraphic(Helpers.getFontIcon(FontIconType.WARNING, 13, Color.web(controller.getBundle().getString("color.text"))));
 
 		// apply theme
 		anchorPaneMain.setStyle("-fx-background-color: #F4F4F4;");
@@ -141,7 +133,7 @@ public class PaymentController implements Refreshable
 	{
 		try
 		{
-			FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/NewPaymentGUI.fxml"));
+			FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/NewPaymentGUI.fxml"));
 			Parent root = (Parent)fxmlLoader.load();
 			Stage newStage = new Stage();
 			newStage.initOwner(controller.getStage());
@@ -191,8 +183,8 @@ public class PaymentController implements Refreshable
 		{
 			currency = controller.getSettings().getCurrency();
 		}
-		labelIncomes.setText(String.valueOf(Helpers.NUMBER_FORMAT.format(budget.getIncomeSum()).replace(".", ",")) + " " + currency);
-		labelPayments.setText(String.valueOf(Helpers.NUMBER_FORMAT.format(budget.getPaymentSum()).replace(".", ",")) + " " + currency);
+		labelIncomes.setText(Helpers.getCurrencyString(budget.getIncomeSum(), currency));
+		labelPayments.setText(Helpers.getCurrencyString(budget.getPaymentSum(), currency));
 	}
 
 	public void deleteNormalPayment(NormalPayment payment)
@@ -248,7 +240,7 @@ public class PaymentController implements Refreshable
 	{
 		try
 		{
-			FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/FilterGUI.fxml"));
+			FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/FilterGUI.fxml"));
 			Parent root = (Parent)fxmlLoader.load();
 			Stage newStage = new Stage();
 			newStage.initOwner(controller.getStage());
@@ -258,8 +250,8 @@ public class PaymentController implements Refreshable
 			newStage.getIcons().add(controller.getIcon());
 			newStage.setResizable(false);
 			FilterController newController = fxmlLoader.getController();			
-			newController.init(newStage, controller, this, controller.getFilterSettings());
-			newStage.show();
+			newController.init(newStage, controller, controller.getFilterSettings());
+			newStage.showAndWait();
 		}
 		catch(IOException e)
 		{
@@ -286,9 +278,5 @@ public class PaymentController implements Refreshable
 		{
 			labelFilterActive.setVisible(true);
 		}
-
-		Label labelPlaceholder = new Label("Keine Daten verfügbar");		
-		labelPlaceholder.setStyle("-fx-font-size: 16");
-		listView.setPlaceholder(labelPlaceholder);
 	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/controller/ReportController.java b/src/de/deadlocker8/budgetmaster/ui/controller/ReportController.java
new file mode 100644
index 0000000000000000000000000000000000000000..4790ea4e2a084fb0a68e878ac533fca679e01494
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/ui/controller/ReportController.java
@@ -0,0 +1,631 @@
+package de.deadlocker8.budgetmaster.ui.controller;
+
+import java.awt.Desktop;
+import java.io.File;
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Optional;
+
+import de.deadlocker8.budgetmaster.logic.FilterSettings;
+import de.deadlocker8.budgetmaster.logic.Payment;
+import de.deadlocker8.budgetmaster.logic.RepeatingPaymentEntry;
+import de.deadlocker8.budgetmaster.logic.comparators.DateComparator;
+import de.deadlocker8.budgetmaster.logic.comparators.RatingComparator;
+import de.deadlocker8.budgetmaster.logic.report.ColumnFilter;
+import de.deadlocker8.budgetmaster.logic.report.ColumnOrder;
+import de.deadlocker8.budgetmaster.logic.report.ColumnType;
+import de.deadlocker8.budgetmaster.logic.report.ReportGenerator;
+import de.deadlocker8.budgetmaster.logic.report.ReportItem;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
+import de.deadlocker8.budgetmaster.ui.Refreshable;
+import fontAwesome.FontIconType;
+import javafx.application.Platform;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.geometry.Pos;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.CheckBox;
+import javafx.scene.control.Label;
+import javafx.scene.control.TableCell;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableColumn.CellDataFeatures;
+import javafx.scene.control.TableView;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.paint.Color;
+import javafx.stage.FileChooser;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.util.Callback;
+import logger.Logger;
+import tools.AlertGenerator;
+import tools.Worker;
+
+public class ReportController implements Refreshable
+{
+	@FXML private AnchorPane anchorPaneMain;
+	@FXML private Label labelPayments;
+	@FXML private Label labelFilterActive;
+	@FXML private CheckBox checkBoxSplitTable;
+	@FXML private CheckBox checkBoxIncludeCategoryBudgets;
+	@FXML private Button buttonFilter;
+	@FXML private Button buttonGenerate;
+	@FXML private TableView<ReportItem> tableView;
+
+	private Controller controller;
+	private ColumnFilter columnFilter;
+	private File reportPath;
+
+	public void init(Controller controller)
+	{
+		this.controller = controller;
+
+		buttonFilter.setGraphic(Helpers.getFontIcon(FontIconType.FILTER, 18, Color.WHITE));		
+		buttonGenerate.setGraphic(Helpers.getFontIcon(FontIconType.COGS, 18, Color.WHITE));	
+		labelFilterActive.setGraphic(Helpers.getFontIcon(FontIconType.WARNING, 16, Color.web(controller.getBundle().getString("color.text"))));
+		
+		initTable();
+
+		// apply theme
+		anchorPaneMain.setStyle("-fx-background-color: #F4F4F4;");
+		labelFilterActive.setStyle("-fx-text-fill: " + controller.getBundle().getString("color.text"));
+		buttonFilter.setStyle("-fx-background-color: #2E79B9; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;");
+		buttonGenerate.setStyle("-fx-background-color: #2E79B9; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;");
+		checkBoxSplitTable.setStyle("-fx-text-fill: " + controller.getBundle().getString("color.text") + "; -fx-font-size: 14;");
+		checkBoxIncludeCategoryBudgets.setStyle("-fx-text-fill: " + controller.getBundle().getString("color.text") + "; -fx-font-size: 14;");
+
+		refresh();
+	}
+	
+	private void initColumnPosition()
+	{
+	    TableColumn<ReportItem, Integer> columnPosition = new TableColumn<>();
+        columnPosition.setUserData(ColumnType.POSITION);
+        columnPosition.setCellValueFactory(new PropertyValueFactory<ReportItem, Integer>("position"));
+        columnPosition.setStyle("-fx-alignment: CENTER;");
+        
+        HBox hboxColumnPosition = new HBox();
+        hboxColumnPosition.setAlignment(Pos.CENTER);
+        hboxColumnPosition.setSpacing(3);
+        
+        CheckBox checkBoxPositions = new CheckBox();
+        checkBoxPositions.setSelected(true);
+        hboxColumnPosition.getChildren().add(checkBoxPositions);
+
+        Label labelColumnPosition = new Label("Nr.");      
+        hboxColumnPosition.getChildren().add(labelColumnPosition);
+        
+        checkBoxPositions.selectedProperty().addListener((a, b, c)->{
+            String style = c ? "" : "-fx-background-color: salmon;";           
+            hboxColumnPosition.setStyle(style);
+            columnFilter.toggleColumn(ColumnType.POSITION, c);
+        });
+        columnPosition.setGraphic(hboxColumnPosition);
+        tableView.getColumns().add(columnPosition);
+	}
+	
+	private void initColumnDate()
+	{
+	    TableColumn<ReportItem, String> columnDate = new TableColumn<>();
+        columnDate.setUserData(ColumnType.DATE);
+        columnDate.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ReportItem, String>, ObservableValue<String>>()
+        {
+            @Override
+            public ObservableValue<String> call(CellDataFeatures<ReportItem, String> param)
+            {               
+                String dateString = param.getValue().getDate();
+                try
+                {
+                    DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+                    Date date = format.parse(dateString);
+                    DateFormat finalFormat = new SimpleDateFormat("dd.MM.yy");
+                    dateString = finalFormat.format(date);
+                    return new SimpleStringProperty(dateString);
+                }
+                catch(Exception e)
+                {
+                    Logger.error(e);
+                    return null;
+                }
+            }
+        });
+        columnDate.setStyle("-fx-alignment: CENTER;");
+        
+        HBox hboxColumnDate = new HBox();
+        hboxColumnDate.setAlignment(Pos.CENTER);
+        hboxColumnDate.setSpacing(3);
+        
+        CheckBox checkBoxDate = new CheckBox();
+        checkBoxDate.setSelected(true);
+        hboxColumnDate.getChildren().add(checkBoxDate);
+
+        Label labelComlumnDate = new Label("Datum");
+        hboxColumnDate.getChildren().add(labelComlumnDate);        
+        
+        checkBoxDate.selectedProperty().addListener((a, b, c)->{
+            String style = c ? "" : "-fx-background-color: salmon;";           
+            hboxColumnDate.setStyle(style);
+            columnFilter.toggleColumn(ColumnType.DATE, c);
+        });
+        columnDate.setGraphic(hboxColumnDate);
+        columnDate.setComparator(new DateComparator());
+        tableView.getColumns().add(columnDate);
+	}
+	
+	private void initColumnIsRepeating()
+	{
+	    TableColumn<ReportItem, Boolean> columnIsRepeating = new TableColumn<>();
+        columnIsRepeating.setUserData(ColumnType.REPEATING);
+        columnIsRepeating.setCellValueFactory(new PropertyValueFactory<ReportItem, Boolean>("repeating"));
+        columnIsRepeating.setCellFactory(new Callback<TableColumn<ReportItem, Boolean>, TableCell<ReportItem, Boolean>>()
+        {
+            @Override
+            public TableCell<ReportItem, Boolean> call(TableColumn<ReportItem, Boolean> param)
+            {
+                TableCell<ReportItem, Boolean> cell = new TableCell<ReportItem, Boolean>()
+                {
+                    @Override
+                    public void updateItem(Boolean item, boolean empty)
+                    {
+                        if(!empty)
+                        {   
+                            Label labelRepeating = new Label();
+                            if(item)
+                            {
+                                labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.CALENDAR, 16, Color.web(controller.getBundle().getString("color.text"))));
+                            }
+                            else
+                            {
+                                labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.CALENDAR, 16, Color.TRANSPARENT));
+                            }                            
+                            labelRepeating.setStyle("-fx-font-weight: bold; -fx-font-size: 14; -fx-text-fill: #212121");
+                            labelRepeating.setAlignment(Pos.CENTER);
+                            setGraphic(labelRepeating);
+                        }
+                        else
+                        {
+                            setGraphic(null);
+                        }
+                    }
+                };
+                return cell;
+            }
+        });
+        columnIsRepeating.setStyle("-fx-alignment: CENTER;");
+        
+        HBox hboxColumnIsRepeating = new HBox();
+        hboxColumnIsRepeating.setAlignment(Pos.CENTER);
+        hboxColumnIsRepeating.setSpacing(3);
+        
+        CheckBox checkBoxRepeating = new CheckBox();
+        checkBoxRepeating.setSelected(true);
+        hboxColumnIsRepeating.getChildren().add(checkBoxRepeating);
+        
+        Label labelColumnIsRepeating = new Label("Wiederholend");
+        hboxColumnIsRepeating.getChildren().add(labelColumnIsRepeating);
+        
+        checkBoxRepeating.selectedProperty().addListener((a, b, c)->{
+            String style = c ? "" : "-fx-background-color: salmon;";           
+            hboxColumnIsRepeating.setStyle(style);
+            columnFilter.toggleColumn(ColumnType.REPEATING, c);
+        });
+        
+        columnIsRepeating.setGraphic(hboxColumnIsRepeating);        
+        tableView.getColumns().add(columnIsRepeating);
+	}
+	
+	private void initColumnCategory()
+	{
+	    TableColumn<ReportItem, String> columnCategory = new TableColumn<>();
+        columnCategory.setUserData(ColumnType.CATEGORY);
+        columnCategory.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ReportItem, String>, ObservableValue<String>>()
+        {
+            @Override
+            public ObservableValue<String> call(CellDataFeatures<ReportItem, String> param)
+            {
+                String categoryName = param.getValue().getCategory().getName();
+                if(categoryName.equals("NONE"))
+                {
+                    categoryName = "";
+                }
+                return new SimpleStringProperty(categoryName);
+            }
+        });
+        columnCategory.setStyle("-fx-alignment: CENTER;");
+        
+        HBox hboxColumnCategory = new HBox();
+        hboxColumnCategory.setAlignment(Pos.CENTER);
+        hboxColumnCategory.setSpacing(3);
+        
+        CheckBox checkBoxCategory = new CheckBox();
+        checkBoxCategory.setSelected(true);
+        hboxColumnCategory.getChildren().add(checkBoxCategory);
+        
+        Label labelColumnCategory = new Label("Kategorie");
+        hboxColumnCategory.getChildren().add(labelColumnCategory);
+        
+        checkBoxCategory.selectedProperty().addListener((a, b, c)->{
+            String style = c ? "" : "-fx-background-color: salmon;";           
+            hboxColumnCategory.setStyle(style);
+            columnFilter.toggleColumn(ColumnType.CATEGORY, c);
+        });
+        columnCategory.setGraphic(hboxColumnCategory);    
+        tableView.getColumns().add(columnCategory);
+	}
+	
+	private void initColumnName()
+	{
+	    TableColumn<ReportItem, Integer> columnName = new TableColumn<>();
+        columnName.setUserData(ColumnType.NAME);
+        columnName.setCellValueFactory(new PropertyValueFactory<ReportItem, Integer>("name"));
+        columnName.setStyle("-fx-alignment: CENTER;");
+        
+        HBox hboxColumnName = new HBox();
+        hboxColumnName.setAlignment(Pos.CENTER);
+        hboxColumnName.setSpacing(3); 
+        
+        CheckBox checkBoxName = new CheckBox();
+        checkBoxName.setSelected(true);
+        hboxColumnName.getChildren().add(checkBoxName);
+        
+        Label labelColumnName = new Label("Name");
+        hboxColumnName.getChildren().add(labelColumnName);        
+        
+        checkBoxName.selectedProperty().addListener((a, b, c)->{
+            String style = c ? "" : "-fx-background-color: salmon;";           
+            hboxColumnName.setStyle(style);
+            columnFilter.toggleColumn(ColumnType.NAME, c);
+        });
+        columnName.setGraphic(hboxColumnName);
+        tableView.getColumns().add(columnName);
+	}
+	
+	private void initColumnDescription()
+	{
+	    TableColumn<ReportItem, String> columnDescription = new TableColumn<>();
+        columnDescription.setUserData(ColumnType.DESCRIPTION);
+        columnDescription.setCellValueFactory(new PropertyValueFactory<ReportItem, String>("description"));
+        columnDescription.setStyle("-fx-alignment: CENTER;");
+        
+        HBox hboxColumnDescription = new HBox();
+        hboxColumnDescription.setAlignment(Pos.CENTER);
+        hboxColumnDescription.setSpacing(3); 
+        
+        CheckBox checkBoxDescription = new CheckBox();
+        checkBoxDescription.setSelected(true);
+        hboxColumnDescription.getChildren().add(checkBoxDescription);
+        
+        Label labelColumnDescription = new Label("Notiz");
+        hboxColumnDescription.getChildren().add(labelColumnDescription);
+        
+        checkBoxDescription.selectedProperty().addListener((a, b, c)->{
+            String style = c ? "" : "-fx-background-color: salmon;";           
+            hboxColumnDescription.setStyle(style);
+            columnFilter.toggleColumn(ColumnType.DESCRIPTION, c);
+        });
+        columnDescription.setGraphic(hboxColumnDescription);
+        tableView.getColumns().add(columnDescription);
+	}
+	
+	private void initColumnRating()
+	{
+	    TableColumn<ReportItem, Integer> columnRating = new TableColumn<>();
+        columnRating.setUserData(ColumnType.RATING);
+        columnRating.setCellValueFactory(new PropertyValueFactory<ReportItem, Integer>("amount"));
+        columnRating.setCellFactory(new Callback<TableColumn<ReportItem, Integer>, TableCell<ReportItem, Integer>>()
+        {
+            @Override
+            public TableCell<ReportItem, Integer> call(TableColumn<ReportItem, Integer> param)
+            {
+                TableCell<ReportItem, Integer> cell = new TableCell<ReportItem, Integer>()
+                {
+                    @Override
+                    public void updateItem(Integer item, boolean empty)
+                    {
+                        if(!empty)
+                        {                               
+                            Label labelRepeating = new Label();
+                            if(item > 0)
+                            {
+                                labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.PLUS, 14, Color.web(controller.getBundle().getString("color.text"))));
+                            }
+                            else
+                            {
+                                labelRepeating.setGraphic(Helpers.getFontIcon(FontIconType.MINUS, 14, Color.web(controller.getBundle().getString("color.text"))));
+                            }
+                            labelRepeating.setStyle("-fx-font-weight: bold; -fx-font-size: 14; -fx-text-fill: #212121");
+                            labelRepeating.setAlignment(Pos.CENTER);
+                            setGraphic(labelRepeating);
+                        }
+                        else
+                        {
+                            setGraphic(null);
+                        }
+                    }
+                };
+                return cell;
+            }
+        });
+        columnRating.setStyle("-fx-alignment: CENTER;");
+        
+        HBox hboxColumnRating = new HBox();
+        hboxColumnRating.setAlignment(Pos.CENTER);
+        hboxColumnRating.setSpacing(3);         
+        
+        CheckBox checkBoxRating = new CheckBox();
+        checkBoxRating.setSelected(true);
+        hboxColumnRating.getChildren().add(checkBoxRating);
+        
+        Label labelColumnRating = new Label("Bewertung");
+        hboxColumnRating.getChildren().add(labelColumnRating);
+        
+        checkBoxRating.selectedProperty().addListener((a, b, c)->{
+            String style = c ? "" : "-fx-background-color: salmon;";           
+            hboxColumnRating.setStyle(style);
+            columnFilter.toggleColumn(ColumnType.RATING, c);
+        });
+        columnRating.setGraphic(hboxColumnRating);
+        columnRating.setComparator(new RatingComparator());
+        tableView.getColumns().add(columnRating);
+	}
+	
+	private void initColumnAmount()
+	{
+	    TableColumn<ReportItem, String> columnAmount = new TableColumn<>();
+        columnAmount.setUserData(ColumnType.AMOUNT);
+        columnAmount.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ReportItem, String>, ObservableValue<String>>()
+        {
+            @Override
+            public ObservableValue<String> call(CellDataFeatures<ReportItem, String> param)
+            {
+                StringProperty value = new SimpleStringProperty();
+                double amount = param.getValue().getAmount() / 100.0;
+                value.set(Helpers.getCurrencyString(amount, controller.getSettings().getCurrency()));
+                return value;
+            }
+        });
+        columnAmount.setStyle("-fx-alignment: CENTER;");
+        
+        HBox hboxColumnAmount = new HBox();
+        hboxColumnAmount.setAlignment(Pos.CENTER);
+        hboxColumnAmount.setSpacing(3);
+        
+        CheckBox checkBoxAmount = new CheckBox();
+        checkBoxAmount.setSelected(true);
+        hboxColumnAmount.getChildren().add(checkBoxAmount);
+        
+        Label labelColumnAmount = new Label("Betrag");
+        hboxColumnAmount.getChildren().add(labelColumnAmount);
+        
+        checkBoxAmount.selectedProperty().addListener((a, b, c)->{
+            String style = c ? "" : "-fx-background-color: salmon;";           
+            hboxColumnAmount.setStyle(style);
+            columnFilter.toggleColumn(ColumnType.AMOUNT, c);
+        });
+        columnAmount.setGraphic(hboxColumnAmount);
+        tableView.getColumns().add(columnAmount);
+	}
+
+	private void initTable()
+	{
+		columnFilter = new ColumnFilter();
+		for(ColumnType type : ColumnType.values())
+		{
+			columnFilter.addColumn(type);
+		}
+		
+		Label labelPlaceholder = new Label("Keine Daten verfügbar");
+		labelPlaceholder.setStyle("-fx-font-size: 16");
+		tableView.setPlaceholder(labelPlaceholder);		
+
+		tableView.setFixedCellSize(26);
+		
+		initColumnPosition();
+		initColumnDate();
+		initColumnIsRepeating();
+		initColumnCategory();
+		initColumnName();
+		initColumnDescription();
+		initColumnRating();
+		initColumnAmount();
+	}
+
+	public void filter()
+	{
+		try
+		{
+			FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/FilterGUI.fxml"));
+			Parent root = (Parent)fxmlLoader.load();
+			Stage newStage = new Stage();
+			newStage.initOwner(controller.getStage());
+			newStage.initModality(Modality.APPLICATION_MODAL);
+			newStage.setTitle("Filter");
+			newStage.setScene(new Scene(root));
+			newStage.getIcons().add(controller.getIcon());
+			newStage.setResizable(false);
+			FilterController newController = fxmlLoader.getController();
+			newController.init(newStage, controller, controller.getFilterSettings());
+			newStage.show();
+		}
+		catch(IOException e)
+		{
+			Logger.error(e);
+		}
+	}
+
+	private ArrayList<ReportItem> createReportItems(ArrayList<Payment> payments)
+	{
+		ArrayList<ReportItem> reportItems = new ArrayList<>();
+		for(int i = 0; i < payments.size(); i++)
+		{
+			Payment currentPayment = payments.get(i);
+			ReportItem reportItem = new ReportItem();
+			reportItem.setPosition(i + 1);
+			reportItem.setDate(currentPayment.getDate());
+			reportItem.setAmount(currentPayment.getAmount());
+			reportItem.setDescription(currentPayment.getDescription());
+			reportItem.setName(currentPayment.getName());
+			reportItem.setRepeating(currentPayment instanceof RepeatingPaymentEntry);
+			reportItem.setCategory(controller.getCategoryHandler().getCategory(currentPayment.getCategoryID()));
+
+			reportItems.add(reportItem);
+		}
+
+		return reportItems;
+	}
+
+	private void refreshTableView()
+	{
+		tableView.getItems().clear();
+
+		ArrayList<Payment> payments = controller.getPaymentHandler().getPayments();		
+		if(payments != null)
+		{
+			ArrayList<ReportItem> reportItems = createReportItems(payments);
+			ObservableList<ReportItem> objectsForTable = FXCollections.observableArrayList(reportItems);
+			tableView.setItems(objectsForTable);
+		}
+	}
+
+	@SuppressWarnings("rawtypes")
+	public void generate()
+	{
+		ColumnOrder columnOrder = new ColumnOrder();
+		for(TableColumn currentColumn : tableView.getColumns())
+		{
+			ColumnType currentType = (ColumnType)currentColumn.getUserData();			
+			if(columnFilter.containsColumn(currentType))
+			{
+				columnOrder.addColumn(currentType);
+			}
+		}		
+		
+		FileChooser fileChooser = new FileChooser();
+		fileChooser.setTitle("Bericht speichern");
+		FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("PDF (*.pdf)", "*.pdf");
+		if(reportPath != null)
+		{
+			fileChooser.setInitialDirectory(reportPath.getParentFile());
+			fileChooser.setInitialFileName(reportPath.getName());
+		}
+		fileChooser.getExtensionFilters().add(extFilter);
+		File file = fileChooser.showSaveDialog(controller.getStage());		
+		if(file != null)
+		{		
+			reportPath = file;
+			ReportGenerator reportGenerator = new ReportGenerator(new ArrayList<ReportItem>(tableView.getItems()),
+																controller.getCategoryBudgets(),
+																columnOrder,
+																checkBoxSplitTable.isSelected(), 
+																checkBoxIncludeCategoryBudgets.isSelected(),																
+																file,
+																controller.getSettings().getCurrency(),
+																controller.getCurrentDate());
+			
+			Stage modalStage = Helpers.showModal("Vorgang läuft", "Der Monatsbericht wird erstellt, bitte warten...", controller.getStage(), controller.getIcon());
+
+			Worker.runLater(() -> {
+				try
+				{
+					reportGenerator.generate();					
+
+					Platform.runLater(() -> {
+						if(modalStage != null)
+						{
+							modalStage.close();
+						}
+						
+						controller.showNotification("Bericht erfolgreich gespeichert");	
+						
+						Alert alert = new Alert(AlertType.INFORMATION);
+						alert.setTitle("Erfolgreich erstellt");
+						alert.setHeaderText("");
+						alert.setContentText("Der Monatsbericht wurde erfolgreich erstellt");			
+						Stage dialogStage = (Stage)alert.getDialogPane().getScene().getWindow();
+						dialogStage.getIcons().add(controller.getIcon());						
+						
+						ButtonType buttonTypeOne = new ButtonType("Ordner öffnen");
+						ButtonType buttonTypeTwo = new ButtonType("Bericht öffnen");
+						ButtonType buttonTypeThree = new ButtonType("OK");						
+						alert.getButtonTypes().setAll(buttonTypeOne, buttonTypeTwo, buttonTypeThree);
+						
+						Optional<ButtonType> result = alert.showAndWait();						
+						if (result.get() == buttonTypeOne)
+						{
+							try
+							{
+								Desktop.getDesktop().open(new File(file.getParent().replace("\\", "/")));
+							}
+							catch(IOException e1)
+							{
+								Logger.error(e1);
+								AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Der Ordner konnte nicht geöffnet werden\n\n" + e1.getMessage(), controller.getIcon(), controller.getStage(), null, false);
+							}
+						}
+						else if (result.get() == buttonTypeTwo)
+						{
+							try
+							{
+								Desktop.getDesktop().open(new File(file.getAbsolutePath().replace("\\", "/")));
+							}
+							catch(IOException e1)
+							{
+								Logger.error(e1);
+								AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Der Bericht konnte nicht geöffnet werden\n\n" + e1.getMessage(), controller.getIcon(), controller.getStage(), null, false);
+							}
+						}
+						else
+						{
+							alert.close();
+						}
+					});
+				}
+				catch(Exception e)
+				{
+					Logger.error(e);
+					Platform.runLater(() -> {
+						if(modalStage != null)
+						{
+							modalStage.close();
+						}
+						AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Beim Erstellen des Monatsberichts ist ein Fehler aufgetreten:\n\n" + e.getMessage(), controller.getIcon(), controller.getStage(), null, false);
+					});
+				}
+			});			
+		}
+	}
+
+	public Controller getController()
+	{
+		return controller;
+	}
+
+	@Override
+	public void refresh()
+	{
+		if(controller.getFilterSettings().equals(new FilterSettings()))
+		{
+			labelFilterActive.setVisible(false);
+		}
+		else
+		{
+			labelFilterActive.setVisible(true);
+		}
+		
+		refreshTableView();
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/SettingsController.java b/src/de/deadlocker8/budgetmaster/ui/controller/SettingsController.java
similarity index 82%
rename from src/de/deadlocker8/budgetmaster/ui/SettingsController.java
rename to src/de/deadlocker8/budgetmaster/ui/controller/SettingsController.java
index 76e98b0784ff7d04fcf25ccf4e5e9b44328b4803..34993a4d68c4e92cded299e56cda8413a8723971 100644
--- a/src/de/deadlocker8/budgetmaster/ui/SettingsController.java
+++ b/src/de/deadlocker8/budgetmaster/ui/controller/SettingsController.java
@@ -1,21 +1,18 @@
-package de.deadlocker8.budgetmaster.ui;
+package de.deadlocker8.budgetmaster.ui.controller;
 
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Optional;
 
-import de.deadlocker8.budgetmaster.logic.ExceptionHandler;
-import de.deadlocker8.budgetmaster.logic.Helpers;
-import de.deadlocker8.budgetmaster.logic.ServerConnection;
 import de.deadlocker8.budgetmaster.logic.Settings;
-import de.deadlocker8.budgetmaster.logic.Utils;
+import de.deadlocker8.budgetmaster.logic.serverconnection.ExceptionHandler;
+import de.deadlocker8.budgetmaster.logic.serverconnection.ServerConnection;
+import de.deadlocker8.budgetmaster.logic.utils.FileHelper;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
 import de.deadlocker8.budgetmasterserver.logic.Database;
 import javafx.application.Platform;
 import javafx.fxml.FXML;
-import javafx.fxml.FXMLLoader;
-import javafx.scene.Parent;
-import javafx.scene.Scene;
 import javafx.scene.control.Alert;
 import javafx.scene.control.Alert.AlertType;
 import javafx.scene.control.Button;
@@ -29,7 +26,6 @@ import javafx.scene.control.TextInputDialog;
 import javafx.scene.control.ToggleGroup;
 import javafx.scene.layout.AnchorPane;
 import javafx.stage.FileChooser;
-import javafx.stage.Modality;
 import javafx.stage.Stage;
 import logger.Logger;
 import tools.AlertGenerator;
@@ -42,6 +38,8 @@ import tools.Worker;
 public class SettingsController
 {
 	@FXML private AnchorPane anchorPaneMain;
+	@FXML private Label labelClientSecret;
+	@FXML private TextField textFieldClientSecret;
 	@FXML private TextField textFieldURL;
 	@FXML private Label labelURL;
 	@FXML private TextField textFieldSecret;
@@ -61,7 +59,11 @@ public class SettingsController
 	public void init(Controller controller)
 	{
 		this.controller = controller;
-		if(controller.getSettings() != null)
+		
+		textFieldClientSecret.setText("******");
+		radioButtonRestDeactivated.setSelected(true);
+		
+		if(controller.getSettings().isComplete())
 		{
 			textFieldURL.setText(controller.getSettings().getUrl());
 			textFieldSecret.setText("******");
@@ -78,6 +80,7 @@ public class SettingsController
 		}
 
 		anchorPaneMain.setStyle("-fx-background-color: #F4F4F4;");
+		labelClientSecret.setStyle("-fx-text-fill: " + controller.getBundle().getString("color.text"));
 		labelSecret.setStyle("-fx-text-fill: " + controller.getBundle().getString("color.text"));
 		labelURL.setStyle("-fx-text-fill: " + controller.getBundle().getString("color.text"));
 		labelCurrency.setStyle("-fx-text-fill: " + controller.getBundle().getString("color.text"));
@@ -114,9 +117,17 @@ public class SettingsController
 
 	public void save()
 	{
+		String clientSecret = textFieldClientSecret.getText().trim();
 		String url = textFieldURL.getText().trim();
 		String secret = textFieldSecret.getText().trim();
 		String currency = textFieldCurrency.getText().trim();
+		
+		if(clientSecret == null || clientSecret.equals(""))
+		{
+			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Feld für das Client Passwort darf nicht leer sein!", controller.getIcon(), controller.getStage(), null, false);
+			return;
+		}
+		
 		if(url == null || url.equals(""))
 		{
 			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Feld für die Server URL darf nicht leer sein!", controller.getIcon(), controller.getStage(), null, false);
@@ -148,8 +159,13 @@ public class SettingsController
 		}
 		setTextAreaTrustedHosts(trustedHosts);
 
-		if(controller.getSettings() != null)
+		if(controller.getSettings().isComplete())
 		{
+			if(!clientSecret.equals("******"))
+			{
+				controller.getSettings().setClientSecret(HashUtils.hash(clientSecret, Helpers.SALT));
+			}
+			
 			if(!secret.equals("******"))
 			{
 				controller.getSettings().setSecret(HashUtils.hash(secret, Helpers.SALT));
@@ -162,8 +178,25 @@ public class SettingsController
 		else
 		{
 			Settings settings = new Settings();
-			settings.setUrl(url);
-			settings.setSecret(HashUtils.hash(secret, Helpers.SALT));
+			
+			if(!clientSecret.equals("******"))
+			{
+				settings.setClientSecret(HashUtils.hash(clientSecret, Helpers.SALT));
+			}
+			else
+			{
+				settings.setClientSecret(controller.getSettings().getClientSecret());
+			}
+			
+			if(!secret.equals("******"))
+			{
+				settings.setSecret(HashUtils.hash(secret, Helpers.SALT));
+			}
+			else
+			{
+				settings.setSecret(controller.getSettings().getSecret());
+			}
+			settings.setUrl(url);			
 			settings.setCurrency(currency);
 			settings.setRestActivated(radioButtonRestActivated.isSelected());
 			settings.setTrustedHosts(trustedHosts);
@@ -172,7 +205,7 @@ public class SettingsController
 
 		try
 		{
-			Utils.saveSettings(controller.getSettings());
+			FileHelper.saveSettings(controller.getSettings());
 		}
 		catch(IOException e)
 		{
@@ -180,6 +213,7 @@ public class SettingsController
 			AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Beim Speichern der Einstellungen ist ein Fehler aufgetreten", controller.getIcon(), controller.getStage(), null, false);
 		}
 
+		textFieldClientSecret.setText("******");
 		textFieldSecret.setText("******");
 
 		controller.refresh(controller.getFilterSettings());
@@ -195,21 +229,21 @@ public class SettingsController
 		File file = fileChooser.showSaveDialog(controller.getStage());
 		if(file != null)
 		{
-			Stage modalStage = showModal("Vorgang läuft", "Die Datenbank wird exportiert, bitte warten...");
+			Stage modalStage = Helpers.showModal("Vorgang läuft", "Die Datenbank wird exportiert, bitte warten...", controller.getStage(), controller.getIcon());
 
 			Worker.runLater(() -> {
 				try
 				{
 					ServerConnection connection = new ServerConnection(controller.getSettings());
 					String databaseJSON = connection.exportDatabase();
-					Utils.saveDatabaseJSON(file, databaseJSON);
+					FileHelper.saveDatabaseJSON(file, databaseJSON);
 
 					Platform.runLater(() -> {
 						if(modalStage != null)
 						{
 							modalStage.close();
 						}
-						AlertGenerator.showAlert(AlertType.INFORMATION, "Erfolgreich exportiert", "", "Die Datenbank wurder erfolgreich exportiert.", controller.getIcon(), controller.getStage(), null, false);
+						AlertGenerator.showAlert(AlertType.INFORMATION, "Erfolgreich exportiert", "", "Die Datenbank wurde erfolgreich exportiert.", controller.getIcon(), controller.getStage(), null, false);
 					});
 				}
 				catch(Exception e)
@@ -239,7 +273,7 @@ public class SettingsController
 			Database database;
 			try
 			{
-				database = Utils.loadDatabaseJSON(file);
+				database = FileHelper.loadDatabaseJSON(file);
 				if(database.getCategories() == null || database.getNormalPayments() == null || database.getRepeatingPayments() == null)
 				{
 					AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Die angegebene Datei enthält kein gültiges BudgetMaster-Datenformat und kann daher nicht importiert werden.", controller.getIcon(), controller.getStage(), null, false);
@@ -253,7 +287,7 @@ public class SettingsController
 				return;
 			}
 
-			Stage modalStage = showModal("Vorgang läuft", "Die Datenbank wird importiert, bitte warten...");
+			Stage modalStage = Helpers.showModal("Vorgang läuft", "Die Datenbank wird importiert, bitte warten...", controller.getStage(), controller.getIcon());
 
 			Worker.runLater(() -> {
 				try
@@ -332,7 +366,7 @@ public class SettingsController
 		{
 			if(result.get().equals(verificationCode))
 			{
-				Stage modalStage = showModal("Vorgang läuft", "Die Datenbank wird gelöscht, bitte warten...");
+				Stage modalStage = Helpers.showModal("Vorgang läuft", "Die Datenbank wird gelöscht, bitte warten...", controller.getStage(), controller.getIcon());
 
 				Worker.runLater(() -> {
 					try
@@ -370,30 +404,4 @@ public class SettingsController
 			}
 		}
 	}
-
-	private Stage showModal(String title, String message)
-	{
-		try
-		{
-			FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/Modal.fxml"));
-			Parent root = (Parent)fxmlLoader.load();
-			Stage newStage = new Stage();
-			newStage.initOwner(controller.getStage());
-			newStage.initModality(Modality.APPLICATION_MODAL);
-			newStage.setTitle(title);
-			newStage.setScene(new Scene(root));
-			newStage.getIcons().add(controller.getIcon());
-			newStage.setResizable(false);
-			ModalController newController = fxmlLoader.getController();
-			newController.init(newStage, message);
-			newStage.show();
-
-			return newStage;
-		}
-		catch(IOException e)
-		{
-			Logger.error(e);
-			return null;
-		}
-	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/controller/SplashScreenController.java b/src/de/deadlocker8/budgetmaster/ui/controller/SplashScreenController.java
new file mode 100644
index 0000000000000000000000000000000000000000..5c2efed54bb7f3915b404fff847525345184aa2d
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/ui/controller/SplashScreenController.java
@@ -0,0 +1,153 @@
+package de.deadlocker8.budgetmaster.ui.controller;
+
+import java.io.IOException;
+import java.util.ResourceBundle;
+
+import de.deadlocker8.budgetmaster.logic.Settings;
+import de.deadlocker8.budgetmaster.logic.utils.FileHelper;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
+import fontAwesome.FontIconType;
+import javafx.application.Platform;
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.geometry.Insets;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.PasswordField;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.input.KeyCode;
+import javafx.scene.paint.Color;
+import javafx.stage.Stage;
+import logger.Logger;
+import tools.AlertGenerator;
+import tools.HashUtils;
+
+public class SplashScreenController
+{
+	@FXML private ImageView imageViewLogo;
+	@FXML private Label labelVersion;
+	@FXML private PasswordField textFieldPassword;
+	@FXML private Button buttonLogin;
+	
+	private ResourceBundle bundle;
+	private Stage stage;
+	private Image icon;
+	private Settings settings;
+	private boolean isFirstStart;
+
+	public void init(Stage stage, Image icon, ResourceBundle bundle)
+	{
+		this.stage = stage;
+		this.icon = icon;
+		this.bundle = bundle;
+		
+		imageViewLogo.setImage(icon);
+		
+		labelVersion.setText("v" + bundle.getString("version.name"));
+	
+		buttonLogin.setGraphic(Helpers.getFontIcon(FontIconType.SIGN_IN, 18, Color.WHITE));
+		buttonLogin.setStyle("-fx-background-color: #2E79B9; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: 16;");
+		buttonLogin.setPadding(new Insets(3, 7, 3, 7));		
+		
+		textFieldPassword.setOnKeyReleased((event)->{
+			if(event.getCode() == KeyCode.ENTER)
+			{
+				login();
+			}
+		});
+		
+		settings = FileHelper.loadSettings();
+		if(settings == null)
+		{	
+			settings = new Settings();
+			//first start of budgetmaster
+			Platform.runLater(() -> {
+				AlertGenerator.showAlert(AlertType.INFORMATION, "Willkommen", "Willkommen beim BudgetMaster", "Dies scheint dein erster Besuch zu sein, da noch keine Einstellungen existieren.\nDamit es losgehen kann, überlege dir ein Passwort und trage es in das Passwortfeld ein.\n\n(Hinweis: Das Passwort kann später jederzeit geändert werden.)\n ", icon, stage, null, false);
+			});
+			isFirstStart = true;
+		}
+		else
+		{
+			if(settings.getClientSecret() == null)
+			{
+				//compatibility (settings exists but from older version without clientSecret)
+				Platform.runLater(() -> {
+					AlertGenerator.showAlert(AlertType.INFORMATION, "Willkommen", "Willkommen beim BudgetMaster", "Deine Einstellungsdatei ist veraltet und muss aktualisert werden.\nSeit Version v1.3.0 wird ein Passwort benötigt, um BudgetMaster zu entsperren. Damit es losgehen kann, überlege dir ein Passwort und trage es in das Passwortfeld ein.\n\n(Hinweis: Das Passwort kann später jederzeit geändert werden.)\n ", icon, stage, null, false);
+				});
+				isFirstStart = true;
+			}
+			else
+			{
+				isFirstStart = false;
+			}
+		}
+	}
+	
+	public void login()
+	{
+		String password = textFieldPassword.getText().trim();
+		if(password == null || password.isEmpty())
+		{
+			AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Bitte gib dein Passwort ein.", icon, stage, null, false);
+			return;
+		}		
+	
+		if(isFirstStart)
+		{
+			//save to settings
+			settings.setClientSecret(HashUtils.hash(password, Helpers.SALT));
+			try
+			{
+				FileHelper.saveSettings(settings);
+				
+				stage.close();
+				openBudgetMaster();	
+			}
+			catch(IOException e)
+			{
+				Logger.error(e);
+				AlertGenerator.showAlert(AlertType.ERROR, "Fehler", "", "Beim Speichern des Passworts ist ein Fehler aufgetreten.", icon, stage, null, false);
+			}
+		}
+		else
+		{			
+			//check password
+			if(!HashUtils.hash(password, Helpers.SALT).equals(settings.getClientSecret()))
+			{
+				AlertGenerator.showAlert(AlertType.WARNING, "Warnung", "", "Das Passwort ist nicht korrekt.", icon, stage, null, false);
+				return;
+			}
+			
+			stage.close();
+			openBudgetMaster();	
+		}
+	}
+	
+	private void openBudgetMaster()
+	{
+		try
+		{
+			FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/de/deadlocker8/budgetmaster/ui/fxml/GUI.fxml"));
+			Parent root = (Parent)fxmlLoader.load();
+			Stage newStage = new Stage();
+			newStage.setTitle(bundle.getString("app.name"));
+			newStage.setScene(new Scene(root, 650, 650));
+			newStage.getIcons().add(icon);			
+			newStage.setResizable(true);
+			newStage.setMinHeight(650);
+			newStage.setMinWidth(610);
+			newStage.getScene().getStylesheets().add("/de/deadlocker8/budgetmaster/ui/style.css");
+			Controller newController = fxmlLoader.getController();
+			newController.init(newStage, bundle, settings);
+			newStage.show();
+		}
+		catch(IOException e)
+		{
+			Logger.error(e);
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmaster/ui/CategoryTab.fxml b/src/de/deadlocker8/budgetmaster/ui/fxml/CategoryTab.fxml
similarity index 97%
rename from src/de/deadlocker8/budgetmaster/ui/CategoryTab.fxml
rename to src/de/deadlocker8/budgetmaster/ui/fxml/CategoryTab.fxml
index 39c008340c0e91fe20ecb768f1cc8bb0dcda7030..308c45777eb5722cf94af3f6ade82e2659f4680b 100644
--- a/src/de/deadlocker8/budgetmaster/ui/CategoryTab.fxml
+++ b/src/de/deadlocker8/budgetmaster/ui/fxml/CategoryTab.fxml
@@ -7,7 +7,7 @@
 <?import javafx.scene.layout.VBox?>
 <?import javafx.scene.text.Font?>
 
-<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.CategoryController">
+<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.CategoryController">
    <children>
       <VBox alignment="TOP_CENTER" layoutY="24.0" prefHeight="562.0" prefWidth="772.0" spacing="25.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="25.0">
          <children>
diff --git a/src/de/deadlocker8/budgetmaster/ui/ChartTab.fxml b/src/de/deadlocker8/budgetmaster/ui/fxml/ChartTab.fxml
similarity index 86%
rename from src/de/deadlocker8/budgetmaster/ui/ChartTab.fxml
rename to src/de/deadlocker8/budgetmaster/ui/fxml/ChartTab.fxml
index 7ffa60128c56a3f29617e506560b0eef6f6963ad..608f46d85e4a54e45443bb67844ed7a22d49fdbb 100644
--- a/src/de/deadlocker8/budgetmaster/ui/ChartTab.fxml
+++ b/src/de/deadlocker8/budgetmaster/ui/fxml/ChartTab.fxml
@@ -13,7 +13,7 @@
 <?import javafx.scene.layout.VBox?>
 <?import javafx.scene.text.Font?>
 
-<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.ChartController">
+<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.ChartController">
    <children>
       <Accordion fx:id="accordion" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="25.0">
         <panes>
@@ -44,7 +44,7 @@
                                        </font>
                                     </Label>
                                     <DatePicker fx:id="datePickerEnd" />
-                                    <Button fx:id="buttonChartCategoriesShow" mnemonicParsing="false" onAction="#chartCategoriesShow">
+                                    <Button fx:id="buttonChartCategoriesShow" mnemonicParsing="false" onAction="#buttonChartCategoriesShow">
                                        <font>
                                           <Font name="System Bold" size="12.0" />
                                        </font>
@@ -52,6 +52,11 @@
                                           <Insets left="15.0" />
                                        </HBox.margin>
                                     </Button>
+                                    <Button fx:id="buttonChartCategoriesExport" mnemonicParsing="false" onAction="#chartCategoriesExport">
+                                       <font>
+                                          <Font name="System Bold" size="12.0" />
+                                       </font>
+                                    </Button>
                                  </children>
                                  <HBox.margin>
                                     <Insets left="15.0" />
@@ -126,6 +131,14 @@
                                           <Insets left="10.0" />
                                        </HBox.margin>
                                     </Button>
+                                    <Button fx:id="buttonChartMonthExport" mnemonicParsing="false" onAction="#chartMonthExport">
+                                       <font>
+                                          <Font name="System Bold" size="12.0" />
+                                       </font>
+                                       <HBox.margin>
+                                          <Insets left="10.0" />
+                                       </HBox.margin>
+                                    </Button>
                                  </children>
                               </HBox>
                            </children>
diff --git a/src/de/deadlocker8/budgetmaster/ui/fxml/ExportChartGUI.fxml b/src/de/deadlocker8/budgetmaster/ui/fxml/ExportChartGUI.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..1b0ad1292b4d9f91aeb8a40e0eccbdec22969c48
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/ui/fxml/ExportChartGUI.fxml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.control.TextField?>
+<?import javafx.scene.layout.AnchorPane?>
+<?import javafx.scene.layout.HBox?>
+<?import javafx.scene.layout.VBox?>
+<?import javafx.scene.text.Font?>
+
+<AnchorPane fx:id="anchorPaneMain" prefHeight="200.0" prefWidth="450.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.ExportChartController">
+   <children>
+      <VBox AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
+         <children>
+            <HBox prefHeight="125.0" prefWidth="372.0" spacing="15.0">
+               <children>
+                  <VBox alignment="TOP_RIGHT" prefHeight="125.0" prefWidth="99.0" spacing="15.0">
+                     <children>
+                        <Label text="Breite:">
+                           <font>
+                              <Font name="System Bold" size="16.0" />
+                           </font>
+                        </Label>
+                        <Label text="Höhe:">
+                           <font>
+                              <Font name="System Bold" size="16.0" />
+                           </font>
+                        </Label>
+                        <Label prefHeight="30.0" prefWidth="92.0" text="Speicherort:">
+                           <font>
+                              <Font name="System Bold" size="16.0" />
+                           </font>
+                        </Label>
+                     </children>
+                     <HBox.margin>
+                        <Insets />
+                     </HBox.margin>
+                  </VBox>
+                  <VBox prefHeight="4.0" prefWidth="100.0" spacing="15.0" HBox.hgrow="ALWAYS">
+                     <children>
+                        <TextField fx:id="textFieldWidth" />
+                        <TextField fx:id="textFieldHeight" />
+                        <HBox alignment="CENTER_LEFT" spacing="15.0">
+                           <children>
+                              <Label fx:id="labelSavePath" maxWidth="1.7976931348623157E308" HBox.hgrow="ALWAYS" />
+                              <Button fx:id="buttonChooseFile" mnemonicParsing="false" onAction="#chooseFile" text="Ändern" />
+                           </children>
+                        </HBox>
+                     </children>
+                  </VBox>
+               </children>
+            </HBox>
+            <HBox alignment="CENTER" spacing="25.0" VBox.vgrow="ALWAYS">
+               <children>
+                  <Button fx:id="buttonCancel" mnemonicParsing="false" onAction="#cancel" text="Abbrechen" />
+                  <Button fx:id="buttonExport" mnemonicParsing="false" onAction="#export" text="Exportieren" />
+               </children>
+            </HBox>
+         </children>
+      </VBox>
+   </children>
+</AnchorPane>
diff --git a/src/de/deadlocker8/budgetmaster/ui/FilterGUI.fxml b/src/de/deadlocker8/budgetmaster/ui/fxml/FilterGUI.fxml
similarity index 98%
rename from src/de/deadlocker8/budgetmaster/ui/FilterGUI.fxml
rename to src/de/deadlocker8/budgetmaster/ui/fxml/FilterGUI.fxml
index 643fd670ecbe7c76ad87e023a0608e9037bac18c..9d3e61437ca8cab1118bafc0503d88a40571e52c 100644
--- a/src/de/deadlocker8/budgetmaster/ui/FilterGUI.fxml
+++ b/src/de/deadlocker8/budgetmaster/ui/fxml/FilterGUI.fxml
@@ -12,7 +12,7 @@
 <?import javafx.scene.layout.VBox?>
 <?import javafx.scene.text.Font?>
 
-<AnchorPane prefHeight="600.0" prefWidth="450.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.FilterController">
+<AnchorPane prefHeight="600.0" prefWidth="450.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.FilterController">
    <children>
       <VBox prefHeight="273.0" prefWidth="465.0" spacing="25.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
          <children>
diff --git a/src/de/deadlocker8/budgetmaster/ui/GUI.fxml b/src/de/deadlocker8/budgetmaster/ui/fxml/GUI.fxml
similarity index 69%
rename from src/de/deadlocker8/budgetmaster/ui/GUI.fxml
rename to src/de/deadlocker8/budgetmaster/ui/fxml/GUI.fxml
index 122b897e50a412a24f72688ec0a6db4237fbdfa6..f6f3815ef6f5ba9dd9ca2d798f357e9ba84f3767 100644
--- a/src/de/deadlocker8/budgetmaster/ui/GUI.fxml
+++ b/src/de/deadlocker8/budgetmaster/ui/fxml/GUI.fxml
@@ -7,26 +7,34 @@
 <?import javafx.scene.control.TabPane?>
 <?import javafx.scene.layout.AnchorPane?>
 <?import javafx.scene.layout.HBox?>
+<?import javafx.scene.layout.Region?>
 <?import javafx.scene.layout.StackPane?>
 <?import javafx.scene.layout.VBox?>
 <?import javafx.scene.text.Font?>
 
-<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.Controller">
+<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.Controller">
    <children>
       <VBox alignment="TOP_CENTER" layoutY="24.0" prefHeight="562.0" prefWidth="772.0" spacing="15.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="14.0">
          <children>
             <HBox alignment="CENTER" prefWidth="772.0" spacing="15.0">
                <children>
+                  <Region prefHeight="0.0" prefWidth="200.0" HBox.hgrow="ALWAYS">
+                     <HBox.margin>
+                        <Insets left="25.0" />
+                     </HBox.margin>
+                  </Region>
                   <Button fx:id="buttonLeft" mnemonicParsing="false" onAction="#previousMonth" />
-                  <Label fx:id="labelMonth" alignment="CENTER" prefHeight="36.0" prefWidth="196.0" text="Dezember 2016">
+                  <Label fx:id="labelMonth" alignment="CENTER" prefHeight="36.0" prefWidth="280.0" text="Dezember 2016" HBox.hgrow="ALWAYS">
                      <font>
-                        <Font name="System Bold" size="25.0" />
+                        <Font name="System Bold" size="24.0" />
                      </font>
                   </Label>
                   <Button fx:id="buttonRight" mnemonicParsing="false" onAction="#nextMonth" />
-                  <Button fx:id="buttonToday" alignment="CENTER" mnemonicParsing="false" onAction="#today">
+                  <Button fx:id="buttonToday" mnemonicParsing="false" onAction="#today" />
+                  <Region prefHeight="0.0" prefWidth="200.0" HBox.hgrow="ALWAYS" />
+                  <Button fx:id="buttonAbout" alignment="CENTER" mnemonicParsing="false" onAction="#about">
                      <HBox.margin>
-                        <Insets />
+                        <Insets right="10.0" />
                      </HBox.margin>
                   </Button>
                </children>
@@ -39,6 +47,7 @@
                         <Tab fx:id="tabPayments" closable="false" text="Buchungen" />
                         <Tab fx:id="tabCategories" closable="false" text="Kategorien" />
                         <Tab fx:id="tabCharts" closable="false" text="Diagramme" />
+                        <Tab fx:id="tabReports" closable="false" text="Monatsbericht" />
                         <Tab fx:id="tabSettings" closable="false" text="Einstellungen" />
                     </tabs>
                   </TabPane>
diff --git a/src/de/deadlocker8/budgetmaster/ui/HomeTab.fxml b/src/de/deadlocker8/budgetmaster/ui/fxml/HomeTab.fxml
similarity index 98%
rename from src/de/deadlocker8/budgetmaster/ui/HomeTab.fxml
rename to src/de/deadlocker8/budgetmaster/ui/fxml/HomeTab.fxml
index 0144989045ba447bb06c251528de84497b54b7b2..77674f01c5c45b86e088df7c7820cd59511f538d 100644
--- a/src/de/deadlocker8/budgetmaster/ui/HomeTab.fxml
+++ b/src/de/deadlocker8/budgetmaster/ui/fxml/HomeTab.fxml
@@ -8,7 +8,7 @@
 <?import javafx.scene.layout.VBox?>
 <?import javafx.scene.text.Font?>
 
-<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.HomeController">
+<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.HomeController">
    <children>
       <VBox alignment="TOP_CENTER" layoutY="24.0" prefHeight="562.0" prefWidth="772.0" spacing="15.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
          <children>
diff --git a/src/de/deadlocker8/budgetmaster/ui/Modal.fxml b/src/de/deadlocker8/budgetmaster/ui/fxml/Modal.fxml
similarity index 96%
rename from src/de/deadlocker8/budgetmaster/ui/Modal.fxml
rename to src/de/deadlocker8/budgetmaster/ui/fxml/Modal.fxml
index 33759ff9bb89cf861f75e900f957f48ee27a25fd..846a76e2b3ba52076c54a92a9d95eab81bf105fb 100644
--- a/src/de/deadlocker8/budgetmaster/ui/Modal.fxml
+++ b/src/de/deadlocker8/budgetmaster/ui/fxml/Modal.fxml
@@ -6,7 +6,7 @@
 <?import javafx.scene.layout.HBox?>
 <?import javafx.scene.text.Font?>
 
-<AnchorPane fx:id="anchorPaneMain" prefHeight="100.0" prefWidth="375.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.ModalController">
+<AnchorPane fx:id="anchorPaneMain" prefHeight="100.0" prefWidth="375.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.ModalController">
    <children>
       <HBox alignment="CENTER_LEFT" spacing="10.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
          <children>
diff --git a/src/de/deadlocker8/budgetmaster/ui/NewCategoryGUI.fxml b/src/de/deadlocker8/budgetmaster/ui/fxml/NewCategoryGUI.fxml
similarity index 97%
rename from src/de/deadlocker8/budgetmaster/ui/NewCategoryGUI.fxml
rename to src/de/deadlocker8/budgetmaster/ui/fxml/NewCategoryGUI.fxml
index 203d4acb88da4931ec70ca307d61d331d061861c..0bb2bb676e02a1c6ef47e336022f7c151bb256f7 100644
--- a/src/de/deadlocker8/budgetmaster/ui/NewCategoryGUI.fxml
+++ b/src/de/deadlocker8/budgetmaster/ui/fxml/NewCategoryGUI.fxml
@@ -9,7 +9,7 @@
 <?import javafx.scene.layout.VBox?>
 <?import javafx.scene.text.Font?>
 
-<AnchorPane prefHeight="180.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.NewCategoryController">
+<AnchorPane prefHeight="180.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.NewCategoryController">
    <children>
       <VBox prefHeight="273.0" prefWidth="465.0" spacing="25.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
          <children>
diff --git a/src/de/deadlocker8/budgetmaster/ui/NewPaymentGUI.fxml b/src/de/deadlocker8/budgetmaster/ui/fxml/NewPaymentGUI.fxml
similarity index 99%
rename from src/de/deadlocker8/budgetmaster/ui/NewPaymentGUI.fxml
rename to src/de/deadlocker8/budgetmaster/ui/fxml/NewPaymentGUI.fxml
index 31366e41dd3bded01be30e3b15e6ab06cdce95be..59b546bdf8234e1044cbada23c69a4be65192a08 100644
--- a/src/de/deadlocker8/budgetmaster/ui/NewPaymentGUI.fxml
+++ b/src/de/deadlocker8/budgetmaster/ui/fxml/NewPaymentGUI.fxml
@@ -16,7 +16,7 @@
 <?import javafx.scene.layout.VBox?>
 <?import javafx.scene.text.Font?>
 
-<AnchorPane prefHeight="600.0" prefWidth="450.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.NewPaymentController">
+<AnchorPane prefHeight="600.0" prefWidth="450.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.NewPaymentController">
    <children>
       <VBox prefHeight="273.0" prefWidth="465.0" spacing="20.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
          <children>
diff --git a/src/de/deadlocker8/budgetmaster/ui/PaymentTab.fxml b/src/de/deadlocker8/budgetmaster/ui/fxml/PaymentTab.fxml
similarity index 99%
rename from src/de/deadlocker8/budgetmaster/ui/PaymentTab.fxml
rename to src/de/deadlocker8/budgetmaster/ui/fxml/PaymentTab.fxml
index 6222f5e8f8219b798a02de61cdcab31573d41e66..ede86bb05d9a96997b1a479b5fc72f38b06a12e0 100644
--- a/src/de/deadlocker8/budgetmaster/ui/PaymentTab.fxml
+++ b/src/de/deadlocker8/budgetmaster/ui/fxml/PaymentTab.fxml
@@ -10,7 +10,7 @@
 <?import javafx.scene.layout.VBox?>
 <?import javafx.scene.text.Font?>
 
-<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.PaymentController">
+<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.PaymentController">
    <children>
       <VBox alignment="TOP_CENTER" layoutY="24.0" prefHeight="562.0" prefWidth="772.0" spacing="25.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="25.0">
          <children>
diff --git a/src/de/deadlocker8/budgetmaster/ui/fxml/ReportTab.fxml b/src/de/deadlocker8/budgetmaster/ui/fxml/ReportTab.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..ab291d65658415d00f20767d52e55fdb8d82a51b
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/ui/fxml/ReportTab.fxml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.CheckBox?>
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.control.TableView?>
+<?import javafx.scene.layout.AnchorPane?>
+<?import javafx.scene.layout.HBox?>
+<?import javafx.scene.layout.VBox?>
+<?import javafx.scene.text.Font?>
+
+<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.ReportController">
+   <children>
+      <VBox alignment="TOP_CENTER" layoutY="24.0" prefHeight="562.0" prefWidth="772.0" spacing="20.0" AnchorPane.bottomAnchor="35.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="25.0">
+         <children>
+            <HBox alignment="CENTER" prefHeight="11.0" prefWidth="772.0">
+               <children>
+                  <VBox alignment="CENTER" spacing="10.0">
+                     <children>
+                        <Button fx:id="buttonFilter" mnemonicParsing="false" onAction="#filter" text="Filter">
+                           <font>
+                              <Font name="System Bold" size="14.0" />
+                           </font>
+                        </Button>
+                        <Label fx:id="labelFilterActive" text="Filter aktiv">
+                           <font>
+                              <Font name="System Bold" size="13.0" />
+                           </font>
+                        </Label>
+                     </children>
+                  </VBox>
+               </children>
+               <VBox.margin>
+                  <Insets />
+               </VBox.margin>
+            </HBox>
+            <HBox alignment="CENTER" prefHeight="11.0" prefWidth="772.0">
+               <children>
+                  <VBox spacing="10.0">
+                     <children>
+                        <CheckBox fx:id="checkBoxSplitTable" mnemonicParsing="false" text="Einnahmen und Ausgaben als getrennte Tabellen" />
+                        <CheckBox fx:id="checkBoxIncludeCategoryBudgets" mnemonicParsing="false" text="Verbrauch nach Kategorien hinzufügen" />
+                     </children>
+                  </VBox>
+               </children>
+               <VBox.margin>
+                  <Insets bottom="10.0" />
+               </VBox.margin>
+            </HBox>
+            <TableView fx:id="tableView" prefHeight="270.0" prefWidth="772.0" VBox.vgrow="ALWAYS">
+               <columnResizePolicy>
+                  <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
+               </columnResizePolicy></TableView>
+            <HBox alignment="CENTER" prefHeight="11.0" prefWidth="772.0">
+               <children>
+                  <VBox alignment="CENTER" spacing="10.0">
+                     <children>
+                        <Button fx:id="buttonGenerate" mnemonicParsing="false" onAction="#generate" text="Bericht erzeugen">
+                           <font>
+                              <Font name="System Bold" size="14.0" />
+                           </font>
+                        </Button>
+                     </children>
+                  </VBox>
+               </children>
+               <VBox.margin>
+                  <Insets top="15.0" />
+               </VBox.margin>
+            </HBox>
+         </children>
+      </VBox>
+   </children>
+</AnchorPane>
diff --git a/src/de/deadlocker8/budgetmaster/ui/SettingsTab.fxml b/src/de/deadlocker8/budgetmaster/ui/fxml/SettingsTab.fxml
similarity index 95%
rename from src/de/deadlocker8/budgetmaster/ui/SettingsTab.fxml
rename to src/de/deadlocker8/budgetmaster/ui/fxml/SettingsTab.fxml
index 8014a8cab8429d648976e326a52d09a1abbe935d..29b7eeb2ed092f59d70fcf8ca7c0908ca3192bf7 100644
--- a/src/de/deadlocker8/budgetmaster/ui/SettingsTab.fxml
+++ b/src/de/deadlocker8/budgetmaster/ui/fxml/SettingsTab.fxml
@@ -12,7 +12,7 @@
 <?import javafx.scene.layout.VBox?>
 <?import javafx.scene.text.Font?>
 
-<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.SettingsController">
+<AnchorPane fx:id="anchorPaneMain" prefHeight="600.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.SettingsController">
    <children>
       <VBox alignment="TOP_CENTER" layoutY="24.0" prefHeight="562.0" prefWidth="772.0" spacing="25.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="25.0">
          <children>
@@ -20,6 +20,11 @@
                <children>
                   <VBox alignment="CENTER_RIGHT" prefHeight="25.0" prefWidth="158.0" spacing="20.0">
                      <children>
+                        <Label fx:id="labelClientSecret" prefHeight="25.0" text="Client Passwort:">
+                           <font>
+                              <Font name="System Bold" size="16.0" />
+                           </font>
+                        </Label>
                         <Label fx:id="labelURL" prefHeight="25.0" text="Server URL:">
                            <font>
                               <Font name="System Bold" size="16.0" />
@@ -83,6 +88,7 @@
                   </VBox>
                   <VBox alignment="CENTER_LEFT" prefHeight="200.0" prefWidth="100.0" spacing="20.0" HBox.hgrow="ALWAYS">
                      <children>
+                        <TextField fx:id="textFieldClientSecret" />
                         <TextField fx:id="textFieldURL" />
                         <TextField fx:id="textFieldSecret" />
                         <TextField fx:id="textFieldCurrency" />
diff --git a/src/de/deadlocker8/budgetmaster/ui/fxml/SplashScreen.fxml b/src/de/deadlocker8/budgetmaster/ui/fxml/SplashScreen.fxml
new file mode 100644
index 0000000000000000000000000000000000000000..a028fad4e6d8894c5b51a38db79102ceed5b2f5d
--- /dev/null
+++ b/src/de/deadlocker8/budgetmaster/ui/fxml/SplashScreen.fxml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.control.PasswordField?>
+<?import javafx.scene.image.ImageView?>
+<?import javafx.scene.layout.AnchorPane?>
+<?import javafx.scene.layout.HBox?>
+<?import javafx.scene.layout.VBox?>
+<?import javafx.scene.text.Font?>
+
+<AnchorPane fx:id="anchorPaneMain" prefHeight="230.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.deadlocker8.budgetmaster.ui.controller.SplashScreenController">
+   <children>
+      <VBox layoutX="14.0" layoutY="14.0" spacing="10.0" AnchorPane.bottomAnchor="14.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
+         <children>
+            <HBox alignment="CENTER_LEFT" spacing="25.0">
+               <children>
+                  <ImageView fx:id="imageViewLogo" fitHeight="120.0" fitWidth="120.0" pickOnBounds="true" preserveRatio="true">
+                     <HBox.margin>
+                        <Insets left="15.0" />
+                     </HBox.margin></ImageView>
+                  <VBox alignment="CENTER" HBox.hgrow="ALWAYS">
+                     <children>
+                        <Label alignment="CENTER" maxWidth="1.7976931348623157E308" text="BudgetMaster">
+                           <font>
+                              <Font name="System Bold" size="25.0" />
+                           </font>
+                        </Label>
+                        <Label fx:id="labelVersion" alignment="CENTER" maxWidth="1.7976931348623157E308" text="v1.0.0">
+                           <font>
+                              <Font size="16.0" />
+                           </font>
+                        </Label>
+                     </children>
+                  </VBox>
+               </children>
+            </HBox>
+            <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" spacing="20.0">
+               <children>
+                  <Label text="Passwort:">
+                     <font>
+                        <Font name="System Bold" size="16.0" />
+                     </font>
+                  </Label>
+                  <PasswordField fx:id="textFieldPassword" prefHeight="28.0" prefWidth="159.0" />
+                  <Button fx:id="buttonLogin" maxHeight="-Infinity" maxWidth="-Infinity" mnemonicParsing="false" onAction="#login" prefHeight="28.0" prefWidth="28.0" />
+               </children>
+            </HBox>
+         </children>
+      </VBox>
+   </children>
+</AnchorPane>
diff --git a/src/de/deadlocker8/budgetmasterserver/logic/DatabaseExporter.java b/src/de/deadlocker8/budgetmasterserver/logic/DatabaseExporter.java
index eeda5e9593b00b74b71a76672598123af4467320..754c631652a5421eb878549ca182a329aa3a1883 100644
--- a/src/de/deadlocker8/budgetmasterserver/logic/DatabaseExporter.java
+++ b/src/de/deadlocker8/budgetmasterserver/logic/DatabaseExporter.java
@@ -2,6 +2,7 @@ package de.deadlocker8.budgetmasterserver.logic;
 
 import java.sql.Connection;
 import java.sql.DriverManager;
+import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
@@ -39,15 +40,28 @@ public class DatabaseExporter
 	    return new Database(categories, normalPayments, repeatingPayments);
 	}
 	
+	private void closeConnection(Statement statement)
+	{
+		if(statement != null)
+		{
+			try
+			{
+				statement.close();
+			}
+			catch(SQLException e)
+			{
+			}
+		}
+	}
+	
 	private ArrayList<Category> getAllCategories()
 	{	   
-        Statement stmt = null;
-        String query = "SELECT * FROM category ORDER BY category.ID";
+        PreparedStatement stmt = null;
         ArrayList<Category> results = new ArrayList<>();
         try
         {
-            stmt = connection.createStatement();
-            ResultSet rs = stmt.executeQuery(query);
+        	stmt = connection.prepareStatement("SELECT * FROM category ORDER BY category.ID");            
+            ResultSet rs = stmt.executeQuery();
             while(rs.next())
             {
                 int id = rs.getInt("ID");
@@ -63,16 +77,7 @@ public class DatabaseExporter
         }
         finally
         {
-            if(stmt != null)
-            {
-                try
-                {
-                    stmt.close();
-                }
-                catch(SQLException e)
-                {
-                }
-            }
+            closeConnection(stmt);
         }
 
         return results;    
@@ -80,14 +85,12 @@ public class DatabaseExporter
 	
 	private ArrayList<NormalPayment> getAllNormalPayments()
     {
-	    Statement stmt = null;
-        String query = "SELECT * FROM payment;";
-
+	    PreparedStatement stmt = null;
         ArrayList<NormalPayment> results = new ArrayList<>();
         try
         {
-            stmt = connection.createStatement();
-            ResultSet rs = stmt.executeQuery(query);
+        	stmt = connection.prepareStatement("SELECT * FROM payment;");           
+            ResultSet rs = stmt.executeQuery();
 
             while(rs.next())
             {
@@ -107,16 +110,7 @@ public class DatabaseExporter
         }
         finally
         {
-            if(stmt != null)
-            {
-                try
-                {
-                    stmt.close();
-                }
-                catch(SQLException e)
-                {
-                }
-            }
+           closeConnection(stmt);
         }
 
         return results;
@@ -124,14 +118,12 @@ public class DatabaseExporter
 	
 	private ArrayList<RepeatingPayment> getAllRepeatingPayments()
     {
-	    Statement stmt = null;
-        String query = "SELECT * FROM repeating_payment;";
-
+	    PreparedStatement stmt = null;
         ArrayList<RepeatingPayment> results = new ArrayList<>();
         try
         {
-            stmt = connection.createStatement();
-            ResultSet rs = stmt.executeQuery(query);
+        	stmt = connection.prepareStatement("SELECT * FROM repeating_payment;");
+            ResultSet rs = stmt.executeQuery();
 
             while(rs.next())
             {
@@ -154,16 +146,7 @@ public class DatabaseExporter
         }
         finally
         {
-            if(stmt != null)
-            {
-                try
-                {
-                    stmt.close();
-                }
-                catch(SQLException e)
-                {
-                }
-            }
+            closeConnection(stmt);
         }
 
         return results;
diff --git a/src/de/deadlocker8/budgetmasterserver/logic/DatabaseHandler.java b/src/de/deadlocker8/budgetmasterserver/logic/DatabaseHandler.java
index 328d6ee8226b84f57f3d758d0b2c929262960b51..f1e4863c8be3901bb95c310ce78e2e0afc1c4d40 100644
--- a/src/de/deadlocker8/budgetmasterserver/logic/DatabaseHandler.java
+++ b/src/de/deadlocker8/budgetmasterserver/logic/DatabaseHandler.java
@@ -2,6 +2,7 @@ package de.deadlocker8.budgetmasterserver.logic;
 
 import java.sql.Connection;
 import java.sql.DriverManager;
+import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
@@ -60,13 +61,12 @@ public class DatabaseHandler
 	 */
 	public int getLastInsertID()
 	{
-		Statement stmt = null;
-		String query = "SELECT LAST_INSERT_ID();";
+		PreparedStatement stmt = null;
 		int lastInsertID = 0;
 		try
 		{
-			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);
+			stmt = connection.prepareStatement("SELECT LAST_INSERT_ID();");		
+			ResultSet rs = stmt.executeQuery();
 
 			while(rs.next())
 			{
@@ -87,13 +87,12 @@ public class DatabaseHandler
 	
 	public DateTime getFirstNormalPaymentDate()
 	{
-		Statement stmt = null;
-		String query = "SELECT MIN(Date) as \"min\" FROM payment";
+		PreparedStatement stmt = null;
 		DateTime dateTime = null;
 		try
 		{
-			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);
+			stmt = connection.prepareStatement("SELECT MIN(Date) as \"min\" FROM payment");			
+			ResultSet rs = stmt.executeQuery();
 
 			while(rs.next())
 			{
@@ -122,13 +121,12 @@ public class DatabaseHandler
 
 	public DateTime getFirstRepeatingPaymentDate()
 	{
-		Statement stmt = null;
-		String query = "SELECT MIN(Date) as \"min\" FROM repeating_payment";
+		PreparedStatement stmt = null;
 		DateTime dateTime = null;
 		try
 		{
-			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);
+			stmt = connection.prepareStatement("SELECT MIN(Date) as \"min\" FROM repeating_payment");
+			ResultSet rs = stmt.executeQuery();
 
 			while(rs.next())
 			{
@@ -218,13 +216,12 @@ public class DatabaseHandler
 
 	public ArrayList<Category> getCategories()
 	{
-		Statement stmt = null;
-		String query = "SELECT * FROM category ORDER BY category.ID";
+		PreparedStatement stmt = null;
 		ArrayList<Category> results = new ArrayList<>();
 		try
 		{
-			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);
+			stmt = connection.prepareStatement("SELECT * FROM category ORDER BY category.ID");			
+			ResultSet rs = stmt.executeQuery();
 			while(rs.next())
 			{
 				int id = rs.getInt("ID");
@@ -247,14 +244,14 @@ public class DatabaseHandler
 	}
 
 	public Category getCategory(int ID)
-	{
-		Statement stmt = null;
-		String query = "SELECT * FROM category WHERE category.ID = " + ID;
+	{	
+		PreparedStatement stmt = null;
 		Category result = null;
 		try
-		{
-			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);
+		{		
+			stmt = connection.prepareStatement("SELECT * FROM category WHERE category.ID = ?");		
+			stmt.setInt(1, ID);
+			ResultSet rs = stmt.executeQuery();
 			while(rs.next())
 			{
 				int id = rs.getInt("ID");
@@ -278,13 +275,15 @@ public class DatabaseHandler
 	
 	public Category getCategory(String name, Color color)
 	{
-		Statement stmt = null;
-		String query = "SELECT * FROM category WHERE category.name = \"" + name + "\" AND category.color = \"" + ConvertTo.toRGBHexWithoutOpacity(color) + "\";";
+		PreparedStatement stmt = null;
 		Category result = null;
 		try
 		{
-			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);
+			stmt = connection.prepareStatement("SELECT * FROM category WHERE category.name = ? AND category.color = ?;");
+			stmt.setString(1, name);
+			stmt.setString(2, ConvertTo.toRGBHexWithoutOpacity(color));
+			
+			ResultSet rs = stmt.executeQuery();
 			while(rs.next())
 			{
 				int id = rs.getInt("ID");
@@ -308,13 +307,13 @@ public class DatabaseHandler
 	
 	public boolean categoryExists(int ID)
 	{
-		Statement stmt = null;
-		String query = "SELECT COUNT(ID) as \"count\" FROM category WHERE category.ID = " + ID;
+		PreparedStatement stmt = null;
 		boolean exists = false;
 		try
 		{
-			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);
+			stmt = connection.prepareStatement("SELECT COUNT(ID) as \"count\" FROM category WHERE category.ID = ?;");
+			stmt.setInt(1, ID);
+			ResultSet rs = stmt.executeQuery();
 			while(rs.next())
 			{
 				if(rs.getInt("count") > 0)
@@ -337,12 +336,12 @@ public class DatabaseHandler
 
 	public NormalPayment getPayment(int ID)
 	{
-		Statement stmt = null;
-		String query = "SELECT * FROM payment WHERE payment.ID= " + ID;
+		PreparedStatement stmt = null;
 		try
 		{
-			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);
+			stmt = connection.prepareStatement("SELECT * FROM payment WHERE payment.ID= ?;");	
+			stmt.setInt(1, ID);
+			ResultSet rs = stmt.executeQuery();
 
 			while(rs.next())
 			{
@@ -370,14 +369,15 @@ public class DatabaseHandler
 
 	public ArrayList<NormalPayment> getPayments(int year, int month)
 	{
-		Statement stmt = null;
-		String query = "SELECT * FROM payment WHERE YEAR(Date) = " + year + " AND  MONTH(Date) = " + month;
+		PreparedStatement stmt = null;
 
 		ArrayList<NormalPayment> results = new ArrayList<>();
 		try
 		{
-			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);
+			stmt = connection.prepareStatement("SELECT * FROM payment WHERE YEAR(Date) = ? AND  MONTH(Date) = ?;");
+			stmt.setInt(1, year);
+			stmt.setInt(2, month);
+			ResultSet rs = stmt.executeQuery();
 
 			while(rs.next())
 			{
@@ -405,14 +405,15 @@ public class DatabaseHandler
 	
 	public ArrayList<NormalPayment> getPaymentsBetween(String startDate, String endDate)
 	{	
-		Statement stmt = null;
-		String query = "SELECT * FROM payment WHERE DATE(Date) BETWEEN '" + startDate + "' AND '" + endDate + "';";
+		PreparedStatement stmt = null;
 
 		ArrayList<NormalPayment> results = new ArrayList<>();
 		try
 		{
-			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);
+			stmt = connection.prepareStatement("SELECT * FROM payment WHERE DATE(Date) BETWEEN ? AND ?;");
+			stmt.setString(1, startDate);
+			stmt.setString(2, endDate);			
+			ResultSet rs = stmt.executeQuery();
 
 			while(rs.next())
 			{
@@ -440,15 +441,15 @@ public class DatabaseHandler
 
 	public ArrayList<RepeatingPaymentEntry> getRepeatingPayments(int year, int month)
 	{
-		Statement stmt = null;
-		String query = "SELECT repeating_entry.ID, repeating_entry.RepeatingPaymentID, repeating_entry.Date, repeating_payment.Name, repeating_payment.CategoryID, repeating_payment.Amount, repeating_payment.RepeatInterval, repeating_payment.RepeatEndDate, repeating_payment.RepeatMonthDay, repeating_payment.Description FROM repeating_entry, repeating_payment WHERE repeating_entry.RepeatingPaymentID = repeating_payment.ID AND YEAR(repeating_entry.Date) = "
-				+ year + " AND MONTH(repeating_entry.Date) = " + month;
+		PreparedStatement stmt = null;
 
 		ArrayList<RepeatingPaymentEntry> results = new ArrayList<>();
 		try
 		{
-			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);
+			stmt = connection.prepareStatement("SELECT repeating_entry.ID, repeating_entry.RepeatingPaymentID, repeating_entry.Date, repeating_payment.Name, repeating_payment.CategoryID, repeating_payment.Amount, repeating_payment.RepeatInterval, repeating_payment.RepeatEndDate, repeating_payment.RepeatMonthDay, repeating_payment.Description FROM repeating_entry, repeating_payment WHERE repeating_entry.RepeatingPaymentID = repeating_payment.ID AND YEAR(repeating_entry.Date) = ? AND MONTH(repeating_entry.Date) = ?;");
+			stmt.setInt(1, year);
+			stmt.setInt(2, month);			
+			ResultSet rs = stmt.executeQuery();
 
 			while(rs.next())
 			{
@@ -480,14 +481,15 @@ public class DatabaseHandler
 	
 	public ArrayList<RepeatingPaymentEntry> getRepeatingPaymentsBetween(String startDate, String endDate)
 	{
-		Statement stmt = null;
-		String query = "SELECT repeating_entry.ID, repeating_entry.RepeatingPaymentID, repeating_entry.Date, repeating_payment.Name, repeating_payment.CategoryID, repeating_payment.Amount, repeating_payment.RepeatInterval, repeating_payment.RepeatEndDate, repeating_payment.RepeatMonthDay, repeating_payment.Description FROM repeating_entry, repeating_payment WHERE repeating_entry.RepeatingPaymentID = repeating_payment.ID AND DATE(repeating_entry.Date) BETWEEN '" + startDate + "' AND '" + endDate + "';";
+		PreparedStatement stmt = null;
 
 		ArrayList<RepeatingPaymentEntry> results = new ArrayList<>();
 		try
 		{
-			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);
+			stmt = connection.prepareStatement("SELECT repeating_entry.ID, repeating_entry.RepeatingPaymentID, repeating_entry.Date, repeating_payment.Name, repeating_payment.CategoryID, repeating_payment.Amount, repeating_payment.RepeatInterval, repeating_payment.RepeatEndDate, repeating_payment.RepeatMonthDay, repeating_payment.Description FROM repeating_entry, repeating_payment WHERE repeating_entry.RepeatingPaymentID = repeating_payment.ID AND DATE(repeating_entry.Date) BETWEEN ? AND ?;");
+			stmt.setString(1, startDate);
+			stmt.setString(2,  endDate);
+			ResultSet rs = stmt.executeQuery();
 
 			while(rs.next())
 			{
@@ -519,14 +521,13 @@ public class DatabaseHandler
 
 	public ArrayList<RepeatingPayment> getAllRepeatingPayments()
 	{
-		Statement stmt = null;
-		String query = "SELECT * FROM repeating_payment;";
+		PreparedStatement stmt = null;
 
 		ArrayList<RepeatingPayment> results = new ArrayList<>();
 		try
 		{
-			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);
+			stmt = connection.prepareStatement("SELECT * FROM repeating_payment;");			
+			ResultSet rs = stmt.executeQuery();
 
 			while(rs.next())
 			{
@@ -557,14 +558,13 @@ public class DatabaseHandler
 
 	public ArrayList<LatestRepeatingPayment> getLatestRepeatingPaymentEntries()
 	{
-		Statement stmt = null;
-		String query = "SELECT ID, RepeatingPaymentID, MAX(Date) as 'LastDate' FROM repeating_entry GROUP BY RepeatingPaymentID";
+		PreparedStatement stmt = null;
 
 		ArrayList<LatestRepeatingPayment> results = new ArrayList<>();
 		try
 		{
-			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);
+			stmt = connection.prepareStatement("SELECT ID, RepeatingPaymentID, MAX(Date) as 'LastDate' FROM repeating_entry GROUP BY RepeatingPaymentID");		
+			ResultSet rs = stmt.executeQuery();
 
 			while(rs.next())
 			{
@@ -589,13 +589,13 @@ public class DatabaseHandler
 
 	public RepeatingPayment getRepeatingPayment(int ID)
 	{
-		Statement stmt = null;
-		String query = "SELECT * FROM repeating_payment WHERE ID = " + ID;
+		PreparedStatement stmt = null;
 		RepeatingPayment result = null;
 		try
 		{
-			stmt = connection.createStatement();
-			ResultSet rs = stmt.executeQuery(query);
+			stmt = connection.prepareStatement("SELECT * FROM repeating_payment WHERE ID = ?;");
+			stmt.setInt(1,  ID);
+			ResultSet rs = stmt.executeQuery();
 			while(rs.next())
 			{
 				int id = rs.getInt("ID");
@@ -628,12 +628,12 @@ public class DatabaseHandler
 	 */
 	public void deleteCategory(int ID)
 	{
-		Statement stmt = null;
-		String query = "DELETE FROM category WHERE category.ID = " + ID;
+		PreparedStatement stmt = null;
 		try
 		{
-			stmt = connection.createStatement();
-			stmt.execute(query);
+			stmt = connection.prepareStatement("DELETE FROM category WHERE category.ID = ?;");
+			stmt.setInt(1, ID);
+			stmt.execute();
 		}
 		catch(SQLException e)
 		{
@@ -647,12 +647,12 @@ public class DatabaseHandler
 
 	public void deletePayment(int ID)
 	{
-		Statement stmt = null;
-		String query = "DELETE FROM payment WHERE payment.ID = " + ID;
+		PreparedStatement stmt = null;
 		try
 		{
-			stmt = connection.createStatement();
-			stmt.execute(query);
+			stmt = connection.prepareStatement("DELETE FROM payment WHERE payment.ID = ?;");
+			stmt.setInt(1, ID);
+			stmt.execute();
 		}
 		catch(SQLException e)
 		{
@@ -666,12 +666,12 @@ public class DatabaseHandler
 
 	public void deleteRepeatingPayment(int ID)
 	{
-		Statement stmt = null;
-		String query = "DELETE FROM repeating_payment WHERE repeating_payment.ID = " + ID;
+		PreparedStatement stmt = null;
 		try
 		{
-			stmt = connection.createStatement();
-			stmt.execute(query);
+			stmt = connection.prepareStatement("DELETE FROM repeating_payment WHERE repeating_payment.ID = ?;");
+			stmt.setInt(1, ID);
+			stmt.execute();
 		}
 		catch(SQLException e)
 		{
@@ -719,12 +719,13 @@ public class DatabaseHandler
 	 */
 	public void addCategory(String name, Color color)
 	{
-		Statement stmt = null;
-		String query = "INSERT INTO category (Name, Color) VALUES('" + name + "' , '" + ConvertTo.toRGBHexWithoutOpacity(color) + "');";
+		PreparedStatement stmt = null;
 		try
 		{
-			stmt = connection.createStatement();
-			stmt.execute(query);
+			stmt = connection.prepareStatement("INSERT INTO category (Name, Color) VALUES(?, ?);");
+			stmt.setString(1, name);
+			stmt.setString(2, ConvertTo.toRGBHexWithoutOpacity(color));
+			stmt.execute();
 		}
 		catch(SQLException e)
 		{
@@ -738,12 +739,14 @@ public class DatabaseHandler
 
 	public void importCategory(Category category)
 	{
-		Statement stmt = null;
-		String query = "INSERT INTO category (ID, Name, Color) VALUES('" + category.getID() + "', '" + category.getName() + "' , '" + ConvertTo.toRGBHexWithoutOpacity(category.getColor()) + "');";
+		PreparedStatement stmt = null;
 		try
 		{
-			stmt = connection.createStatement();
-			stmt.execute(query);
+			stmt = connection.prepareStatement("INSERT INTO category (ID, Name, Color) VALUES(?, ?, ?);");
+			stmt.setInt(1,  category.getID());
+			stmt.setString(2, category.getName());
+			stmt.setString(3, ConvertTo.toRGBHexWithoutOpacity(category.getColor()));
+			stmt.execute();
 		}
 		catch(SQLException e)
 		{
@@ -757,12 +760,16 @@ public class DatabaseHandler
 
 	public void addNormalPayment(int amount, String date, int categoryID, String name, String description)
 	{
-		Statement stmt = null;
-		String query = "INSERT INTO payment (Amount, Date, CategoryID, Name, Description) VALUES('" + amount + "' , '" + date + "' , '" + categoryID + "' , '" + name + "' , '" + description + "');";
+		PreparedStatement stmt = null;
 		try
 		{
-			stmt = connection.createStatement();
-			stmt.execute(query);
+			stmt = connection.prepareStatement("INSERT INTO payment (Amount, Date, CategoryID, Name, Description) VALUES(?, ?, ?, ?, ?);");
+			stmt.setInt(1, amount);
+			stmt.setString(2, date);
+			stmt.setInt(3, categoryID);
+			stmt.setString(4, name);
+			stmt.setString(5, description);
+			stmt.execute();
 		}
 		catch(SQLException e)
 		{
@@ -776,28 +783,29 @@ public class DatabaseHandler
 
 	public void addRepeatingPayment(int amount, String date, int categoryID, String name, String description, int repeatInterval, String repeatEndDate, int repeatMonthDay)
 	{
-		Statement stmt = null;
-		String query;
+		PreparedStatement stmt = null;
 		String correctRepeatEndDate = repeatEndDate;
 		if(correctRepeatEndDate == null || correctRepeatEndDate.equals("A"))
 		{
-			correctRepeatEndDate = "NULL";
+			correctRepeatEndDate = null;
 		}
-		else
-		{
-			correctRepeatEndDate = "'" + correctRepeatEndDate + "'";
-		}
-
-		query = "INSERT INTO repeating_payment (Amount, Date, CategoryID, Name, RepeatInterval, RepeatEndDate, RepeatMonthDay, Description) VALUES('" + amount + "' , '" + date + "' , '" + categoryID + "' , '" + name + "' , '" + repeatInterval + "' , " + correctRepeatEndDate + " , '" + repeatMonthDay
-				+ "' , '" + description + "');";
 
 		try
 		{
-			stmt = connection.createStatement();
-			stmt.execute(query);
+			stmt = connection.prepareStatement("INSERT INTO repeating_payment (Amount, Date, CategoryID, Name, RepeatInterval, RepeatEndDate, RepeatMonthDay, Description) VALUES(?, ?, ?, ?, ?, ?, ?, ?);");
+			stmt.setInt(1, amount);
+			stmt.setString(2, date);
+			stmt.setInt(3, categoryID);
+			stmt.setString(4, name);
+			stmt.setInt(5, repeatInterval);
+			stmt.setString(6, correctRepeatEndDate);
+			stmt.setInt(7, repeatMonthDay);
+			stmt.setString(8, description);
+			stmt.execute();
 		}
 		catch(SQLException e)
 		{
+			e.printStackTrace();
 			Logger.error(e);
 		}
 		finally
@@ -808,13 +816,14 @@ public class DatabaseHandler
 	
 	public void addRepeatingPaymentEntry(int repeatingPaymentID, String date)
 	{
-		Statement stmt = null;
-		String query;
-		query = "INSERT INTO repeating_entry (RepeatingPaymentID, Date) VALUES('" + repeatingPaymentID + "' , '" + date + "');";
+		PreparedStatement stmt = null;
+		
 		try
 		{
-			stmt = connection.createStatement();
-			stmt.execute(query);
+			stmt = connection.prepareStatement("INSERT INTO repeating_entry (RepeatingPaymentID, Date) VALUES(?, ?);");
+			stmt.setInt(1, repeatingPaymentID);
+			stmt.setString(2, date);
+			stmt.execute();
 		}
 		catch(SQLException e)
 		{
@@ -831,12 +840,14 @@ public class DatabaseHandler
 	 */
 	public void updateCategory(int ID, String name, Color color)
 	{
-		Statement stmt = null;
-		String query = "UPDATE category SET name='" + name + "' , color='" + ConvertTo.toRGBHexWithoutOpacity(color) + "' WHERE ID = " + ID + ";";
+		PreparedStatement stmt = null;
 		try
 		{
-			stmt = connection.createStatement();
-			stmt.execute(query);
+			stmt = connection.prepareStatement("UPDATE category SET name=? , color=? WHERE ID = ?;");
+			stmt.setString(1, name);
+			stmt.setString(2, ConvertTo.toRGBHexWithoutOpacity(color));
+			stmt.setInt(3, ID);
+			stmt.executeUpdate();
 		}
 		catch(SQLException e)
 		{
@@ -850,12 +861,17 @@ public class DatabaseHandler
 
 	public void updateNormalPayment(int ID, int amount, String date, int categoryID, String name, String description)
 	{
-		Statement stmt = null;
-		String query = "UPDATE payment SET amount = '" + amount + "', date='" + date + "', categoryID='" + categoryID + "', name='" + name + "', description='" + description + "' WHERE ID = " + ID + ";";
+		PreparedStatement stmt = null;
 		try
 		{
-			stmt = connection.createStatement();
-			stmt.execute(query);
+			stmt = connection.prepareStatement("UPDATE payment SET amount=?, date=?, categoryID=?, name=?, description=? WHERE ID=?;");
+			stmt.setInt(1, amount);
+			stmt.setString(2, date);
+			stmt.setInt(3, categoryID);
+			stmt.setString(4, name);
+			stmt.setString(5, description);
+			stmt.setInt(6, ID);
+			stmt.executeUpdate();
 		}
 		catch(SQLException e)
 		{
diff --git a/src/de/deadlocker8/budgetmasterserver/logic/Settings.java b/src/de/deadlocker8/budgetmasterserver/logic/Settings.java
index 121ba938b3b45f8ab641e1b267e2b896a5777491..821531725dcb7c8f81ddbd9061dd996d052f135e 100644
--- a/src/de/deadlocker8/budgetmasterserver/logic/Settings.java
+++ b/src/de/deadlocker8/budgetmasterserver/logic/Settings.java
@@ -6,60 +6,164 @@ public class Settings
 	private String databaseName;
 	private String databaseUsername;
 	private String databasePassword;
-	private int serverPort;	
+	private int serverPort;
 	private String serverSecret;
 	private String keystorePath;
 	private String keystorePassword;
-	
+
 	public Settings()
 	{
-		
+
 	}
-	
+
 	public String getDatabaseUrl()
 	{
 		return databaseUrl;
 	}
 
+	public void setDatabaseUrl(String databaseUrl)
+	{
+		this.databaseUrl = databaseUrl;
+	}
+
 	public String getDatabaseName()
 	{
 		return databaseName;
 	}
 
+	public void setDatabaseName(String databaseName)
+	{
+		this.databaseName = databaseName;
+	}
+
 	public String getDatabaseUsername()
 	{
 		return databaseUsername;
 	}
 
+	public void setDatabaseUsername(String databaseUsername)
+	{
+		this.databaseUsername = databaseUsername;
+	}
+
 	public String getDatabasePassword()
 	{
 		return databasePassword;
 	}
 
+	public void setDatabasePassword(String databasePassword)
+	{
+		this.databasePassword = databasePassword;
+	}
+
 	public int getServerPort()
 	{
 		return serverPort;
 	}
 
+	public void setServerPort(int serverPort)
+	{
+		this.serverPort = serverPort;
+	}
+
 	public String getServerSecret()
 	{
 		return serverSecret;
 	}
 
+	public void setServerSecret(String serverSecret)
+	{
+		this.serverSecret = serverSecret;
+	}
+
 	public String getKeystorePath()
 	{
 		return keystorePath;
 	}
 
+	public void setKeystorePath(String keystorePath)
+	{
+		this.keystorePath = keystorePath;
+	}
+
 	public String getKeystorePassword()
 	{
 		return keystorePassword;
 	}
 
+	public void setKeystorePassword(String keystorePassword)
+	{
+		this.keystorePassword = keystorePassword;
+	}
+
 	@Override
 	public String toString()
 	{
 		return "Settings [databaseUrl=" + databaseUrl + ", databaseName=" + databaseName + ", databaseUsername=" + databaseUsername + ", databasePassword=" + databasePassword + ", serverPort=" + serverPort + ", serverSecret=" + serverSecret + ", keystorePath=" + keystorePath + ", keystorePassword="
 				+ keystorePassword + "]";
 	}
+
+	@Override
+	public boolean equals(Object obj)
+	{
+		if(this == obj)
+			return true;
+		if(obj == null)
+			return false;
+		if(getClass() != obj.getClass())
+			return false;
+		Settings other = (Settings)obj;
+		if(databaseName == null)
+		{
+			if(other.databaseName != null)
+				return false;
+		}
+		else if(!databaseName.equals(other.databaseName))
+			return false;
+		if(databasePassword == null)
+		{
+			if(other.databasePassword != null)
+				return false;
+		}
+		else if(!databasePassword.equals(other.databasePassword))
+			return false;
+		if(databaseUrl == null)
+		{
+			if(other.databaseUrl != null)
+				return false;
+		}
+		else if(!databaseUrl.equals(other.databaseUrl))
+			return false;
+		if(databaseUsername == null)
+		{
+			if(other.databaseUsername != null)
+				return false;
+		}
+		else if(!databaseUsername.equals(other.databaseUsername))
+			return false;
+		if(keystorePassword == null)
+		{
+			if(other.keystorePassword != null)
+				return false;
+		}
+		else if(!keystorePassword.equals(other.keystorePassword))
+			return false;
+		if(keystorePath == null)
+		{
+			if(other.keystorePath != null)
+				return false;
+		}
+		else if(!keystorePath.equals(other.keystorePath))
+			return false;
+		if(serverPort != other.serverPort)
+			return false;
+		if(serverSecret == null)
+		{
+			if(other.serverSecret != null)
+				return false;
+		}
+		else if(!serverSecret.equals(other.serverSecret))
+			return false;
+		return true;
+	}
 }
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/main/_de.properties b/src/de/deadlocker8/budgetmasterserver/main/_de.properties
index a3d8467008e914df260865c3283be6d831e09e01..713a76327463db483cc54898db38106a16685244 100644
--- a/src/de/deadlocker8/budgetmasterserver/main/_de.properties
+++ b/src/de/deadlocker8/budgetmasterserver/main/_de.properties
@@ -1,5 +1,5 @@
 app.name=BudgetMasterServer
-version.code=3
-version.name=1.2.0
-version.date=25.05.17
+version.code=4
+version.name=1.3.0
+version.date=10.08.17
 author=Robert Goldmann
\ No newline at end of file
diff --git a/src/de/deadlocker8/budgetmasterserver/server/SparkServer.java b/src/de/deadlocker8/budgetmasterserver/server/SparkServer.java
index b2389dd932e79e399f09272e5140ae9d2b87e3e3..29317035bd5b5e5d585dcb568baf2713ccbc2307 100644
--- a/src/de/deadlocker8/budgetmasterserver/server/SparkServer.java
+++ b/src/de/deadlocker8/budgetmasterserver/server/SparkServer.java
@@ -17,7 +17,7 @@ import org.joda.time.DateTime;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
-import de.deadlocker8.budgetmaster.logic.Helpers;
+import de.deadlocker8.budgetmaster.logic.utils.Helpers;
 import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
 import de.deadlocker8.budgetmasterserver.logic.Settings;
 import de.deadlocker8.budgetmasterserver.server.category.CategoryAdd;
diff --git a/tests/de/deadlocker8/budgetmaster/tests/resources/export.json b/tests/de/deadlocker8/budgetmaster/tests/resources/export.json
new file mode 100644
index 0000000000000000000000000000000000000000..12515b0b63822774520696258cc0d14ecb525eff
--- /dev/null
+++ b/tests/de/deadlocker8/budgetmaster/tests/resources/export.json
@@ -0,0 +1 @@
+{"categories":[{"ID":1,"name":"NONE","color":{"red":1.0,"green":1.0,"blue":1.0,"opacity":1.0}},{"ID":2,"name":"Übertrag","color":{"red":1.0,"green":1.0,"blue":0.0,"opacity":1.0}},{"ID":3,"name":"123 Tü+?est Category","color":{"red":0.9411765,"green":0.972549,"blue":1.0,"opacity":1.0}}],"normalPayments":[{"ID":1,"amount":23,"date":"2017-06-02","categoryID":0,"name":"Test Normal","description":"Lorem Ipsum"}],"repeatingPayments":[{"repeatInterval":7,"repeatEndDate":"2017-06-30","repeatMonthDay":0,"ID":1,"amount":-10012,"date":"2017-06-01","categoryID":1,"name":"Test Repeating","description":"Lorem Ipsum"}]}
\ No newline at end of file
diff --git a/tests/de/deadlocker8/budgetmaster/tests/resources/import.json b/tests/de/deadlocker8/budgetmaster/tests/resources/import.json
new file mode 100644
index 0000000000000000000000000000000000000000..12515b0b63822774520696258cc0d14ecb525eff
--- /dev/null
+++ b/tests/de/deadlocker8/budgetmaster/tests/resources/import.json
@@ -0,0 +1 @@
+{"categories":[{"ID":1,"name":"NONE","color":{"red":1.0,"green":1.0,"blue":1.0,"opacity":1.0}},{"ID":2,"name":"Übertrag","color":{"red":1.0,"green":1.0,"blue":0.0,"opacity":1.0}},{"ID":3,"name":"123 Tü+?est Category","color":{"red":0.9411765,"green":0.972549,"blue":1.0,"opacity":1.0}}],"normalPayments":[{"ID":1,"amount":23,"date":"2017-06-02","categoryID":0,"name":"Test Normal","description":"Lorem Ipsum"}],"repeatingPayments":[{"repeatInterval":7,"repeatEndDate":"2017-06-30","repeatMonthDay":0,"ID":1,"amount":-10012,"date":"2017-06-01","categoryID":1,"name":"Test Repeating","description":"Lorem Ipsum"}]}
\ No newline at end of file
diff --git a/tests/de/deadlocker8/budgetmaster/tests/server/database/DatabaseHandlerTest.java b/tests/de/deadlocker8/budgetmaster/tests/server/database/DatabaseHandlerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..94bd4b2ae7bb367ba5674c5b06e574c2623891ab
--- /dev/null
+++ b/tests/de/deadlocker8/budgetmaster/tests/server/database/DatabaseHandlerTest.java
@@ -0,0 +1,257 @@
+package de.deadlocker8.budgetmaster.tests.server.database;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import de.deadlocker8.budgetmaster.logic.Category;
+import de.deadlocker8.budgetmaster.logic.LatestRepeatingPayment;
+import de.deadlocker8.budgetmaster.logic.NormalPayment;
+import de.deadlocker8.budgetmaster.logic.RepeatingPayment;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.Settings;
+import de.deadlocker8.budgetmasterserver.logic.Utils;
+import javafx.scene.paint.Color;
+
+public class DatabaseHandlerTest
+{			
+	private static DatabaseHandler databaseHandler;
+	
+	@BeforeClass
+	public static void init()
+	{
+		try
+		{
+			//init
+			Settings settings = Utils.loadSettings();
+			System.out.println(settings);
+			DatabaseHandler handler = new DatabaseHandler(settings);
+			handler.deleteDatabase();
+			handler = new DatabaseHandler(settings);			
+			databaseHandler = handler;
+		}
+		catch(IOException | URISyntaxException e)
+		{
+			fail(e.getMessage());
+		}		
+	}	
+	
+	@Test
+	public void testLastInsertID()
+	{			
+		Category expected = new Category("123 Tü+?est Category", Color.ALICEBLUE);
+		databaseHandler.addCategory(expected.getName(), expected.getColor());
+		//3 because "NONE" and "Übertrag" has already been inserted at database creation	
+		assertEquals(3, databaseHandler.getLastInsertID());		
+	}
+	
+	@Test
+	public void testCategory()
+	{
+		//add
+		Category expected = new Category("123 Tü+?est Category", Color.ALICEBLUE);
+		databaseHandler.addCategory(expected.getName(), expected.getColor());
+		ArrayList<Category> categories = databaseHandler.getCategories();	
+		
+		//get
+		Category category = databaseHandler.getCategory(categories.get(categories.size()-1).getID());
+		assertEquals(expected.getName(), category.getName());
+		assertEquals(expected.getColor(), category.getColor());
+		
+		//update
+		Category expectedUpdated = new Category(category.getID(), "456", Color.RED);
+		databaseHandler.updateCategory(expectedUpdated.getID(), expectedUpdated.getName(), expectedUpdated.getColor());
+		category = databaseHandler.getCategory(expectedUpdated.getID());
+		assertEquals(expectedUpdated.getName(), category.getName());
+		assertEquals(expectedUpdated.getColor(), category.getColor());
+		
+		//misc
+		category = databaseHandler.getCategory("NONE", Color.web("#FFFFFF"));
+		assertEquals(1, category.getID());
+		
+		assertTrue(databaseHandler.categoryExists(1));
+	}
+
+	@Test
+	public void testDeleteCategory()
+	{
+		//add
+		Category expected = new Category("123 Tü+?est Category", Color.ALICEBLUE);
+		databaseHandler.addCategory(expected.getName(), expected.getColor());		
+		
+		int id = databaseHandler.getLastInsertID();
+		
+		databaseHandler.deleteCategory(id);
+		Category category = databaseHandler.getCategory(id);
+		
+		assertNull(category);
+	}
+	
+	@Test
+	public void testNormalPayment()
+	{		
+		//add
+		NormalPayment expectedPayment = new NormalPayment(1, 1000, "2017-03-01", 2, "Buchung", "Lorem Ipsum");
+		
+		databaseHandler.addNormalPayment(expectedPayment.getAmount(),
+										 expectedPayment.getDate(),
+										 expectedPayment.getCategoryID(),
+										 expectedPayment.getName(),
+										 expectedPayment.getDescription());
+		
+		int id = databaseHandler.getLastInsertID();
+		
+		//get
+		NormalPayment payment = databaseHandler.getPayment(id);
+		
+		assertEquals(expectedPayment.getAmount(), payment.getAmount());		
+		assertEquals(expectedPayment.getDate(), payment.getDate());
+		assertEquals(expectedPayment.getCategoryID(), payment.getCategoryID());
+		assertEquals(expectedPayment.getName(), payment.getName());
+		assertEquals(expectedPayment.getDescription(), payment.getDescription());
+		
+		//update
+		NormalPayment expectedUpdated = new NormalPayment(id, 2000, "2017-03-02", 1, "Buchung 2", "Lorem Ipsum");
+		databaseHandler.updateNormalPayment(expectedUpdated.getID(),
+											expectedUpdated.getAmount(),
+											expectedUpdated.getDate(),
+											expectedUpdated.getCategoryID(),
+											expectedUpdated.getName(),
+											expectedUpdated.getDescription());
+		
+		payment = databaseHandler.getPayment(id);
+		
+		assertEquals(expectedUpdated.getAmount(), payment.getAmount());		
+		assertEquals(expectedUpdated.getDate(), payment.getDate());
+		assertEquals(expectedUpdated.getCategoryID(), payment.getCategoryID());
+		assertEquals(expectedUpdated.getName(), payment.getName());
+		assertEquals(expectedUpdated.getDescription(), payment.getDescription());		
+		
+		//misc
+		assertEquals(1, databaseHandler.getPayments(2017, 03).size());
+		assertEquals(0, databaseHandler.getPayments(2015, 03).size());
+		
+		assertEquals(1, databaseHandler.getPaymentsBetween("2016-01-01", "2018-01-01").size());
+		assertEquals(0, databaseHandler.getPaymentsBetween("2018-01-01", "2019-01-01").size());
+	}
+	
+	@Test
+	public void testDeleteNormalPayment()
+	{
+		//add
+		NormalPayment expectedPayment = new NormalPayment(1, 1000, "2017-03-01", 2, "Buchung", "Lorem Ipsum");
+		
+		databaseHandler.addNormalPayment(expectedPayment.getAmount(),
+										 expectedPayment.getDate(),
+										 expectedPayment.getCategoryID(),
+										 expectedPayment.getName(),
+										 expectedPayment.getDescription());
+		
+		int id = databaseHandler.getLastInsertID();
+		
+		databaseHandler.deletePayment(id);
+		NormalPayment payment = databaseHandler.getPayment(id);
+		
+		assertNull(payment);
+	}
+	
+	@Test
+	public void testRepeatingPayment()
+	{	
+		//add
+		RepeatingPayment expectedPayment = new RepeatingPayment(1, 1000, "2017-03-01", 2, "Buchung", "Lorem Ipsum", 0, null, 15);
+		
+		databaseHandler.addRepeatingPayment(expectedPayment.getAmount(),
+											expectedPayment.getDate(),
+											expectedPayment.getCategoryID(),
+											expectedPayment.getName(),
+											expectedPayment.getDescription(),
+											expectedPayment.getRepeatInterval(),
+											expectedPayment.getRepeatEndDate(),
+											expectedPayment.getRepeatMonthDay());
+		//get
+		RepeatingPayment payment = databaseHandler.getRepeatingPayment(databaseHandler.getLastInsertID());
+		
+		assertEquals(expectedPayment.getAmount(), payment.getAmount());		
+		assertEquals(expectedPayment.getDate(), payment.getDate());
+		assertEquals(expectedPayment.getCategoryID(), payment.getCategoryID());
+		assertEquals(expectedPayment.getName(), payment.getName());
+		assertEquals(expectedPayment.getDescription(), payment.getDescription());
+		assertEquals(expectedPayment.getRepeatInterval(), payment.getRepeatInterval());
+		assertEquals(expectedPayment.getRepeatEndDate(), payment.getRepeatEndDate());
+		assertEquals(expectedPayment.getRepeatMonthDay(), payment.getRepeatMonthDay());
+		
+		//RepeatingPaymentEntry
+		databaseHandler.addRepeatingPaymentEntry(expectedPayment.getID(), "2017-03-15");
+		ArrayList<LatestRepeatingPayment> latestPayments = databaseHandler.getLatestRepeatingPaymentEntries();
+		assertEquals(1, latestPayments.size());
+		assertEquals(expectedPayment.getID(), latestPayments.get(0).getRepeatingPaymentID());
+		assertEquals("2017-03-15", latestPayments.get(0).getLastDate());		
+		
+		//misc
+		assertEquals(1, databaseHandler.getRepeatingPayments(2017, 03).size());
+		assertEquals(0, databaseHandler.getRepeatingPayments(2015, 03).size());
+		
+		assertEquals(1, databaseHandler.getRepeatingPaymentsBetween("2016-01-01", "2018-01-01").size());
+		assertEquals(0, databaseHandler.getRepeatingPaymentsBetween("2018-01-01", "2019-01-01").size());
+		
+		assertEquals(1, databaseHandler.getAllRepeatingPayments().size());		
+	}
+	
+	@Test
+	public void testDeleteRepeatingPayment()
+	{
+		RepeatingPayment expectedPayment = new RepeatingPayment(1, 1000, "2017-03-01", 2, "Buchung", "Lorem Ipsum", 0, null, 15);
+		
+		databaseHandler.addRepeatingPayment(expectedPayment.getAmount(),
+											expectedPayment.getDate(),
+											expectedPayment.getCategoryID(),
+											expectedPayment.getName(),
+											expectedPayment.getDescription(),
+											expectedPayment.getRepeatInterval(),
+											expectedPayment.getRepeatEndDate(),
+											expectedPayment.getRepeatMonthDay());
+		
+		int id = databaseHandler.getLastInsertID();
+		
+		databaseHandler.deleteRepeatingPayment(id);
+		RepeatingPayment payment = databaseHandler.getRepeatingPayment(id);
+		
+		assertNull(payment);
+	}
+	
+	@Test
+	public void testRest()
+	{
+		//add payments for previous months
+		NormalPayment expectedPayment = new NormalPayment(1, 1000, "2017-03-01", 2, "Buchung", "Lorem Ipsum");		
+		databaseHandler.addNormalPayment(expectedPayment.getAmount(),
+										 expectedPayment.getDate(),
+										 expectedPayment.getCategoryID(),
+										 expectedPayment.getName(),
+										 expectedPayment.getDescription());		
+		int idPayment1 = databaseHandler.getLastInsertID();
+		
+		expectedPayment = new NormalPayment(2, -800, "2017-02-01", 2, "Buchung", "Lorem Ipsum");		
+		databaseHandler.addNormalPayment(expectedPayment.getAmount(),
+										 expectedPayment.getDate(),
+										 expectedPayment.getCategoryID(),
+										 expectedPayment.getName(),
+										 expectedPayment.getDescription());
+		int idPayment2 = databaseHandler.getLastInsertID();
+		
+		assertEquals(1000, databaseHandler.getRest(2017, 3));		
+		assertEquals(200, databaseHandler.getRestForAllPreviousMonths(2017, 4));
+		
+		databaseHandler.deletePayment(idPayment1);
+		databaseHandler.deletePayment(idPayment2);
+	}
+}
\ No newline at end of file
diff --git a/tests/de/deadlocker8/budgetmaster/tests/server/database/DatabaseImportExportTest.java b/tests/de/deadlocker8/budgetmaster/tests/server/database/DatabaseImportExportTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f319ff5d5c64f56be491167e641b1ae501231205
--- /dev/null
+++ b/tests/de/deadlocker8/budgetmaster/tests/server/database/DatabaseImportExportTest.java
@@ -0,0 +1,131 @@
+package de.deadlocker8.budgetmaster.tests.server.database;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.gson.Gson;
+
+import de.deadlocker8.budgetmaster.logic.Category;
+import de.deadlocker8.budgetmaster.logic.NormalPayment;
+import de.deadlocker8.budgetmaster.logic.RepeatingPayment;
+import de.deadlocker8.budgetmaster.logic.utils.FileHelper;
+import de.deadlocker8.budgetmasterserver.logic.Database;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseExporter;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseHandler;
+import de.deadlocker8.budgetmasterserver.logic.DatabaseImporter;
+import de.deadlocker8.budgetmasterserver.logic.Settings;
+import de.deadlocker8.budgetmasterserver.logic.Utils;
+import javafx.scene.paint.Color;
+
+public class DatabaseImportExportTest
+{			
+	private static Settings settings;
+	private static DatabaseHandler databaseHandler;
+	
+	@BeforeClass
+	public static void init()
+	{
+		try
+		{
+			//init
+			settings = Utils.loadSettings();			
+			DatabaseHandler handler = new DatabaseHandler(settings);
+			handler.deleteDatabase();
+			handler = new DatabaseHandler(settings);			
+			databaseHandler = handler;
+		}
+		catch(IOException | URISyntaxException e)
+		{
+			fail(e.getMessage());
+		}		
+	}	
+	
+	@Test
+	public void testImport()
+	{	
+		try
+		{
+			File file = Paths.get("tests/de/deadlocker8/budgetmaster/tests/resources/import.json").toFile();
+			Database database = FileHelper.loadDatabaseJSON(file);			
+			
+			DatabaseImporter importer = new DatabaseImporter(databaseHandler);
+			importer.importDatabase(database);
+			
+			//test category
+			Category expectedCategory = new Category(3, "123 Tü+?est Category", Color.ALICEBLUE);			
+			ArrayList<Category> categories = databaseHandler.getCategories();	
+			
+			Category category = databaseHandler.getCategory(categories.get(categories.size()-1).getID());
+			assertEquals(expectedCategory.getName(), category.getName());
+			assertEquals(expectedCategory.getColor(), category.getColor());
+			
+			//test normal payment
+			NormalPayment expectedPayment = new NormalPayment(1, 23, "2017-06-02", 0, "Test Normal", "Lorem Ipsum");			
+			NormalPayment payment = databaseHandler.getPayment(1);			
+			assertEquals(expectedPayment.getAmount(), payment.getAmount());		
+			assertEquals(expectedPayment.getDate(), payment.getDate());
+			assertEquals(expectedPayment.getCategoryID(), payment.getCategoryID());
+			assertEquals(expectedPayment.getName(), payment.getName());
+			assertEquals(expectedPayment.getDescription(), payment.getDescription());
+			
+			//test repeating payment
+			RepeatingPayment expectedRepeatingPayment = new RepeatingPayment(1, -10012, "2017-06-01", 1, "Test Repeating", "Lorem Ipsum", 7, "2017-06-30", 0);			
+			RepeatingPayment repeatingPayment = databaseHandler.getRepeatingPayment(1);
+			assertEquals(expectedRepeatingPayment.getAmount(), repeatingPayment.getAmount());
+			assertEquals(expectedRepeatingPayment.getDate(), repeatingPayment.getDate());
+			assertEquals(expectedRepeatingPayment.getCategoryID(), repeatingPayment.getCategoryID());
+			assertEquals(expectedRepeatingPayment.getName(), repeatingPayment.getName());
+			assertEquals(expectedRepeatingPayment.getDescription(), repeatingPayment.getDescription());
+			assertEquals(expectedRepeatingPayment.getRepeatInterval(), repeatingPayment.getRepeatInterval());
+			assertEquals(expectedRepeatingPayment.getRepeatEndDate(), repeatingPayment.getRepeatEndDate());
+			assertEquals(expectedRepeatingPayment.getRepeatMonthDay(), repeatingPayment.getRepeatMonthDay());			
+		}
+		catch(Exception e)
+		{
+			e.printStackTrace();
+			fail(e.getMessage());
+		}		
+	}
+	
+	@Test
+	public void testExport()
+	{	
+		try
+		{
+			databaseHandler.deleteDatabase();
+			databaseHandler = new DatabaseHandler(settings);
+			
+			File file = Paths.get("tests/de/deadlocker8/budgetmaster/tests/resources/import.json").toFile();
+			Database database = FileHelper.loadDatabaseJSON(file);			
+			
+			DatabaseImporter importer = new DatabaseImporter(databaseHandler);
+			importer.importDatabase(database);			
+			
+			file = Paths.get("tests/de/deadlocker8/budgetmaster/tests/resources/export.json").toFile();
+			DatabaseExporter exporter = new DatabaseExporter(settings);	
+			Gson gson = new Gson();
+			String databaseJSON = gson.toJson(exporter.exportDatabase());
+			FileHelper.saveDatabaseJSON(file, databaseJSON);		
+			
+			String expectedJSON = new String(Files.readAllBytes(Paths.get("tests/de/deadlocker8/budgetmaster/tests/resources/import.json")));
+			String exportedJSON = new String(Files.readAllBytes(Paths.get("tests/de/deadlocker8/budgetmaster/tests/resources/export.json")));		
+			
+			assertEquals(expectedJSON, exportedJSON);
+		}
+		catch(Exception e)
+		{
+			e.printStackTrace();
+			fail(e.getMessage());
+		}		
+	}
+}
\ No newline at end of file
diff --git a/tests/de/deadlocker8/budgetmaster/tests/server/settings/SettingsTest.java b/tests/de/deadlocker8/budgetmaster/tests/server/settings/SettingsTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..6136a4ca9d728627d118e7ca9a2c84dce306c7ea
--- /dev/null
+++ b/tests/de/deadlocker8/budgetmaster/tests/server/settings/SettingsTest.java
@@ -0,0 +1,40 @@
+package de.deadlocker8.budgetmaster.tests.server.settings;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+import org.junit.Test;
+
+import de.deadlocker8.budgetmasterserver.logic.Settings;
+import de.deadlocker8.budgetmasterserver.logic.Utils;
+
+public class SettingsTest
+{		
+	@Test
+	public void testRead()
+	{		
+		try
+		{
+			Settings settings = Utils.loadSettings();
+			
+			Settings expectedSettings = new Settings();
+			expectedSettings.setDatabaseName("b");
+			expectedSettings.setDatabaseUrl("jdbc:mysql://localhost:3306/");
+			expectedSettings.setDatabaseUsername("root");
+			expectedSettings.setDatabasePassword("");
+			expectedSettings.setServerPort(9000);
+			expectedSettings.setServerSecret("geheim");
+			expectedSettings.setKeystorePath("C:/Programmierung/eclipse/workspace/BudgetMaster/certs/keystore_self_signed.jks");
+			expectedSettings.setKeystorePassword("geheim");			
+			
+			assertEquals(expectedSettings, settings);
+		}
+		catch(IOException | URISyntaxException e)
+		{
+			fail(e.getMessage());
+		}
+	}
+}
\ No newline at end of file