From 7a233e97362d8368482f79b34438febd2a27d14c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matej=20Kov=C3=A1r?= <xkovar4@fi.muni.cz>
Date: Thu, 3 Feb 2022 12:42:13 +0100
Subject: [PATCH] Resolve "Project tab improvements"

---
 .../java/cz/fidentis/analyst/Project.java     |  12 +-
 .../analyst/ProjectConfiguration.java         |  12 +-
 .../cz/fidentis/analyst/face/HumanFace.java   |  31 +
 GUI/pom.xml                                   |   5 +
 .../fidentis/analyst/batch/BatchAction.java   |   2 +-
 .../cz/fidentis/analyst/batch/BatchPanel.java |   2 +-
 .../analyst/core/OutputWindowThread.java      |   2 +-
 .../fidentis/analyst/core/ProjectTopComp.form | 441 -----------
 .../analyst/dashboard/FaceStatePanel.java     |  68 --
 .../analyst/dashboard/FilterPanel.java        | 100 ---
 .../analyst/project/FaceStatePanel.form       | 308 ++++++++
 .../analyst/project/FaceStatePanel.java       | 404 ++++++++++
 .../fidentis/analyst/project/FilterPanel.form | 183 +++++
 .../fidentis/analyst/project/FilterPanel.java | 237 ++++++
 .../ModelsTableModel.java                     |  54 +-
 .../analyst/project/ProjectPanel.form         | 322 ++++++++
 .../ProjectPanel.java}                        | 722 ++++++++----------
 .../analyst/project/ProjectTopComp.java       | 184 +++++
 .../project/events/AllFacesLoaded.java        |  28 +
 .../project/events/FaceDeselected.java        |  14 +
 .../analyst/project/events/FaceSelected.java  |  44 ++
 .../analyst/project/events/ProjectEvent.java  |  14 +
 .../project/events/ProjectListener.java       |  23 +
 .../analyst/project/Bundle.properties         |  35 +
 GUI/src/main/resources/face160x160.png        | Bin 0 -> 4468 bytes
 GUI/src/main/resources/face16x16.png          | Bin 0 -> 365 bytes
 GUI/src/main/resources/face200x200.png        | Bin 0 -> 4801 bytes
 GUI/src/main/resources/face32x32.png          | Bin 0 -> 745 bytes
 GUI/src/main/resources/filter28x28.png        | Bin 0 -> 885 bytes
 GUI/src/main/resources/warning16x16.png       | Bin 0 -> 411 bytes
 30 files changed, 2198 insertions(+), 1049 deletions(-)
 delete mode 100644 GUI/src/main/java/cz/fidentis/analyst/core/ProjectTopComp.form
 delete mode 100644 GUI/src/main/java/cz/fidentis/analyst/dashboard/FaceStatePanel.java
 delete mode 100644 GUI/src/main/java/cz/fidentis/analyst/dashboard/FilterPanel.java
 create mode 100644 GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.form
 create mode 100644 GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.java
 create mode 100644 GUI/src/main/java/cz/fidentis/analyst/project/FilterPanel.form
 create mode 100644 GUI/src/main/java/cz/fidentis/analyst/project/FilterPanel.java
 rename GUI/src/main/java/cz/fidentis/analyst/{dashboard => project}/ModelsTableModel.java (53%)
 create mode 100644 GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.form
 rename GUI/src/main/java/cz/fidentis/analyst/{core/ProjectTopComp.java => project/ProjectPanel.java} (68%)
 create mode 100644 GUI/src/main/java/cz/fidentis/analyst/project/ProjectTopComp.java
 create mode 100644 GUI/src/main/java/cz/fidentis/analyst/project/events/AllFacesLoaded.java
 create mode 100644 GUI/src/main/java/cz/fidentis/analyst/project/events/FaceDeselected.java
 create mode 100644 GUI/src/main/java/cz/fidentis/analyst/project/events/FaceSelected.java
 create mode 100644 GUI/src/main/java/cz/fidentis/analyst/project/events/ProjectEvent.java
 create mode 100644 GUI/src/main/java/cz/fidentis/analyst/project/events/ProjectListener.java
 create mode 100644 GUI/src/main/resources/cz/fidentis/analyst/project/Bundle.properties
 create mode 100644 GUI/src/main/resources/face160x160.png
 create mode 100644 GUI/src/main/resources/face16x16.png
 create mode 100644 GUI/src/main/resources/face200x200.png
 create mode 100644 GUI/src/main/resources/face32x32.png
 create mode 100644 GUI/src/main/resources/filter28x28.png
 create mode 100644 GUI/src/main/resources/warning16x16.png

diff --git a/Comparison/src/main/java/cz/fidentis/analyst/Project.java b/Comparison/src/main/java/cz/fidentis/analyst/Project.java
index 1a006fe9..14db43ce 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/Project.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/Project.java
@@ -4,6 +4,7 @@ import cz.fidentis.analyst.face.HumanFace;
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -211,18 +212,19 @@ public class Project {
      * @return loaded HumanFace
      */
     public HumanFace loadFace(String name) {
-        //File[] files = new File[getCfg().getPaths().size()];
-        //files = getCfg().openFiles().toArray(files);
         HumanFace face = this.getFaceByName(name);
-        //File file = new File(path);
-        //for ()
-        //Path path = this.getCfg().pathToFaceByName(name);
         if (face == null) {
             try {
                 Logger out = Logger.measureTime();
                 Path path = this.getCfg().getPathToFaceByName(name);
                 File file = path.toFile();
                 face = new HumanFace(file, true); // loads also landmarks, if exist
+                
+                String pathString = path.toString();
+                Path preview = Paths.get(pathString.substring(0, pathString.lastIndexOf(".")).concat("_preview.jpg"));
+                //Path previewSmall = Paths.get(pathString.substring(0, pathString.lastIndexOf(".")).concat("_preview_small.png"));
+                face.setPreview(preview);
+                this.addFace(face);
                 out.printDuration("Loaded model " + face.getShortName() +" with " + face.getMeshModel().getNumVertices() + " vertices");
             } catch (IOException ex) {
                 //ex.printStackTrace();
diff --git a/Comparison/src/main/java/cz/fidentis/analyst/ProjectConfiguration.java b/Comparison/src/main/java/cz/fidentis/analyst/ProjectConfiguration.java
index fb66bec4..3f42efb6 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/ProjectConfiguration.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/ProjectConfiguration.java
@@ -10,6 +10,7 @@ import java.util.Map;
 /**
  * This class encapsulates data important for project (re)storing such as paths
  * to faces or which tabs were opened
+ * 
  * @author Matej Kovar
  */
 public class ProjectConfiguration {
@@ -40,7 +41,11 @@ public class ProjectConfiguration {
      * @return true if path was successfully added 
      */
     public boolean addPath(Path path) {
-        return paths.add(path);
+        if (paths.contains(path)) {
+            return false;
+        }
+        paths.add(path);
+        return true;
     }
     
     /**
@@ -48,7 +53,10 @@ public class ProjectConfiguration {
      * @param name String of face
      */
     public void removePath(String name) {
-        paths.removeIf(p -> p.toString().substring(p.toString().lastIndexOf(File.separatorChar) + 1, p.toString().lastIndexOf('.')).equals(name));
+        paths.removeIf(p -> p.toString().substring(
+                p.toString().lastIndexOf(File.separatorChar) + 1, 
+                p.toString().lastIndexOf('.')
+        ).equals(name));
     }
     
     /**
diff --git a/Comparison/src/main/java/cz/fidentis/analyst/face/HumanFace.java b/Comparison/src/main/java/cz/fidentis/analyst/face/HumanFace.java
index 3d9275be..15cafbc9 100644
--- a/Comparison/src/main/java/cz/fidentis/analyst/face/HumanFace.java
+++ b/Comparison/src/main/java/cz/fidentis/analyst/face/HumanFace.java
@@ -18,6 +18,7 @@ import cz.fidentis.analyst.symmetry.Plane;
 import cz.fidentis.analyst.visitors.face.HumanFaceVisitor;
 import cz.fidentis.analyst.visitors.mesh.BoundingBox;
 import cz.fidentis.analyst.visitors.mesh.BoundingBox.BBox;
+import java.awt.image.BufferedImage;
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 
@@ -28,10 +29,12 @@ import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
+import java.nio.file.Path;
 import java.util.Collections;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Objects;
+import javax.imageio.ImageIO;
 //import org.nustaq.serialization.FSTConfiguration;
 //import org.nustaq.serialization.FSTObjectInput;
 //import org.nustaq.serialization.FSTObjectOutput;
@@ -48,6 +51,7 @@ import java.util.Objects;
  * </p>
  * 
  * @author Radek Oslejsek
+ * @author Matej Kovar
  */
 public class HumanFace implements Serializable {
     
@@ -66,6 +70,8 @@ public class HumanFace implements Serializable {
     
     private final String id;
     
+    private BufferedImage preview;
+    
     /**
      * Fast (de)serialization handler
      */
@@ -351,6 +357,31 @@ public class HumanFace implements Serializable {
         return ret;
     }
     
+    /**
+     * Sets preview image
+     * @param path Path to preview
+     * @return whether preview was found and successfully set or not
+     */
+    public boolean setPreview(Path path) {
+        try {
+            if (path.toFile().exists()) {
+                preview = ImageIO.read(path.toFile());
+                return true;
+            }
+        } catch (IOException ex) {
+            ex.printStackTrace();
+        }
+        return false;
+    }
+    
+    /**
+     * Gets preview image
+     * @return preview photo (or {@code null})
+     */
+    public BufferedImage getPreview() {
+        return this.preview;
+    }
+    
     /**
      * Tries to find a file with landmarks definition based on the name of the face's OBJ file.
      * @return The file with landmarks or {@code null}
diff --git a/GUI/pom.xml b/GUI/pom.xml
index 4a1aeea3..7af2194f 100644
--- a/GUI/pom.xml
+++ b/GUI/pom.xml
@@ -154,6 +154,11 @@
             <version>2.13.0</version>
             <type>jar</type>
         </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>30.1-jre</version>
+        </dependency>
     </dependencies>
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
diff --git a/GUI/src/main/java/cz/fidentis/analyst/batch/BatchAction.java b/GUI/src/main/java/cz/fidentis/analyst/batch/BatchAction.java
index 79f143e9..ae5c2b58 100644
--- a/GUI/src/main/java/cz/fidentis/analyst/batch/BatchAction.java
+++ b/GUI/src/main/java/cz/fidentis/analyst/batch/BatchAction.java
@@ -8,7 +8,7 @@ import cz.fidentis.analyst.face.HumanFace;
 import cz.fidentis.analyst.face.events.HumanFaceEvent;
 import cz.fidentis.analyst.face.events.HumanFaceListener;
 import cz.fidentis.analyst.core.ProgressDialog;
-import cz.fidentis.analyst.core.ProjectTopComp;
+import cz.fidentis.analyst.project.ProjectTopComp;
 import cz.fidentis.analyst.scene.DrawableFace;
 import java.awt.event.ActionEvent;
 import java.beans.PropertyChangeEvent;
diff --git a/GUI/src/main/java/cz/fidentis/analyst/batch/BatchPanel.java b/GUI/src/main/java/cz/fidentis/analyst/batch/BatchPanel.java
index adfd35e8..50177304 100644
--- a/GUI/src/main/java/cz/fidentis/analyst/batch/BatchPanel.java
+++ b/GUI/src/main/java/cz/fidentis/analyst/batch/BatchPanel.java
@@ -2,7 +2,7 @@ package cz.fidentis.analyst.batch;
 
 import cz.fidentis.analyst.Logger;
 import cz.fidentis.analyst.core.ControlPanel;
-import cz.fidentis.analyst.core.ProjectTopComp;
+import cz.fidentis.analyst.project.ProjectTopComp;
 import cz.fidentis.analyst.face.HumanFace;
 import cz.fidentis.analyst.face.HumanFaceFactory;
 import cz.fidentis.analyst.mesh.io.MeshObjExporter;
diff --git a/GUI/src/main/java/cz/fidentis/analyst/core/OutputWindowThread.java b/GUI/src/main/java/cz/fidentis/analyst/core/OutputWindowThread.java
index eed010d2..ee27fd8c 100644
--- a/GUI/src/main/java/cz/fidentis/analyst/core/OutputWindowThread.java
+++ b/GUI/src/main/java/cz/fidentis/analyst/core/OutputWindowThread.java
@@ -15,7 +15,7 @@ import org.openide.windows.WindowManager;
  * the {@link cz.fidentis.analyst.Logger} and displays them in the output window.
  * 
  * This singleton is currently executed from 
- * the {@link cz.fidentis.analyst.core.ProjectTopComp}, which is always presented
+ * the {@link cz.fidentis.analyst.project.ProjectTopComp}, which is always presented
  * in the FIDENTIS application.
  *
  * @author Radek Oslejsek
diff --git a/GUI/src/main/java/cz/fidentis/analyst/core/ProjectTopComp.form b/GUI/src/main/java/cz/fidentis/analyst/core/ProjectTopComp.form
deleted file mode 100644
index 8f592816..00000000
--- a/GUI/src/main/java/cz/fidentis/analyst/core/ProjectTopComp.form
+++ /dev/null
@@ -1,441 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-
-<!--
-
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-
--->
-
-<Form version="1.9" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
-  <Properties>
-    <Property name="opaque" type="boolean" value="true"/>
-  </Properties>
-  <AuxValues>
-    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
-    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
-    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
-    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
-    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
-    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
-    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
-    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
-    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
-  </AuxValues>
-
-  <Layout>
-    <DimensionLayout dim="0">
-      <Group type="103" groupAlignment="0" attributes="0">
-          <Component id="mainScrollPanel" alignment="1" max="32767" attributes="0"/>
-      </Group>
-    </DimensionLayout>
-    <DimensionLayout dim="1">
-      <Group type="103" groupAlignment="0" attributes="0">
-          <Component id="mainScrollPanel" alignment="0" pref="871" max="32767" attributes="0"/>
-      </Group>
-    </DimensionLayout>
-  </Layout>
-  <SubComponents>
-    <Container class="javax.swing.JScrollPane" name="mainScrollPanel">
-      <AuxValues>
-        <AuxValue name="JavaCodeGenerator_LayoutCodePost" type="java.lang.String" value="mainScrollPanel.setSize(ControlPanel.CONTROL_PANEL_WIDTH, ControlPanel.HEIGHT);"/>
-      </AuxValues>
-
-      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
-      <SubComponents>
-        <Container class="javax.swing.JPanel" name="mainPanel">
-
-          <Layout>
-            <DimensionLayout dim="0">
-              <Group type="103" groupAlignment="0" attributes="0">
-                  <Group type="102" attributes="0">
-                      <EmptySpace max="-2" attributes="0"/>
-                      <Group type="103" groupAlignment="0" max="-2" attributes="0">
-                          <Component id="buttonsPanel" max="32767" attributes="0"/>
-                          <Component id="faceTableScrollPanel" pref="863" max="32767" attributes="0"/>
-                      </Group>
-                      <EmptySpace max="32767" attributes="0"/>
-                      <Group type="103" groupAlignment="1" attributes="0">
-                          <Group type="102" alignment="1" attributes="0">
-                              <Component id="newProjectButton" min="-2" max="-2" attributes="0"/>
-                              <EmptySpace type="separate" max="-2" attributes="0"/>
-                              <Component id="saveProjectButton" min="-2" max="-2" attributes="0"/>
-                              <EmptySpace type="separate" max="-2" attributes="0"/>
-                              <Component id="openProjectButton" min="-2" max="-2" attributes="0"/>
-                          </Group>
-                          <Group type="103" alignment="1" groupAlignment="0" max="-2" attributes="0">
-                              <Component id="filterPanel" pref="363" max="32767" attributes="0"/>
-                              <Component id="infoPanel" pref="363" max="32767" attributes="0"/>
-                          </Group>
-                      </Group>
-                      <EmptySpace min="-2" pref="20" max="-2" attributes="0"/>
-                  </Group>
-              </Group>
-            </DimensionLayout>
-            <DimensionLayout dim="1">
-              <Group type="103" groupAlignment="0" attributes="0">
-                  <Group type="102" attributes="0">
-                      <EmptySpace max="-2" attributes="0"/>
-                      <Group type="103" groupAlignment="0" attributes="0">
-                          <Group type="103" groupAlignment="0" attributes="0">
-                              <Group type="102" attributes="0">
-                                  <Component id="buttonsPanel" min="-2" max="-2" attributes="0"/>
-                                  <EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
-                              </Group>
-                              <Group type="102" alignment="1" attributes="0">
-                                  <Group type="103" groupAlignment="3" attributes="0">
-                                      <Component id="saveProjectButton" alignment="3" min="-2" max="-2" attributes="0"/>
-                                      <Component id="openProjectButton" alignment="3" min="-2" max="-2" attributes="0"/>
-                                  </Group>
-                                  <EmptySpace type="separate" max="-2" attributes="0"/>
-                              </Group>
-                          </Group>
-                          <Group type="102" alignment="1" attributes="0">
-                              <Component id="newProjectButton" min="-2" max="-2" attributes="0"/>
-                              <EmptySpace type="separate" max="-2" attributes="0"/>
-                          </Group>
-                      </Group>
-                      <Group type="103" groupAlignment="0" max="-2" attributes="0">
-                          <Group type="102" attributes="0">
-                              <Component id="filterPanel" min="-2" max="-2" attributes="0"/>
-                              <EmptySpace min="-2" pref="28" max="-2" attributes="0"/>
-                              <Component id="infoPanel" min="-2" pref="316" max="-2" attributes="0"/>
-                          </Group>
-                          <Component id="faceTableScrollPanel" max="32767" attributes="0"/>
-                      </Group>
-                      <EmptySpace max="-2" attributes="0"/>
-                  </Group>
-              </Group>
-            </DimensionLayout>
-          </Layout>
-          <SubComponents>
-            <Container class="javax.swing.JPanel" name="buttonsPanel">
-              <Properties>
-                <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
-                  <Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
-                    <EtchetBorder/>
-                  </Border>
-                </Property>
-                <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
-                  <Dimension value="[0, 0]"/>
-                </Property>
-              </Properties>
-
-              <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
-              <SubComponents>
-                <Component class="javax.swing.JButton" name="addButton">
-                  <Properties>
-                    <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
-                      <Font name="Tahoma" size="12" style="0"/>
-                    </Property>
-                    <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-                      <ResourceString bundle="cz/fidentis/analyst/core/Bundle.properties" key="ProjectTopComp.addButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
-                    </Property>
-                  </Properties>
-                  <Events>
-                    <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="addButtonMouseClicked"/>
-                  </Events>
-                  <Constraints>
-                    <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
-                      <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="20" ipadY="0" insetsTop="16" insetsLeft="16" insetsBottom="13" insetsRight="4" anchor="13" weightX="0.0" weightY="0.0"/>
-                    </Constraint>
-                  </Constraints>
-                </Component>
-                <Component class="javax.swing.JButton" name="removeButton">
-                  <Properties>
-                    <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
-                      <Font name="Tahoma" size="12" style="0"/>
-                    </Property>
-                    <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-                      <ResourceString bundle="cz/fidentis/analyst/core/Bundle.properties" key="ProjectTopComp.removeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
-                    </Property>
-                  </Properties>
-                  <Events>
-                    <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="removeButtonMouseClicked"/>
-                  </Events>
-                  <Constraints>
-                    <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
-                      <GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="22" insetsBottom="13" insetsRight="4" anchor="18" weightX="0.0" weightY="0.0"/>
-                    </Constraint>
-                  </Constraints>
-                </Component>
-                <Component class="javax.swing.JButton" name="selectAllButton">
-                  <Properties>
-                    <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
-                      <Font name="Tahoma" size="12" style="0"/>
-                    </Property>
-                    <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-                      <ResourceString bundle="cz/fidentis/analyst/core/Bundle.properties" key="ProjectTopComp.selectAllButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
-                    </Property>
-                  </Properties>
-                  <Events>
-                    <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="selectAllButtonMouseClicked"/>
-                  </Events>
-                  <Constraints>
-                    <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
-                      <GridBagConstraints gridX="2" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="22" insetsBottom="13" insetsRight="4" anchor="18" weightX="0.0" weightY="0.0"/>
-                    </Constraint>
-                  </Constraints>
-                </Component>
-                <Component class="javax.swing.JButton" name="deselectAllButton">
-                  <Properties>
-                    <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
-                      <Font name="Tahoma" size="12" style="0"/>
-                    </Property>
-                    <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-                      <ResourceString bundle="cz/fidentis/analyst/core/Bundle.properties" key="ProjectTopComp.deselectAllButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
-                    </Property>
-                  </Properties>
-                  <Events>
-                    <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="deselectAllButtonMouseClicked"/>
-                  </Events>
-                  <Constraints>
-                    <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
-                      <GridBagConstraints gridX="3" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="22" insetsBottom="13" insetsRight="4" anchor="18" weightX="0.0" weightY="0.0"/>
-                    </Constraint>
-                  </Constraints>
-                </Component>
-                <Component class="javax.swing.JButton" name="inflateButton">
-                  <Properties>
-                    <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
-                      <Font name="Tahoma" size="12" style="0"/>
-                    </Property>
-                    <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-                      <ResourceString bundle="cz/fidentis/analyst/core/Bundle.properties" key="ProjectTopComp.inflateButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
-                    </Property>
-                    <Property name="alignmentX" type="float" value="0.5"/>
-                  </Properties>
-                  <Events>
-                    <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="inflateButtonMouseClicked"/>
-                  </Events>
-                  <Constraints>
-                    <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
-                      <GridBagConstraints gridX="4" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="22" insetsBottom="13" insetsRight="4" anchor="18" weightX="0.0" weightY="0.0"/>
-                    </Constraint>
-                  </Constraints>
-                </Component>
-                <Component class="javax.swing.JButton" name="oneOnOneButton">
-                  <Properties>
-                    <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
-                      <Font name="Tahoma" size="12" style="1"/>
-                    </Property>
-                    <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-                      <ResourceString bundle="cz/fidentis/analyst/core/Bundle.properties" key="ProjectTopComp.oneOnOneButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
-                    </Property>
-                    <Property name="alignmentX" type="float" value="0.5"/>
-                  </Properties>
-                  <Events>
-                    <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="oneOnOneButtonMouseClicked"/>
-                  </Events>
-                  <Constraints>
-                    <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
-                      <GridBagConstraints gridX="6" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="11" insetsBottom="13" insetsRight="4" anchor="18" weightX="0.0" weightY="0.0"/>
-                    </Constraint>
-                  </Constraints>
-                </Component>
-                <Component class="javax.swing.JButton" name="manyToManyButton">
-                  <Properties>
-                    <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
-                      <Font name="Tahoma" size="12" style="1"/>
-                    </Property>
-                    <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-                      <ResourceString bundle="cz/fidentis/analyst/core/Bundle.properties" key="ProjectTopComp.manyToManyButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
-                    </Property>
-                  </Properties>
-                  <Events>
-                    <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="manyToManyButtonMouseClicked"/>
-                  </Events>
-                  <Constraints>
-                    <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
-                      <GridBagConstraints gridX="5" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="30" insetsBottom="13" insetsRight="4" anchor="18" weightX="0.0" weightY="0.0"/>
-                    </Constraint>
-                  </Constraints>
-                </Component>
-                <Component class="javax.swing.JButton" name="analyseButton">
-                  <Properties>
-                    <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
-                      <Font name="Tahoma" size="12" style="1"/>
-                    </Property>
-                    <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-                      <ResourceString bundle="cz/fidentis/analyst/core/Bundle.properties" key="ProjectTopComp.analyseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
-                    </Property>
-                  </Properties>
-                  <Events>
-                    <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="analyseButtonMouseClicked"/>
-                  </Events>
-                  <Constraints>
-                    <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
-                      <GridBagConstraints gridX="7" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="11" insetsBottom="13" insetsRight="4" anchor="10" weightX="0.0" weightY="0.0"/>
-                    </Constraint>
-                  </Constraints>
-                </Component>
-              </SubComponents>
-            </Container>
-            <Container class="javax.swing.JScrollPane" name="faceTableScrollPanel">
-              <Properties>
-                <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
-                  <Dimension value="[812, 750]"/>
-                </Property>
-              </Properties>
-              <AuxValues>
-                <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
-              </AuxValues>
-
-              <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
-              <SubComponents>
-                <Component class="javax.swing.JTable" name="table">
-                  <Properties>
-                    <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor" postCode="table.getTableHeader().setOpaque(false);&#xa;table.getTableHeader().setBackground(new java.awt.Color(204,204,204));&#xa;table.getTableHeader().setFont(new java.awt.Font(&quot;Tahoma&quot;, 0, 18));&#xa;model.addTableModelListener(new TableModelListener() {&#xa;&#xa;    public void tableChanged(TableModelEvent e) {&#xa;        jTable1TableChanged(e);&#xa;    }&#xa;});">
-                      <Font name="Tahoma" size="18" style="0"/>
-                    </Property>
-                    <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor" postCode="table.getColumnModel().getColumn(0).setMaxWidth(50);&#xa;table.getColumnModel().getColumn(2).setMaxWidth(75);&#xa;table.getTableHeader().getColumnModel().getColumn(0).setMaxWidth(50);&#xa;table.getTableHeader().getColumnModel().getColumn(2).setMaxWidth(75);">
-                      <Connection code="model" type="code"/>
-                    </Property>
-                    <Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor">
-                      <TableColumnModel selectionModel="0"/>
-                    </Property>
-                    <Property name="dragEnabled" type="boolean" value="true"/>
-                    <Property name="rowHeight" type="int" value="40"/>
-                    <Property name="selectionBackground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
-                      <Color blue="ff" green="cc" red="66" type="rgb"/>
-                    </Property>
-                    <Property name="selectionMode" type="int" value="0"/>
-                    <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
-                      <TableHeader reorderingAllowed="false" resizingAllowed="true"/>
-                    </Property>
-                  </Properties>
-                  <Events>
-                    <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="tableMouseClicked"/>
-                  </Events>
-                  <AuxValues>
-                    <AuxValue name="JavaCodeGenerator_InitCodePre" type="java.lang.String" value="table.setSize(faceTableScrollPanel.getWidth(), faceTableScrollPanel.getHeight());"/>
-                  </AuxValues>
-                </Component>
-              </SubComponents>
-            </Container>
-            <Container class="javax.swing.JPanel" name="filterPanel">
-              <Properties>
-                <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
-                  <Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
-                    <EtchetBorder/>
-                  </Border>
-                </Property>
-                <Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
-                  <Dimension value="[342, 424]"/>
-                </Property>
-                <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
-                  <Dimension value="[342, 424]"/>
-                </Property>
-              </Properties>
-
-              <Layout>
-                <DimensionLayout dim="0">
-                  <Group type="103" groupAlignment="0" attributes="0">
-                      <EmptySpace min="0" pref="359" max="32767" attributes="0"/>
-                  </Group>
-                </DimensionLayout>
-                <DimensionLayout dim="1">
-                  <Group type="103" groupAlignment="0" attributes="0">
-                      <EmptySpace min="0" pref="420" max="32767" attributes="0"/>
-                  </Group>
-                </DimensionLayout>
-              </Layout>
-            </Container>
-            <Container class="javax.swing.JPanel" name="infoPanel">
-              <Properties>
-                <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
-                  <Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
-                    <EtchetBorder/>
-                  </Border>
-                </Property>
-                <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
-                  <Dimension value="[349, 363]"/>
-                </Property>
-              </Properties>
-              <AuxValues>
-                <AuxValue name="JavaCodeGenerator_LayoutCodePost" type="java.lang.String" value="infoPanel.setVisible(false);"/>
-              </AuxValues>
-
-              <Layout>
-                <DimensionLayout dim="0">
-                  <Group type="103" groupAlignment="0" attributes="0">
-                      <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
-                  </Group>
-                </DimensionLayout>
-                <DimensionLayout dim="1">
-                  <Group type="103" groupAlignment="0" attributes="0">
-                      <EmptySpace min="0" pref="312" max="32767" attributes="0"/>
-                  </Group>
-                </DimensionLayout>
-              </Layout>
-            </Container>
-            <Component class="javax.swing.JButton" name="saveProjectButton">
-              <Properties>
-                <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
-                  <Font name="Tahoma" size="12" style="0"/>
-                </Property>
-                <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
-                  <Image iconType="3" name="/save100x24.png"/>
-                </Property>
-                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-                  <ResourceString bundle="cz/fidentis/analyst/core/Bundle.properties" key="ProjectTopComp.saveProjectButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
-                </Property>
-              </Properties>
-              <AccessibilityProperties>
-                <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-                  <ResourceString bundle="cz/fidentis/analyst/core/Bundle.properties" key="ProjectTopComp.saveProjectButton.AccessibleContext.accessibleName" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
-                </Property>
-              </AccessibilityProperties>
-              <Events>
-                <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="saveProjectButtonMouseClicked"/>
-              </Events>
-            </Component>
-            <Component class="javax.swing.JButton" name="openProjectButton">
-              <Properties>
-                <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
-                  <Font name="Tahoma" size="12" style="0"/>
-                </Property>
-                <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
-                  <Image iconType="3" name="/open100x24.png"/>
-                </Property>
-                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-                  <ResourceString bundle="cz/fidentis/analyst/core/Bundle.properties" key="ProjectTopComp.openProjectButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
-                </Property>
-              </Properties>
-              <Events>
-                <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="openProjectButtonMouseClicked"/>
-              </Events>
-            </Component>
-            <Component class="javax.swing.JButton" name="newProjectButton">
-              <Properties>
-                <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
-                  <Image iconType="3" name="/new100x24.png"/>
-                </Property>
-                <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
-                  <ResourceString bundle="cz/fidentis/analyst/core/Bundle.properties" key="ProjectTopComp.newProjectButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
-                </Property>
-              </Properties>
-              <Events>
-                <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="newProjectButtonMouseClicked"/>
-              </Events>
-            </Component>
-          </SubComponents>
-        </Container>
-      </SubComponents>
-    </Container>
-  </SubComponents>
-</Form>
diff --git a/GUI/src/main/java/cz/fidentis/analyst/dashboard/FaceStatePanel.java b/GUI/src/main/java/cz/fidentis/analyst/dashboard/FaceStatePanel.java
deleted file mode 100644
index 173f96e0..00000000
--- a/GUI/src/main/java/cz/fidentis/analyst/dashboard/FaceStatePanel.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package cz.fidentis.analyst.dashboard;
-
-import cz.fidentis.analyst.core.ControlPanelBuilder;
-import cz.fidentis.analyst.face.HumanFace;
-import javax.swing.ImageIcon;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-
-/**
- * Panel for showing face state information
- * 
- * @author Matej Kovar
- */
-public final class FaceStatePanel extends JPanel {
-
-    private final JPanel controlPanel;
-    
-    private final ImageIcon notCheck = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "notCheck16x16.png"));
-    private final ImageIcon check = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "check16x16.png"));
-    private final JLabel hasKDtree;
-    private final JLabel hasFeaturePoints;
-    private final JLabel tmp1;
-    private final JLabel tmp2;
-    private final JLabel tmp3;
-
-    /**
-     * Constructor
-     * @param controlPanel control panel where components will be added
-     * @param face HumanFace, its state info will be shown
-     */
-    public FaceStatePanel(JPanel controlPanel, HumanFace face) {
-        
-        this.controlPanel = controlPanel;
-        this.controlPanel.removeAll();
-        ControlPanelBuilder builder = new ControlPanelBuilder(this.controlPanel);
-        
-        builder.addCaptionLine("Face state");
-        builder.addLine();
-        
-        hasKDtree = builder.addLabelLine("Has KD-tree calculated");
-        if (face.hasKdTree()) {
-            hasKDtree.setIcon(check);
-        } else {
-            hasKDtree.setIcon(notCheck);
-        }
-        builder.addLine();
-
-        hasFeaturePoints = builder.addLabelLine("Has Feature points");
-        if (face.hasFeaturePoints()) {
-            hasFeaturePoints.setIcon(check);
-        } else {
-            hasFeaturePoints.setIcon(notCheck);
-        }
-        builder.addLine();
-
-        tmp1 = builder.addLabelLine("...");
-        tmp1.setIcon(notCheck);
-        builder.addLine();
-
-        tmp2 = builder.addLabelLine("...");
-        tmp2.setIcon(notCheck);
-        builder.addLine();
-
-        tmp3 = builder.addLabelLine("...");
-        tmp3.setIcon(notCheck);
-        builder.addLine();
-    }  
-}
diff --git a/GUI/src/main/java/cz/fidentis/analyst/dashboard/FilterPanel.java b/GUI/src/main/java/cz/fidentis/analyst/dashboard/FilterPanel.java
deleted file mode 100644
index 9c352f39..00000000
--- a/GUI/src/main/java/cz/fidentis/analyst/dashboard/FilterPanel.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package cz.fidentis.analyst.dashboard;
-
-import cz.fidentis.analyst.core.ControlPanelBuilder;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import javax.swing.JCheckBox;
-import javax.swing.JPanel;
-
-/**
- * Panel for showing filter options
- * 
- * @author Matej Kovar
- */
-public final class FilterPanel extends JPanel {
-
-    private final JPanel controlPanel;
-    
-    private boolean kdTreeFilter = false;
-    private boolean featurePointsFilter = false;
-    private boolean alphabeticalFilter = false;
-   
-
-    /**
-     * Constructor
-     * @param controlPanel control panel where components will be added
-     * @param action ActionListener
-     */
-    public FilterPanel(JPanel controlPanel, ActionListener action) {
-        
-        this.controlPanel = controlPanel;
-        ControlPanelBuilder builder = new ControlPanelBuilder(this.controlPanel);
-        
-        builder.addCaptionLine("Filter");
-        builder.addLine();
-        
-        builder.addCheckBoxOptionLine(
-                null, 
-                "has KD-tree", 
-                false, 
-                (ActionEvent e) -> { 
-                    kdTreeFilter = (((JCheckBox) e.getSource()).isSelected());
-                }
-        );
-        builder.addLine();
-        
-        builder.addCheckBoxOptionLine(
-                null, 
-                "has feature points", 
-                false, 
-                (ActionEvent e) -> { 
-                    featurePointsFilter = (((JCheckBox) e.getSource()).isSelected());
-                }
-        );
-        builder.addLine();
-                
-        builder.addCheckBoxOptionLine(
-                null, 
-                "...", 
-                false, 
-                null
-        );
-        builder.addLine();
-        
-        builder.addCheckBoxOptionLine(
-                null, 
-                "...", 
-                false, 
-                null
-        );
-        builder.addLine();
-        
-        builder.addCheckBoxOptionLine(
-                null, 
-                "alphabetical", 
-                false, 
-                (ActionEvent e) -> { 
-                    alphabeticalFilter = (((JCheckBox) e.getSource()).isSelected());
-                }
-        );
-        builder.addLine();
-        
-        builder.addButton(
-                "Apply filter",
-                action
-        );
-    }
-
-    public boolean isKdTreeFilter() {
-        return kdTreeFilter;
-    }
-
-    public boolean isFeaturePointsFilter() {
-        return featurePointsFilter;
-    }
-    
-    public boolean isAlphaBeticalFilter() {
-        return alphabeticalFilter;
-    }
-    
-}
diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.form b/GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.form
new file mode 100644
index 00000000..496cdadc
--- /dev/null
+++ b/GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.form
@@ -0,0 +1,308 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Component id="filePanel" max="32767" attributes="0"/>
+                  <Component id="facePanel" alignment="0" max="32767" attributes="0"/>
+                  <Component id="photoPanel" alignment="0" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
+              <Component id="photoPanel" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Component id="filePanel" min="-2" max="-2" attributes="0"/>
+              <EmptySpace type="separate" max="-2" attributes="0"/>
+              <Component id="facePanel" max="32767" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JPanel" name="filePanel">
+      <Properties>
+        <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+          <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
+            <TitledBorder title="&lt;FaceStatePanel.filePanel.border.title&gt;">
+              <ResourceString PropertyName="titleX" bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.filePanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+              <Font PropertyName="font" name="Dialog" size="12" style="1"/>
+            </TitledBorder>
+          </Border>
+        </Property>
+      </Properties>
+      <AccessibilityProperties>
+        <Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.filePanel.AccessibleContext.accessibleName" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </AccessibilityProperties>
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" attributes="0">
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Component id="pathLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                      <Component id="sizeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace min="-2" pref="49" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Component id="sizeOutput" min="-2" max="-2" attributes="0"/>
+                      <Component id="pathOutput" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace max="32767" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="0" attributes="0">
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="3" attributes="0">
+                      <Component id="pathLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                      <Component id="pathOutput" alignment="3" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace min="-2" pref="13" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="3" attributes="0">
+                      <Component id="sizeLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                      <Component id="sizeOutput" alignment="3" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace pref="41" max="32767" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Component class="javax.swing.JLabel" name="pathLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.pathLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="enabled" type="boolean" value="false"/>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="sizeLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.sizeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="enabled" type="boolean" value="false"/>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="pathOutput">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.pathOutput.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="sizeOutput">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.sizeOutput.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Container class="javax.swing.JPanel" name="facePanel">
+      <Properties>
+        <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+          <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
+            <TitledBorder title="&lt;FaceStatePanel.facePanel.border.title&gt;">
+              <ResourceString PropertyName="titleX" bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.facePanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+              <Font PropertyName="font" name="Dialog" size="12" style="1"/>
+            </TitledBorder>
+          </Border>
+        </Property>
+      </Properties>
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" attributes="0">
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Component id="kdTreeLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                      <Component id="featurePointsLoadedLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace min="-2" pref="22" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Component id="hasFPOutput" min="-2" max="-2" attributes="0"/>
+                      <Component id="hasKDOutput" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace pref="423" max="32767" attributes="0"/>
+              </Group>
+              <Group type="102" alignment="1" attributes="0">
+                  <EmptySpace max="32767" attributes="0"/>
+                  <Component id="warningLabel" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Component id="faceNotLoadedLabel" min="-2" max="-2" attributes="0"/>
+                      <Component id="loadFaceButton" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace min="-2" pref="33" max="-2" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="0" attributes="0">
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="3" attributes="0">
+                      <Component id="kdTreeLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                      <Component id="hasKDOutput" alignment="3" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace type="separate" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="3" attributes="0">
+                      <Component id="featurePointsLoadedLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                      <Component id="hasFPOutput" alignment="3" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace min="-2" pref="56" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="1" attributes="0">
+                      <Component id="warningLabel" min="-2" max="-2" attributes="0"/>
+                      <Component id="faceNotLoadedLabel" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                  <Component id="loadFaceButton" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace pref="44" max="32767" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Component class="javax.swing.JLabel" name="kdTreeLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.kdTreeLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="enabled" type="boolean" value="false"/>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="featurePointsLoadedLabel">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.featurePointsLoadedLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="enabled" type="boolean" value="false"/>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="hasKDOutput">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.hasKDOutput.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="hasFPOutput">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.hasFPOutput.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="faceNotLoadedLabel">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="12" style="1"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.faceNotLoadedLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <AuxValues>
+            <AuxValue name="JavaCodeGenerator_InitCodePost" type="java.lang.String" value="faceNotLoadedLabel.setVisible(false);"/>
+          </AuxValues>
+        </Component>
+        <Component class="javax.swing.JButton" name="loadFaceButton">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.loadFaceButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <AuxValues>
+            <AuxValue name="JavaCodeGenerator_InitCodePre" type="java.lang.String" value="loadFaceButton.setVisible(false);"/>
+          </AuxValues>
+        </Component>
+        <Component class="javax.swing.JLabel" name="warningLabel">
+          <Properties>
+            <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor" postCode="warningLabel.setVisible(false);">
+              <Image iconType="3" name="/warning16x16.png"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.warningLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Container class="javax.swing.JPanel" name="photoPanel">
+      <Properties>
+        <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+          <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
+            <TitledBorder title="&lt;FaceStatePanel.photoPanel.border.title&gt;">
+              <ResourceString PropertyName="titleX" bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.photoPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+              <Font PropertyName="font" name="Dialog" size="12" style="1"/>
+            </TitledBorder>
+          </Border>
+        </Property>
+      </Properties>
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="0" attributes="0">
+                  <EmptySpace min="-2" pref="55" max="-2" attributes="0"/>
+                  <Component id="photo" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace min="-2" pref="55" max="-2" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="0" attributes="0">
+                  <EmptySpace max="32767" attributes="0"/>
+                  <Component id="photo" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace max="32767" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Component class="javax.swing.JLabel" name="photo">
+          <Properties>
+            <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+              <Image iconType="3" name="/face160x160.png"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FaceStatePanel.photo.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+  </SubComponents>
+</Form>
diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.java b/GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.java
new file mode 100644
index 00000000..4cd359e1
--- /dev/null
+++ b/GUI/src/main/java/cz/fidentis/analyst/project/FaceStatePanel.java
@@ -0,0 +1,404 @@
+package cz.fidentis.analyst.project;
+
+import cz.fidentis.analyst.core.ControlPanel;
+import cz.fidentis.analyst.project.events.FaceDeselected;
+import cz.fidentis.analyst.project.events.ProjectListener;
+import cz.fidentis.analyst.project.events.FaceSelected;
+import cz.fidentis.analyst.project.events.ProjectEvent;
+import cz.fidentis.analyst.face.HumanFace;
+import java.awt.Image;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import javax.imageio.ImageIO;
+import javax.swing.ImageIcon;
+
+/**
+ *
+ * @author Matej Kovar
+ */
+public class FaceStatePanel extends ControlPanel implements ProjectListener {
+
+    private final ImageIcon notCheck = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "notCheck16x16.png"));
+    private final ImageIcon check = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "check16x16.png"));
+    //private final ImageIcon warning = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "warning16x16.png"));
+    private final ImageIcon anonymousFace = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "face160x160.png"));
+    
+    public static final String ICON = "head28x28.png";
+    public static final String NAME = "Face State";
+    
+
+    /**
+     * Panel with face information
+     * @param loadFaceListener ActionListener listens when load face button is clicked
+     */
+    public FaceStatePanel(ActionListener loadFaceListener) {
+        
+        this.setName(NAME);
+        initComponents();
+        loadFaceButton.addActionListener(loadFaceListener);
+        //210 140
+
+    }
+
+    /**
+     * This method is called from within the constructor to initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is always
+     * regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        filePanel = new javax.swing.JPanel();
+        pathLabel = new javax.swing.JLabel();
+        sizeLabel = new javax.swing.JLabel();
+        pathOutput = new javax.swing.JLabel();
+        sizeOutput = new javax.swing.JLabel();
+        facePanel = new javax.swing.JPanel();
+        kdTreeLabel = new javax.swing.JLabel();
+        featurePointsLoadedLabel = new javax.swing.JLabel();
+        hasKDOutput = new javax.swing.JLabel();
+        hasFPOutput = new javax.swing.JLabel();
+        faceNotLoadedLabel = new javax.swing.JLabel();
+        loadFaceButton = new javax.swing.JButton();
+        warningLabel = new javax.swing.JLabel();
+        photoPanel = new javax.swing.JPanel();
+        photo = new javax.swing.JLabel();
+
+        filePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.filePanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 1, 12))); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(pathLabel, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.pathLabel.text")); // NOI18N
+        pathLabel.setEnabled(false);
+
+        org.openide.awt.Mnemonics.setLocalizedText(sizeLabel, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.sizeLabel.text")); // NOI18N
+        sizeLabel.setEnabled(false);
+
+        org.openide.awt.Mnemonics.setLocalizedText(pathOutput, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.pathOutput.text")); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(sizeOutput, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.sizeOutput.text")); // NOI18N
+
+        javax.swing.GroupLayout filePanelLayout = new javax.swing.GroupLayout(filePanel);
+        filePanel.setLayout(filePanelLayout);
+        filePanelLayout.setHorizontalGroup(
+            filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(filePanelLayout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(pathLabel)
+                    .addComponent(sizeLabel))
+                .addGap(49, 49, 49)
+                .addGroup(filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(sizeOutput)
+                    .addComponent(pathOutput))
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+        );
+        filePanelLayout.setVerticalGroup(
+            filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(filePanelLayout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(pathLabel)
+                    .addComponent(pathOutput))
+                .addGap(13, 13, 13)
+                .addGroup(filePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(sizeLabel)
+                    .addComponent(sizeOutput))
+                .addContainerGap(41, Short.MAX_VALUE))
+        );
+
+        facePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.facePanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 1, 12))); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(kdTreeLabel, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.kdTreeLabel.text")); // NOI18N
+        kdTreeLabel.setEnabled(false);
+
+        org.openide.awt.Mnemonics.setLocalizedText(featurePointsLoadedLabel, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.featurePointsLoadedLabel.text")); // NOI18N
+        featurePointsLoadedLabel.setEnabled(false);
+
+        org.openide.awt.Mnemonics.setLocalizedText(hasKDOutput, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.hasKDOutput.text")); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(hasFPOutput, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.hasFPOutput.text")); // NOI18N
+
+        faceNotLoadedLabel.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(faceNotLoadedLabel, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.faceNotLoadedLabel.text")); // NOI18N
+        faceNotLoadedLabel.setVisible(false);
+
+        loadFaceButton.setVisible(false);
+        org.openide.awt.Mnemonics.setLocalizedText(loadFaceButton, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.loadFaceButton.text")); // NOI18N
+
+        warningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/warning16x16.png"))); // NOI18N
+        warningLabel.setVisible(false);
+        org.openide.awt.Mnemonics.setLocalizedText(warningLabel, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.warningLabel.text")); // NOI18N
+
+        javax.swing.GroupLayout facePanelLayout = new javax.swing.GroupLayout(facePanel);
+        facePanel.setLayout(facePanelLayout);
+        facePanelLayout.setHorizontalGroup(
+            facePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(facePanelLayout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(facePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(kdTreeLabel)
+                    .addComponent(featurePointsLoadedLabel))
+                .addGap(22, 22, 22)
+                .addGroup(facePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(hasFPOutput)
+                    .addComponent(hasKDOutput))
+                .addContainerGap(423, Short.MAX_VALUE))
+            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, facePanelLayout.createSequentialGroup()
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                .addComponent(warningLabel)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addGroup(facePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(faceNotLoadedLabel)
+                    .addComponent(loadFaceButton))
+                .addGap(33, 33, 33))
+        );
+        facePanelLayout.setVerticalGroup(
+            facePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(facePanelLayout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(facePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(kdTreeLabel)
+                    .addComponent(hasKDOutput))
+                .addGap(18, 18, 18)
+                .addGroup(facePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(featurePointsLoadedLabel)
+                    .addComponent(hasFPOutput))
+                .addGap(56, 56, 56)
+                .addGroup(facePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                    .addComponent(warningLabel)
+                    .addComponent(faceNotLoadedLabel))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(loadFaceButton)
+                .addContainerGap(44, Short.MAX_VALUE))
+        );
+
+        photoPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.photoPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 1, 12))); // NOI18N
+
+        photo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face160x160.png"))); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(photo, org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.photo.text")); // NOI18N
+
+        javax.swing.GroupLayout photoPanelLayout = new javax.swing.GroupLayout(photoPanel);
+        photoPanel.setLayout(photoPanelLayout);
+        photoPanelLayout.setHorizontalGroup(
+            photoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(photoPanelLayout.createSequentialGroup()
+                .addGap(55, 55, 55)
+                .addComponent(photo)
+                .addGap(55, 55, 55))
+        );
+        photoPanelLayout.setVerticalGroup(
+            photoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(photoPanelLayout.createSequentialGroup()
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                .addComponent(photo)
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+        );
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(filePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                    .addComponent(facePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                    .addComponent(photoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+                .addContainerGap())
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addGap(6, 6, 6)
+                .addComponent(photoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(filePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addGap(18, 18, 18)
+                .addComponent(facePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                .addContainerGap())
+        );
+
+        filePanel.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(FaceStatePanel.class, "FaceStatePanel.filePanel.AccessibleContext.accessibleName")); // NOI18N
+    }// </editor-fold>//GEN-END:initComponents
+    
+    /**
+     * Shows face information on panel
+     * @param face HumanFace
+     * @param name String
+     * @param path Path
+     */
+    public void showFaceState(HumanFace face, String name, Path path) {
+        
+        photo.setIcon(getPhoto(face, path));
+        pathOutput.setText(getPathText(path));
+        sizeOutput.setText(getSizeText(path));
+        hasKDOutput.setIcon(getKdTree(face));
+        hasFPOutput.setIcon(getFeaturePoints(face));
+        checkFaceLoaded(face);
+    }
+    
+    @Override
+    public ImageIcon getIcon() {
+        return new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + ICON));
+    }
+    
+    /**
+     * Gets photo which would be displayed on photo panel
+     * @param face HumanFace
+     * @param path Path
+     * @return ImageIcon either loaded face preview or anonymous face when preview is not found
+     */
+    private ImageIcon getPhoto(HumanFace face, Path path) {
+        
+        ImageIcon image;
+        
+        if (face != null) {
+            if (face.getPreview() != null) {
+                return new ImageIcon(face.getPreview().getScaledInstance(240, 160, Image.SCALE_FAST));
+            }
+            return anonymousFace;
+        }
+        
+        if (path != null && path.toFile().exists()) {
+            
+            String pathString = path.toString();
+            Path preview = Paths.get(pathString.substring(0, pathString.lastIndexOf(".")).concat("_preview.jpg"));
+                
+            try {
+                image = new ImageIcon(ImageIO.read(preview.toFile()).getScaledInstance(240, 160, Image.SCALE_FAST));
+                return image;
+            } catch (IOException ex) {
+                //Exceptions.printStackTrace(ex);)
+            }
+        }
+        return anonymousFace;
+    }
+    
+    /**
+     * Gets path text
+     * @param path Path
+     * @return String path
+     */
+    private String getPathText(Path path) {
+        
+        if (path != null) {
+            pathLabel.setEnabled(true);
+            return path.toString();
+        }
+        pathLabel.setEnabled(false);
+        return "";
+    }
+    
+    /**
+     * Gets size of model ".obj"
+     * @param path Path
+     * @return String size in kB
+     */
+    private String getSizeText(Path path) {
+        
+        if (path != null && path.toFile().exists()) {
+
+            try {
+                long bytes = Files.size(path);
+                sizeLabel.setEnabled(true);
+                return String.format("%,d kB", bytes / 1024);
+                
+            } catch (IOException ex) {
+                //Exceptions.printStackTrace(ex);
+                // TODO HANDLE EXCEPTION
+            }
+        }
+        sizeLabel.setEnabled(false);
+        return "";
+    }
+    
+    /**
+     * Gets icon which shows if face has calculated KD-tree
+     * @param face HumanFace
+     * @return ImageIcon either check or notCheck
+     */
+    private ImageIcon getKdTree(HumanFace face) {
+        if (face == null) {
+            kdTreeLabel.setEnabled(false);
+            return null;
+        }
+        
+        kdTreeLabel.setEnabled(true);
+        if (face.hasKdTree()) {
+            return check;
+        }
+        return notCheck;
+    }
+    
+    /**
+     * Gets icon which shows if face has featurePoints
+     * @param face HumanFace
+     * @return ImageIcon either check or notCheck
+     */
+    private ImageIcon getFeaturePoints(HumanFace face) {
+        
+        if (face == null) {
+            featurePointsLoadedLabel.setEnabled(false);
+            return null;
+        }
+        
+        featurePointsLoadedLabel.setEnabled(true);
+        if (face.hasFeaturePoints() || face.findLandmarks() != null) {
+            return check;
+        }
+        return notCheck;
+    }
+    
+    /**
+     * Checks whether face is loaded in project or not
+     * If not, button which loads currently selected face to project shows up
+     * @param face HumanFace
+     */
+    private void checkFaceLoaded(HumanFace face) {
+        warningLabel.setVisible(face == null);
+        faceNotLoadedLabel.setVisible(face == null);
+        loadFaceButton.setVisible(face == null);
+    }
+    
+    /**
+     * All information is returned to basic value
+     */
+    public void deselectFace() {
+        this.showFaceState(null, null, null);
+        warningLabel.setVisible(false);
+        faceNotLoadedLabel.setVisible(false);
+        loadFaceButton.setVisible(false);
+    }
+
+    @Override
+    public void acceptEvent(ProjectEvent event) {
+        if (event.getClass() == FaceSelected.class) {
+            FaceSelected evt = (FaceSelected)event;
+            this.showFaceState(evt.getFace(), evt.getName(), evt.getPath());
+        } else if (event.getClass() == FaceDeselected.class){
+            this.deselectFace();
+        }        
+    }
+    
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JLabel faceNotLoadedLabel;
+    private javax.swing.JPanel facePanel;
+    private javax.swing.JLabel featurePointsLoadedLabel;
+    private javax.swing.JPanel filePanel;
+    private javax.swing.JLabel hasFPOutput;
+    private javax.swing.JLabel hasKDOutput;
+    private javax.swing.JLabel kdTreeLabel;
+    private javax.swing.JButton loadFaceButton;
+    private javax.swing.JLabel pathLabel;
+    private javax.swing.JLabel pathOutput;
+    private javax.swing.JLabel photo;
+    private javax.swing.JPanel photoPanel;
+    private javax.swing.JLabel sizeLabel;
+    private javax.swing.JLabel sizeOutput;
+    private javax.swing.JLabel warningLabel;
+    // End of variables declaration//GEN-END:variables
+
+}
diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/FilterPanel.form b/GUI/src/main/java/cz/fidentis/analyst/project/FilterPanel.form
new file mode 100644
index 00000000..7e703acc
--- /dev/null
+++ b/GUI/src/main/java/cz/fidentis/analyst/project/FilterPanel.form
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="filterPanel" max="32767" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="filterPanel" min="-2" max="-2" attributes="0"/>
+              <EmptySpace pref="270" max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JPanel" name="filterPanel">
+      <Properties>
+        <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+          <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
+            <TitledBorder title="&lt;FilterPanel.filterPanel.border.title&gt;">
+              <ResourceString PropertyName="titleX" bundle="cz/fidentis/analyst/project/Bundle.properties" key="FilterPanel.filterPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+              <Font PropertyName="font" name="Dialog" size="12" style="1"/>
+            </TitledBorder>
+          </Border>
+        </Property>
+      </Properties>
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="0" attributes="0">
+                  <EmptySpace min="-2" pref="38" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="1" attributes="0">
+                      <Component id="applyFilterButton" min="-2" max="-2" attributes="0"/>
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Component id="alphabetical" min="-2" max="-2" attributes="0"/>
+                          <Component id="hasKD" min="-2" max="-2" attributes="0"/>
+                          <Component id="hasFP" min="-2" max="-2" attributes="0"/>
+                      </Group>
+                  </Group>
+                  <EmptySpace pref="201" max="32767" attributes="0"/>
+                  <Component id="loadAllModelsButton" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace min="-2" pref="89" max="-2" attributes="0"/>
+              </Group>
+              <Group type="102" alignment="1" attributes="0">
+                  <EmptySpace max="32767" attributes="0"/>
+                  <Component id="warningLabel" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace type="unrelated" max="-2" attributes="0"/>
+                  <Component id="faceNotLoadedLabel" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace min="-2" pref="22" max="-2" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="0" attributes="0">
+                  <EmptySpace min="-2" pref="40" max="-2" attributes="0"/>
+                  <Component id="hasFP" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace type="separate" max="-2" attributes="0"/>
+                  <Component id="hasKD" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace type="separate" max="-2" attributes="0"/>
+                  <Component id="alphabetical" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace min="-2" pref="19" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="1" attributes="0">
+                      <Component id="warningLabel" min="-2" max="-2" attributes="0"/>
+                      <Component id="faceNotLoadedLabel" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace min="-2" pref="23" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="3" attributes="0">
+                      <Component id="applyFilterButton" alignment="3" min="-2" max="-2" attributes="0"/>
+                      <Component id="loadAllModelsButton" alignment="3" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace pref="69" max="32767" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Component class="javax.swing.JCheckBox" name="hasFP">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FilterPanel.hasFP.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="hasFPActionPerformed"/>
+          </Events>
+        </Component>
+        <Component class="javax.swing.JCheckBox" name="hasKD">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FilterPanel.hasKD.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="hasKDActionPerformed"/>
+          </Events>
+        </Component>
+        <Component class="javax.swing.JCheckBox" name="alphabetical">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FilterPanel.alphabetical.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="alphabeticalActionPerformed"/>
+          </Events>
+        </Component>
+        <Component class="javax.swing.JButton" name="applyFilterButton">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="12" style="1"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FilterPanel.applyFilterButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="enabled" type="boolean" value="false"/>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="warningLabel">
+          <Properties>
+            <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+              <Image iconType="3" name="/warning16x16.png"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FilterPanel.warningLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <AuxValues>
+            <AuxValue name="JavaCodeGenerator_InitCodePost" type="java.lang.String" value="warningLabel.setVisible(false);"/>
+          </AuxValues>
+        </Component>
+        <Component class="javax.swing.JLabel" name="faceNotLoadedLabel">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="12" style="1"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FilterPanel.faceNotLoadedLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <AuxValues>
+            <AuxValue name="JavaCodeGenerator_InitCodePost" type="java.lang.String" value="faceNotLoadedLabel.setVisible(false);"/>
+          </AuxValues>
+        </Component>
+        <Component class="javax.swing.JButton" name="loadAllModelsButton">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="12" style="1"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="FilterPanel.loadAllModelsButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <AuxValues>
+            <AuxValue name="JavaCodeGenerator_ListenersCodePost" type="java.lang.String" value="loadAllModelsButton.setVisible(false);"/>
+          </AuxValues>
+        </Component>
+      </SubComponents>
+    </Container>
+  </SubComponents>
+</Form>
diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/FilterPanel.java b/GUI/src/main/java/cz/fidentis/analyst/project/FilterPanel.java
new file mode 100644
index 00000000..40911de8
--- /dev/null
+++ b/GUI/src/main/java/cz/fidentis/analyst/project/FilterPanel.java
@@ -0,0 +1,237 @@
+package cz.fidentis.analyst.project;
+
+import cz.fidentis.analyst.core.ControlPanel;
+import cz.fidentis.analyst.project.events.AllFacesLoaded;
+import cz.fidentis.analyst.project.events.ProjectEvent;
+import cz.fidentis.analyst.project.events.ProjectListener;
+import java.awt.event.ActionListener;
+import javax.swing.ImageIcon;
+import javax.swing.JCheckBox;
+
+/**
+ *
+ * @author Matej Kovar
+ */
+public class FilterPanel extends ControlPanel implements ProjectListener {
+    
+    private boolean kdTreeFilter = false;
+    private boolean featurePointsFilter = false;
+    private boolean alphabeticalFilter = false;
+
+
+    public static final String ICON = "filter28x28.png";
+    public static final String NAME = "Filter";
+
+    /**
+     * Creates new form FilterPanel
+     */
+    public FilterPanel(ActionListener listenerLoadAllFaces) {
+        this.setName(NAME);
+        initComponents();
+        loadAllModelsButton.addActionListener(listenerLoadAllFaces);
+        //applyFilterButton.addActionListener(buttonListener);
+    }
+
+    /**
+     * This method is called from within the constructor to initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is always
+     * regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        filterPanel = new javax.swing.JPanel();
+        hasFP = new javax.swing.JCheckBox();
+        hasKD = new javax.swing.JCheckBox();
+        alphabetical = new javax.swing.JCheckBox();
+        applyFilterButton = new javax.swing.JButton();
+        warningLabel = new javax.swing.JLabel();
+        faceNotLoadedLabel = new javax.swing.JLabel();
+        loadAllModelsButton = new javax.swing.JButton();
+
+        filterPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.filterPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 1, 12))); // NOI18N
+
+        org.openide.awt.Mnemonics.setLocalizedText(hasFP, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.hasFP.text")); // NOI18N
+        hasFP.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                hasFPActionPerformed(evt);
+            }
+        });
+
+        org.openide.awt.Mnemonics.setLocalizedText(hasKD, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.hasKD.text")); // NOI18N
+        hasKD.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                hasKDActionPerformed(evt);
+            }
+        });
+
+        org.openide.awt.Mnemonics.setLocalizedText(alphabetical, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.alphabetical.text")); // NOI18N
+        alphabetical.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                alphabeticalActionPerformed(evt);
+            }
+        });
+
+        applyFilterButton.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(applyFilterButton, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.applyFilterButton.text")); // NOI18N
+        applyFilterButton.setEnabled(false);
+
+        warningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/warning16x16.png"))); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(warningLabel, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.warningLabel.text")); // NOI18N
+        warningLabel.setVisible(false);
+
+        faceNotLoadedLabel.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(faceNotLoadedLabel, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.faceNotLoadedLabel.text")); // NOI18N
+        faceNotLoadedLabel.setVisible(false);
+
+        loadAllModelsButton.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(loadAllModelsButton, org.openide.util.NbBundle.getMessage(FilterPanel.class, "FilterPanel.loadAllModelsButton.text")); // NOI18N
+        loadAllModelsButton.setVisible(false);
+
+        javax.swing.GroupLayout filterPanelLayout = new javax.swing.GroupLayout(filterPanel);
+        filterPanel.setLayout(filterPanelLayout);
+        filterPanelLayout.setHorizontalGroup(
+            filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(filterPanelLayout.createSequentialGroup()
+                .addGap(38, 38, 38)
+                .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                    .addComponent(applyFilterButton)
+                    .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                        .addComponent(alphabetical)
+                        .addComponent(hasKD)
+                        .addComponent(hasFP)))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 201, Short.MAX_VALUE)
+                .addComponent(loadAllModelsButton)
+                .addGap(89, 89, 89))
+            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, filterPanelLayout.createSequentialGroup()
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                .addComponent(warningLabel)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+                .addComponent(faceNotLoadedLabel)
+                .addGap(22, 22, 22))
+        );
+        filterPanelLayout.setVerticalGroup(
+            filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(filterPanelLayout.createSequentialGroup()
+                .addGap(40, 40, 40)
+                .addComponent(hasFP)
+                .addGap(18, 18, 18)
+                .addComponent(hasKD)
+                .addGap(18, 18, 18)
+                .addComponent(alphabetical)
+                .addGap(19, 19, 19)
+                .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                    .addComponent(warningLabel)
+                    .addComponent(faceNotLoadedLabel))
+                .addGap(23, 23, 23)
+                .addGroup(filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(applyFilterButton)
+                    .addComponent(loadAllModelsButton))
+                .addContainerGap(69, Short.MAX_VALUE))
+        );
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                .addContainerGap())
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(filterPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addContainerGap(270, Short.MAX_VALUE))
+        );
+    }// </editor-fold>//GEN-END:initComponents
+
+    /**
+     * Sets attribute to corresponding value based on checkbox
+     * @param evt 
+     */
+    private void hasFPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hasFPActionPerformed
+        featurePointsFilter = (((JCheckBox)evt.getSource()).isSelected());
+    }//GEN-LAST:event_hasFPActionPerformed
+
+    /**
+     * Sets attribute to corresponding value based on checkbox
+     * @param evt 
+     */
+    private void hasKDActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hasKDActionPerformed
+        kdTreeFilter = (((JCheckBox)evt.getSource()).isSelected());
+    }//GEN-LAST:event_hasKDActionPerformed
+
+    /**
+     * Sets attribute to corresponding value based on checkbox
+     * @param evt 
+     */
+    private void alphabeticalActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_alphabeticalActionPerformed
+        alphabeticalFilter = (((JCheckBox)evt.getSource()).isSelected());
+    }//GEN-LAST:event_alphabeticalActionPerformed
+
+    @Override
+    public ImageIcon getIcon() {
+        return new ImageIcon(FilterPanel.class.getClassLoader().getResource("/" + ICON));
+    }
+
+    /**
+     * Sets ActionListener to apply filter button
+     * @param applyFilterListener ActionListener
+     */
+    public void setFilterActionListener(ActionListener applyFilterListener) {
+        applyFilterButton.addActionListener(applyFilterListener);
+    }
+    
+    public boolean isKdTreeFilter() {
+        return kdTreeFilter;
+    }
+
+    public boolean isFeaturePointsFilter() {
+        return featurePointsFilter;
+    }
+
+    public boolean isAlphabeticalFilter() {
+        return alphabeticalFilter;
+    }
+    
+    /**
+     * Checks if all faces in list are loaded. If not, button which loads all
+     * faces from list shows up
+     * @param isAllFacesLoaded Boolean
+     */
+    public void checkAllFacesLoaded(boolean isAllFacesLoaded) {
+        
+        warningLabel.setVisible(!isAllFacesLoaded);
+        faceNotLoadedLabel.setVisible(!isAllFacesLoaded);
+        loadAllModelsButton.setVisible(!isAllFacesLoaded);
+        applyFilterButton.setEnabled(isAllFacesLoaded);
+    }
+    
+    @Override
+    public void acceptEvent(ProjectEvent event) {
+        
+        if (event.getClass() == AllFacesLoaded.class) {
+            
+            AllFacesLoaded evt = (AllFacesLoaded)event;
+            this.checkAllFacesLoaded(evt.isAllFacesLoaded());
+        }
+    }
+
+    
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JCheckBox alphabetical;
+    private javax.swing.JButton applyFilterButton;
+    private javax.swing.JLabel faceNotLoadedLabel;
+    private javax.swing.JPanel filterPanel;
+    private javax.swing.JCheckBox hasFP;
+    private javax.swing.JCheckBox hasKD;
+    private javax.swing.JButton loadAllModelsButton;
+    private javax.swing.JLabel warningLabel;
+    // End of variables declaration//GEN-END:variables
+
+}
diff --git a/GUI/src/main/java/cz/fidentis/analyst/dashboard/ModelsTableModel.java b/GUI/src/main/java/cz/fidentis/analyst/project/ModelsTableModel.java
similarity index 53%
rename from GUI/src/main/java/cz/fidentis/analyst/dashboard/ModelsTableModel.java
rename to GUI/src/main/java/cz/fidentis/analyst/project/ModelsTableModel.java
index e7e979ed..ae5643e0 100644
--- a/GUI/src/main/java/cz/fidentis/analyst/dashboard/ModelsTableModel.java
+++ b/GUI/src/main/java/cz/fidentis/analyst/project/ModelsTableModel.java
@@ -1,21 +1,24 @@
-package cz.fidentis.analyst.dashboard;
+package cz.fidentis.analyst.project;
 
-import cz.fidentis.analyst.face.events.HumanFaceEvent;
-import cz.fidentis.analyst.face.events.HumanFaceListener;
-import cz.fidentis.analyst.face.events.KdTreeEvent;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.nio.file.Path;
+import javax.imageio.ImageIO;
 import javax.swing.ImageIcon;
 import javax.swing.table.DefaultTableModel;
+import org.openide.util.Exceptions;
 
 /**
  * List of faces TableModel
  * 
  * @author Matej Kovar
  */
-public class ModelsTableModel extends DefaultTableModel implements HumanFaceListener {
-    
-    private final ImageIcon notCheck = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "notCheck16x16.png"));
-    private final ImageIcon check = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "check16x16.png"));
+public class ModelsTableModel extends DefaultTableModel {
     
+    //private final ImageIcon notCheck = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "notCheck16x16.png"));
+    //private final ImageIcon check = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "check16x16.png"));
+    private final ImageIcon previewBasic = new ImageIcon(FaceStatePanel.class.getClassLoader().getResource("/" + "face32x32.png"));
     /**
      * Constructor
      * @param columnNames names of Columns
@@ -60,17 +63,22 @@ public class ModelsTableModel extends DefaultTableModel implements HumanFaceList
      * @param name String name of the face
      * @param hasKD Boolean if face has KD tree calculated
      */
-    public void addRowWithName(String name, boolean hasKD) {
-        if (hasKD) {
-            addRow(new Object[]{false, name, check});
+    public void addRowWithName(String name, Path path) {
+        if (!path.toFile().exists()) {
+            addRow(new Object[]{false, name, previewBasic});
         } else {
-            addRow(new Object[]{false, name, notCheck});
+            try {
+                BufferedImage image = ImageIO.read(path.toFile());
+                addRow(new Object[]{false, name, new ImageIcon(image.getScaledInstance(75, 50, Image.SCALE_FAST))});
+            } catch (IOException ex) {
+                Exceptions.printStackTrace(ex);
+            }
+            
         }
     }
     
     /*
      * 
-     
     public void sortAlphabeticaly() {
         List<String> rows = new ArrayList();
         for (int i = 0; i < getRowCount(); i++) {
@@ -79,25 +87,5 @@ public class ModelsTableModel extends DefaultTableModel implements HumanFaceList
         Collections.sort(rows);
     }
     */
-    
-    @Override
-    public void acceptEvent(HumanFaceEvent event) {
-        if (!(event instanceof KdTreeEvent)) {
-            return;
-        }
-        KdTreeEvent ev = (KdTreeEvent) event;
-        String name = ev.getName();
-        for (int i = 0; i < getRowCount(); i++) {
-            if (getValueAt(i, 1).equals(name)) {
-                if (ev.isCalculated()) {
-                    this.setValueAt(check, i, 2);
-                } else {
-                    this.setValueAt(notCheck, i, 2);
-                }
-                
-                break;
-            }
-        }
-    }
 
 }
diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.form b/GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.form
new file mode 100644
index 00000000..f6842bed
--- /dev/null
+++ b/GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.form
@@ -0,0 +1,322 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace min="-2" pref="41" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="1" attributes="0">
+                  <Component id="saveProjectButton" min="-2" max="-2" attributes="0"/>
+                  <Group type="102" alignment="1" attributes="0">
+                      <Group type="103" groupAlignment="0" max="-2" attributes="0">
+                          <Component id="buttonsPanel" alignment="0" max="32767" attributes="0"/>
+                          <Component id="faceTableScrollPanel" alignment="0" min="-2" pref="863" max="-2" attributes="0"/>
+                      </Group>
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Group type="102" alignment="0" attributes="0">
+                              <EmptySpace min="-2" pref="78" max="-2" attributes="0"/>
+                              <Component id="newProjectButton" min="-2" max="-2" attributes="0"/>
+                          </Group>
+                          <Group type="102" alignment="1" attributes="0">
+                              <EmptySpace max="-2" attributes="0"/>
+                              <Component id="openProjectButton" min="-2" max="-2" attributes="0"/>
+                          </Group>
+                      </Group>
+                  </Group>
+              </Group>
+              <EmptySpace pref="41" max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace min="-2" pref="12" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="102" alignment="0" attributes="0">
+                      <Component id="buttonsPanel" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace min="-2" pref="6" max="-2" attributes="0"/>
+                  </Group>
+                  <Group type="102" alignment="1" attributes="0">
+                      <Component id="newProjectButton" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace type="separate" max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Component id="faceTableScrollPanel" min="-2" pref="768" max="-2" attributes="0"/>
+                  <Group type="102" alignment="0" attributes="0">
+                      <Component id="saveProjectButton" min="-2" max="-2" attributes="0"/>
+                      <EmptySpace type="separate" max="-2" attributes="0"/>
+                      <Component id="openProjectButton" min="-2" max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+              <EmptySpace max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JPanel" name="buttonsPanel">
+      <Properties>
+        <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+          <Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
+            <EtchetBorder/>
+          </Border>
+        </Property>
+        <Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+          <Dimension value="[0, 0]"/>
+        </Property>
+      </Properties>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+      <SubComponents>
+        <Component class="javax.swing.JButton" name="addButton">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="12" style="0"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="ProjectPanel.addButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="addButtonMouseClicked"/>
+          </Events>
+          <Constraints>
+            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+              <GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="20" ipadY="0" insetsTop="16" insetsLeft="16" insetsBottom="13" insetsRight="4" anchor="13" weightX="0.0" weightY="0.0"/>
+            </Constraint>
+          </Constraints>
+        </Component>
+        <Component class="javax.swing.JButton" name="removeButton">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="12" style="0"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="ProjectPanel.removeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="removeButtonMouseClicked"/>
+          </Events>
+          <Constraints>
+            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+              <GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="22" insetsBottom="13" insetsRight="4" anchor="18" weightX="0.0" weightY="0.0"/>
+            </Constraint>
+          </Constraints>
+        </Component>
+        <Component class="javax.swing.JButton" name="selectAllButton">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="12" style="0"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="ProjectPanel.selectAllButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="selectAllButtonMouseClicked"/>
+          </Events>
+          <Constraints>
+            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+              <GridBagConstraints gridX="2" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="22" insetsBottom="13" insetsRight="4" anchor="18" weightX="0.0" weightY="0.0"/>
+            </Constraint>
+          </Constraints>
+        </Component>
+        <Component class="javax.swing.JButton" name="deselectAllButton">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="12" style="0"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="ProjectPanel.deselectAllButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="deselectAllButtonMouseClicked"/>
+          </Events>
+          <Constraints>
+            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+              <GridBagConstraints gridX="3" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="22" insetsBottom="13" insetsRight="4" anchor="18" weightX="0.0" weightY="0.0"/>
+            </Constraint>
+          </Constraints>
+        </Component>
+        <Component class="javax.swing.JButton" name="inflateButton">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="12" style="0"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="ProjectPanel.inflateButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="alignmentX" type="float" value="0.5"/>
+          </Properties>
+          <Events>
+            <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="inflateButtonMouseClicked"/>
+          </Events>
+          <Constraints>
+            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+              <GridBagConstraints gridX="4" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="22" insetsBottom="13" insetsRight="4" anchor="18" weightX="0.0" weightY="0.0"/>
+            </Constraint>
+          </Constraints>
+        </Component>
+        <Component class="javax.swing.JButton" name="oneOnOneButton">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="12" style="1"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="ProjectPanel.oneOnOneButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+            <Property name="alignmentX" type="float" value="0.5"/>
+          </Properties>
+          <Events>
+            <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="oneOnOneButtonMouseClicked"/>
+          </Events>
+          <Constraints>
+            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+              <GridBagConstraints gridX="6" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="11" insetsBottom="13" insetsRight="4" anchor="18" weightX="0.0" weightY="0.0"/>
+            </Constraint>
+          </Constraints>
+        </Component>
+        <Component class="javax.swing.JButton" name="manyToManyButton">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="12" style="1"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="ProjectPanel.manyToManyButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="manyToManyButtonMouseClicked"/>
+          </Events>
+          <Constraints>
+            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+              <GridBagConstraints gridX="5" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="30" insetsBottom="13" insetsRight="4" anchor="18" weightX="0.0" weightY="0.0"/>
+            </Constraint>
+          </Constraints>
+        </Component>
+        <Component class="javax.swing.JButton" name="analyseButton">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+              <Font name="Tahoma" size="12" style="1"/>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="ProjectPanel.analyseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="analyseButtonMouseClicked"/>
+          </Events>
+          <Constraints>
+            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+              <GridBagConstraints gridX="7" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="16" insetsLeft="11" insetsBottom="13" insetsRight="4" anchor="10" weightX="0.0" weightY="0.0"/>
+            </Constraint>
+          </Constraints>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Container class="javax.swing.JScrollPane" name="faceTableScrollPanel">
+      <Properties>
+        <Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
+          <Dimension value="[812, 750]"/>
+        </Property>
+      </Properties>
+      <AuxValues>
+        <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+      </AuxValues>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+      <SubComponents>
+        <Component class="javax.swing.JTable" name="table">
+          <Properties>
+            <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor" postCode="table.getTableHeader().setOpaque(false);&#xa;table.getTableHeader().setBackground(new java.awt.Color(204,204,204));&#xa;table.getTableHeader().setFont(new java.awt.Font(&quot;Tahoma&quot;, 0, 18));&#xa;model.addTableModelListener(new TableModelListener() {&#xa;    public void tableChanged(TableModelEvent e) {&#xa;        jTable1TableChanged(e);&#xa;    }&#xa;});">
+              <Font name="Tahoma" size="18" style="0"/>
+            </Property>
+            <Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor" postCode="table.getColumnModel().getColumn(0).setMaxWidth(50);&#xa;table.getColumnModel().getColumn(2).setMaxWidth(75);&#xa;table.getTableHeader().getColumnModel().getColumn(0).setMaxWidth(50);&#xa;table.getTableHeader().getColumnModel().getColumn(2).setMaxWidth(75);">
+              <Connection code="model" type="code"/>
+            </Property>
+            <Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor">
+              <TableColumnModel selectionModel="0"/>
+            </Property>
+            <Property name="dragEnabled" type="boolean" value="true"/>
+            <Property name="rowHeight" type="int" value="60"/>
+            <Property name="selectionBackground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
+              <Color blue="ff" green="cc" red="66" type="rgb"/>
+            </Property>
+            <Property name="selectionMode" type="int" value="0"/>
+            <Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
+              <TableHeader reorderingAllowed="false" resizingAllowed="true"/>
+            </Property>
+          </Properties>
+          <Events>
+            <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="tableMouseClicked"/>
+          </Events>
+          <AuxValues>
+            <AuxValue name="JavaCodeGenerator_InitCodePre" type="java.lang.String" value="table.setSize(faceTableScrollPanel.getWidth(), faceTableScrollPanel.getHeight());"/>
+          </AuxValues>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Component class="javax.swing.JButton" name="saveProjectButton">
+      <Properties>
+        <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+          <Font name="Tahoma" size="12" style="0"/>
+        </Property>
+        <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+          <Image iconType="3" name="/save100x24.png"/>
+        </Property>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="ProjectPanel.saveProjectButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="saveProjectButtonMouseClicked"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JButton" name="openProjectButton">
+      <Properties>
+        <Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
+          <Font name="Tahoma" size="12" style="0"/>
+        </Property>
+        <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+          <Image iconType="3" name="/open100x24.png"/>
+        </Property>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="ProjectPanel.openProjectButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="openProjectButtonMouseClicked"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JButton" name="newProjectButton">
+      <Properties>
+        <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
+          <Image iconType="3" name="/new100x24.png"/>
+        </Property>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="cz/fidentis/analyst/project/Bundle.properties" key="ProjectPanel.newProjectButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="newProjectButtonMouseClicked"/>
+      </Events>
+    </Component>
+  </SubComponents>
+</Form>
diff --git a/GUI/src/main/java/cz/fidentis/analyst/core/ProjectTopComp.java b/GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.java
similarity index 68%
rename from GUI/src/main/java/cz/fidentis/analyst/core/ProjectTopComp.java
rename to GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.java
index 40caf20e..2d7a4632 100644
--- a/GUI/src/main/java/cz/fidentis/analyst/core/ProjectTopComp.java
+++ b/GUI/src/main/java/cz/fidentis/analyst/project/ProjectPanel.java
@@ -1,16 +1,16 @@
-package cz.fidentis.analyst.core;
+package cz.fidentis.analyst.project;
 
-import cz.fidentis.analyst.ProjectConfiguration;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import org.netbeans.api.settings.ConvertAsProperties;
-import org.openide.awt.ActionID;
-import org.openide.awt.ActionReference;
-import org.openide.windows.TopComponent;
-import org.openide.util.NbBundle.Messages;
+import com.google.common.eventbus.EventBus;
 import cz.fidentis.analyst.Project;
+import cz.fidentis.analyst.ProjectConfiguration;
+import cz.fidentis.analyst.core.FaceTab;
+import cz.fidentis.analyst.project.events.AllFacesLoaded;
+import cz.fidentis.analyst.project.events.FaceDeselected;
+import cz.fidentis.analyst.project.events.FaceSelected;
+import cz.fidentis.analyst.project.events.ProjectListener;
 import cz.fidentis.analyst.face.HumanFace;
-import cz.fidentis.analyst.dashboard.ModelsTableModel;
-import cz.fidentis.analyst.dashboard.FilterPanel;
+import cz.fidentis.analyst.face.events.HumanFaceEvent;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.io.File;
@@ -24,6 +24,7 @@ import javax.swing.AbstractAction;
 import javax.swing.ImageIcon;
 import javax.swing.JFileChooser;
 import javax.swing.JOptionPane;
+import javax.swing.JPanel;
 import javax.swing.event.TableModelEvent;
 import javax.swing.event.TableModelListener;
 import javax.swing.filechooser.FileNameExtensionFilter;
@@ -31,77 +32,35 @@ import org.openide.filesystems.FileChooserBuilder;
 import org.openide.util.Exceptions;
 
 /**
- * The main panel enabling analysts to select the primary and secondary faces,
- * and to perform basic batch processing. This panel also serves as an entry
- * point for detailed face analysis and face-to-face comparison.
  *
  * @author Matej Kovar
  */
-@ConvertAsProperties(
-        dtd = "-//cz.fidentis.analyst.gui//Dashboard//EN",
-        autostore = false
-)
-@TopComponent.Description(
-        preferredID = "ProjectTopComp",
-        //iconBase="SET/PATH/TO/ICON/HERE",
-        persistenceType = TopComponent.PERSISTENCE_ALWAYS
-)
-@TopComponent.Registration(mode = "editor", openAtStartup = true)
-@ActionID(category = "Window", id = "cz.fidentis.analyst.gui.ProjectTopComp")
-@ActionReference(path = "Menu/Window" /*, position = 333 */)
-@TopComponent.OpenActionRegistration(
-        displayName = "#CTL_ProjectTopCompAction",
-        preferredID = "ProjectTopComp"
-)
-@Messages({
-    "CTL_ProjectTopCompAction=Project",
-    "CTL_ProjectTopCompTopComponent=Project",
-    "HINT_ProjectTopCompTopComponent=This is a Project window"
-})
-public final class ProjectTopComp extends TopComponent {
-
+public class ProjectPanel extends JPanel {
+    
     private Project project;
     
     private List<FaceTab> tabs = new ArrayList<>();
     
-    private ModelsTableModel model = new ModelsTableModel(new Object[]{"", "Models", "KD-tree"}, 0);
-    
-    private FilterPanel fp;
-    
+    private ModelsTableModel model = new ModelsTableModel(new Object[]{"", "Models", "Preview"}, 0);
+
     /* List of indexes of selected Rows */
     private List<Integer> selectedRows = new ArrayList<>();
     
     private ObjectMapper mapper = new ObjectMapper();
     
+    private final transient EventBus eventBus;
+
     /**
-     * Creates new ProjectTopComp, initializes new project
+     * Creates new form ProjectPanel
      */
-    public ProjectTopComp() {
-        project = new Project();
-       
-        initComponents();
-        setName(Bundle.CTL_ProjectTopCompTopComponent());
-        setToolTipText(Bundle.HINT_ProjectTopCompTopComponent());
-        putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE);
-        putClientProperty(TopComponent.PROP_DRAGGING_DISABLED, Boolean.TRUE);
-        putClientProperty(TopComponent.PROP_UNDOCKING_DISABLED, Boolean.TRUE);
+    public ProjectPanel() {
         
-        ActionListener listener = new AbstractAction() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                applyFilter();
-            }
-        };
+        project = new Project();
         
-        //fp = new FilterPanel(filterPanel, listener);
+        initComponents();
+        eventBus = new EventBus();
         
-                
-        // Execute infinite OutputWindowThread that redirects messages logged
-        // via Logger into the standard output window
-        OutputWindowThread.execute();
-
         openExistingOrNewProject();
-        
     }
 
     /**
@@ -109,12 +68,11 @@ public final class ProjectTopComp extends TopComponent {
      * WARNING: Do NOT modify this code. The content of this method is always
      * regenerated by the Form Editor.
      */
+    @SuppressWarnings("unchecked")
     // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
     private void initComponents() {
         java.awt.GridBagConstraints gridBagConstraints;
 
-        mainScrollPanel = new javax.swing.JScrollPane();
-        mainPanel = new javax.swing.JPanel();
         buttonsPanel = new javax.swing.JPanel();
         addButton = new javax.swing.JButton();
         removeButton = new javax.swing.JButton();
@@ -126,20 +84,16 @@ public final class ProjectTopComp extends TopComponent {
         analyseButton = new javax.swing.JButton();
         faceTableScrollPanel = new javax.swing.JScrollPane();
         table = new javax.swing.JTable();
-        filterPanel = new javax.swing.JPanel();
-        infoPanel = new javax.swing.JPanel();
         saveProjectButton = new javax.swing.JButton();
         openProjectButton = new javax.swing.JButton();
         newProjectButton = new javax.swing.JButton();
 
-        setOpaque(true);
-
         buttonsPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
         buttonsPanel.setMinimumSize(new java.awt.Dimension(0, 0));
         buttonsPanel.setLayout(new java.awt.GridBagLayout());
 
         addButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
-        org.openide.awt.Mnemonics.setLocalizedText(addButton, org.openide.util.NbBundle.getMessage(ProjectTopComp.class, "ProjectTopComp.addButton.text")); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(addButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.addButton.text")); // NOI18N
         addButton.addMouseListener(new java.awt.event.MouseAdapter() {
             public void mouseClicked(java.awt.event.MouseEvent evt) {
                 addButtonMouseClicked(evt);
@@ -154,7 +108,7 @@ public final class ProjectTopComp extends TopComponent {
         buttonsPanel.add(addButton, gridBagConstraints);
 
         removeButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
-        org.openide.awt.Mnemonics.setLocalizedText(removeButton, org.openide.util.NbBundle.getMessage(ProjectTopComp.class, "ProjectTopComp.removeButton.text")); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(removeButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.removeButton.text")); // NOI18N
         removeButton.addMouseListener(new java.awt.event.MouseAdapter() {
             public void mouseClicked(java.awt.event.MouseEvent evt) {
                 removeButtonMouseClicked(evt);
@@ -168,7 +122,7 @@ public final class ProjectTopComp extends TopComponent {
         buttonsPanel.add(removeButton, gridBagConstraints);
 
         selectAllButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
-        org.openide.awt.Mnemonics.setLocalizedText(selectAllButton, org.openide.util.NbBundle.getMessage(ProjectTopComp.class, "ProjectTopComp.selectAllButton.text")); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(selectAllButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.selectAllButton.text")); // NOI18N
         selectAllButton.addMouseListener(new java.awt.event.MouseAdapter() {
             public void mouseClicked(java.awt.event.MouseEvent evt) {
                 selectAllButtonMouseClicked(evt);
@@ -182,7 +136,7 @@ public final class ProjectTopComp extends TopComponent {
         buttonsPanel.add(selectAllButton, gridBagConstraints);
 
         deselectAllButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
-        org.openide.awt.Mnemonics.setLocalizedText(deselectAllButton, org.openide.util.NbBundle.getMessage(ProjectTopComp.class, "ProjectTopComp.deselectAllButton.text")); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(deselectAllButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.deselectAllButton.text")); // NOI18N
         deselectAllButton.addMouseListener(new java.awt.event.MouseAdapter() {
             public void mouseClicked(java.awt.event.MouseEvent evt) {
                 deselectAllButtonMouseClicked(evt);
@@ -196,7 +150,7 @@ public final class ProjectTopComp extends TopComponent {
         buttonsPanel.add(deselectAllButton, gridBagConstraints);
 
         inflateButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
-        org.openide.awt.Mnemonics.setLocalizedText(inflateButton, org.openide.util.NbBundle.getMessage(ProjectTopComp.class, "ProjectTopComp.inflateButton.text")); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(inflateButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.inflateButton.text")); // NOI18N
         inflateButton.setAlignmentX(0.5F);
         inflateButton.addMouseListener(new java.awt.event.MouseAdapter() {
             public void mouseClicked(java.awt.event.MouseEvent evt) {
@@ -211,7 +165,7 @@ public final class ProjectTopComp extends TopComponent {
         buttonsPanel.add(inflateButton, gridBagConstraints);
 
         oneOnOneButton.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
-        org.openide.awt.Mnemonics.setLocalizedText(oneOnOneButton, org.openide.util.NbBundle.getMessage(ProjectTopComp.class, "ProjectTopComp.oneOnOneButton.text")); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(oneOnOneButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.oneOnOneButton.text")); // NOI18N
         oneOnOneButton.setAlignmentX(0.5F);
         oneOnOneButton.addMouseListener(new java.awt.event.MouseAdapter() {
             public void mouseClicked(java.awt.event.MouseEvent evt) {
@@ -226,7 +180,7 @@ public final class ProjectTopComp extends TopComponent {
         buttonsPanel.add(oneOnOneButton, gridBagConstraints);
 
         manyToManyButton.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
-        org.openide.awt.Mnemonics.setLocalizedText(manyToManyButton, org.openide.util.NbBundle.getMessage(ProjectTopComp.class, "ProjectTopComp.manyToManyButton.text")); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(manyToManyButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.manyToManyButton.text")); // NOI18N
         manyToManyButton.addMouseListener(new java.awt.event.MouseAdapter() {
             public void mouseClicked(java.awt.event.MouseEvent evt) {
                 manyToManyButtonMouseClicked(evt);
@@ -240,7 +194,7 @@ public final class ProjectTopComp extends TopComponent {
         buttonsPanel.add(manyToManyButton, gridBagConstraints);
 
         analyseButton.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
-        org.openide.awt.Mnemonics.setLocalizedText(analyseButton, org.openide.util.NbBundle.getMessage(ProjectTopComp.class, "ProjectTopComp.analyseButton.text")); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(analyseButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.analyseButton.text")); // NOI18N
         analyseButton.addMouseListener(new java.awt.event.MouseAdapter() {
             public void mouseClicked(java.awt.event.MouseEvent evt) {
                 analyseButtonMouseClicked(evt);
@@ -260,7 +214,6 @@ public final class ProjectTopComp extends TopComponent {
         table.getTableHeader().setBackground(new java.awt.Color(204,204,204));
         table.getTableHeader().setFont(new java.awt.Font("Tahoma", 0, 18));
         model.addTableModelListener(new TableModelListener() {
-
             public void tableChanged(TableModelEvent e) {
                 jTable1TableChanged(e);
             }
@@ -271,7 +224,7 @@ public final class ProjectTopComp extends TopComponent {
         table.getTableHeader().getColumnModel().getColumn(0).setMaxWidth(50);
         table.getTableHeader().getColumnModel().getColumn(2).setMaxWidth(75);
         table.setDragEnabled(true);
-        table.setRowHeight(40);
+        table.setRowHeight(60);
         table.setSelectionBackground(new java.awt.Color(102, 204, 255));
         table.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
         table.getTableHeader().setReorderingAllowed(false);
@@ -282,40 +235,9 @@ public final class ProjectTopComp extends TopComponent {
         });
         faceTableScrollPanel.setViewportView(table);
 
-        filterPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
-        filterPanel.setMaximumSize(new java.awt.Dimension(342, 424));
-        filterPanel.setPreferredSize(new java.awt.Dimension(342, 424));
-
-        javax.swing.GroupLayout filterPanelLayout = new javax.swing.GroupLayout(filterPanel);
-        filterPanel.setLayout(filterPanelLayout);
-        filterPanelLayout.setHorizontalGroup(
-            filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGap(0, 359, Short.MAX_VALUE)
-        );
-        filterPanelLayout.setVerticalGroup(
-            filterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGap(0, 420, Short.MAX_VALUE)
-        );
-
-        infoPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
-        infoPanel.setPreferredSize(new java.awt.Dimension(349, 363));
-
-        javax.swing.GroupLayout infoPanelLayout = new javax.swing.GroupLayout(infoPanel);
-        infoPanel.setLayout(infoPanelLayout);
-        infoPanelLayout.setHorizontalGroup(
-            infoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGap(0, 0, Short.MAX_VALUE)
-        );
-        infoPanelLayout.setVerticalGroup(
-            infoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGap(0, 312, Short.MAX_VALUE)
-        );
-
-        infoPanel.setVisible(false);
-
         saveProjectButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
         saveProjectButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/save100x24.png"))); // NOI18N
-        org.openide.awt.Mnemonics.setLocalizedText(saveProjectButton, org.openide.util.NbBundle.getMessage(ProjectTopComp.class, "ProjectTopComp.saveProjectButton.text")); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(saveProjectButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.saveProjectButton.text")); // NOI18N
         saveProjectButton.addMouseListener(new java.awt.event.MouseAdapter() {
             public void mouseClicked(java.awt.event.MouseEvent evt) {
                 saveProjectButtonMouseClicked(evt);
@@ -324,7 +246,7 @@ public final class ProjectTopComp extends TopComponent {
 
         openProjectButton.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
         openProjectButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/open100x24.png"))); // NOI18N
-        org.openide.awt.Mnemonics.setLocalizedText(openProjectButton, org.openide.util.NbBundle.getMessage(ProjectTopComp.class, "ProjectTopComp.openProjectButton.text")); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(openProjectButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.openProjectButton.text")); // NOI18N
         openProjectButton.addMouseListener(new java.awt.event.MouseAdapter() {
             public void mouseClicked(java.awt.event.MouseEvent evt) {
                 openProjectButtonMouseClicked(evt);
@@ -332,113 +254,137 @@ public final class ProjectTopComp extends TopComponent {
         });
 
         newProjectButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/new100x24.png"))); // NOI18N
-        org.openide.awt.Mnemonics.setLocalizedText(newProjectButton, org.openide.util.NbBundle.getMessage(ProjectTopComp.class, "ProjectTopComp.newProjectButton.text")); // NOI18N
+        org.openide.awt.Mnemonics.setLocalizedText(newProjectButton, org.openide.util.NbBundle.getMessage(ProjectPanel.class, "ProjectPanel.newProjectButton.text")); // NOI18N
         newProjectButton.addMouseListener(new java.awt.event.MouseAdapter() {
             public void mouseClicked(java.awt.event.MouseEvent evt) {
                 newProjectButtonMouseClicked(evt);
             }
         });
 
-        javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
-        mainPanel.setLayout(mainPanelLayout);
-        mainPanelLayout.setHorizontalGroup(
-            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(mainPanelLayout.createSequentialGroup()
-                .addContainerGap()
-                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
-                    .addComponent(buttonsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                    .addComponent(faceTableScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 863, Short.MAX_VALUE))
-                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
-                    .addGroup(mainPanelLayout.createSequentialGroup()
-                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 52, Short.MAX_VALUE)
-                        .addComponent(newProjectButton)
-                        .addGap(18, 18, 18)
-                        .addComponent(saveProjectButton)
-                        .addGap(18, 18, 18)
-                        .addComponent(openProjectButton))
-                    .addGroup(mainPanelLayout.createSequentialGroup()
-                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                        .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
-                            .addComponent(filterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 363, Short.MAX_VALUE)
-                            .addComponent(infoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 363, Short.MAX_VALUE))))
-                .addGap(20, 20, 20))
-        );
-        mainPanelLayout.setVerticalGroup(
-            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addGroup(mainPanelLayout.createSequentialGroup()
-                .addContainerGap()
-                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                    .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-                        .addGroup(mainPanelLayout.createSequentialGroup()
-                            .addComponent(buttonsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
-                            .addGap(6, 6, 6))
-                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
-                            .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
-                                .addComponent(saveProjectButton)
-                                .addComponent(openProjectButton))
-                            .addGap(18, 18, 18)))
-                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
-                        .addComponent(newProjectButton)
-                        .addGap(18, 18, 18)))
-                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
-                    .addGroup(mainPanelLayout.createSequentialGroup()
-                        .addComponent(filterPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
-                        .addGap(28, 28, 28)
-                        .addComponent(infoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 316, javax.swing.GroupLayout.PREFERRED_SIZE))
-                    .addComponent(faceTableScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
-                .addContainerGap())
-        );
-
-        saveProjectButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(ProjectTopComp.class, "ProjectTopComp.saveProjectButton.AccessibleContext.accessibleName")); // NOI18N
-
-        mainScrollPanel.setViewportView(mainPanel);
-
-        mainScrollPanel.setSize(ControlPanel.CONTROL_PANEL_WIDTH, ControlPanel.HEIGHT);
-
         javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
         this.setLayout(layout);
         layout.setHorizontalGroup(
             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addComponent(mainScrollPanel, javax.swing.GroupLayout.Alignment.TRAILING)
+            .addGroup(layout.createSequentialGroup()
+                .addGap(41, 41, 41)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                    .addComponent(saveProjectButton)
+                    .addGroup(layout.createSequentialGroup()
+                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+                            .addComponent(buttonsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                            .addComponent(faceTableScrollPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 863, javax.swing.GroupLayout.PREFERRED_SIZE))
+                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addGroup(layout.createSequentialGroup()
+                                .addGap(78, 78, 78)
+                                .addComponent(newProjectButton))
+                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                .addComponent(openProjectButton)))))
+                .addContainerGap(41, Short.MAX_VALUE))
         );
         layout.setVerticalGroup(
             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
-            .addComponent(mainScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 871, Short.MAX_VALUE)
+            .addGroup(layout.createSequentialGroup()
+                .addGap(12, 12, 12)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(buttonsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                        .addGap(6, 6, 6))
+                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+                        .addComponent(newProjectButton)
+                        .addGap(18, 18, 18)))
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addComponent(faceTableScrollPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 768, javax.swing.GroupLayout.PREFERRED_SIZE)
+                    .addGroup(layout.createSequentialGroup()
+                        .addComponent(saveProjectButton)
+                        .addGap(18, 18, 18)
+                        .addComponent(openProjectButton)))
+                .addContainerGap(12, Short.MAX_VALUE))
         );
     }// </editor-fold>//GEN-END:initComponents
 
-    /**
-     * Opens many to many tab
-     * @param evt
-     */
+    public boolean isProjectSaved() {
+        return project.isSaved();
+    }
+    
+    
+    private void newProjectButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_newProjectButtonMouseClicked
+        if (loadNewProject()) {
+            newProject();
+        }
+    }//GEN-LAST:event_newProjectButtonMouseClicked
+
+    private void openProjectButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_openProjectButtonMouseClicked
+        if (loadNewProject()) {
+            openProject();
+        }
+    }//GEN-LAST:event_openProjectButtonMouseClicked
+
+    private void saveProjectButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_saveProjectButtonMouseClicked
+        saveProject();
+    }//GEN-LAST:event_saveProjectButtonMouseClicked
+
+    private void tableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tableMouseClicked
+        if (table.getSelectedRowCount() == 0) {
+            checkFaceState(null, false);
+        } else {
+            if (evt.getClickCount() == 2) {
+                deselectAllRows();
+                model.setValueAt(true, table.getSelectedRow(), 0);
+                analyseButtonMouseClicked(evt);
+            }
+            checkFaceState(table.getValueAt(table.getSelectedRow(), 1).toString(), true);
+
+        }
+    }//GEN-LAST:event_tableMouseClicked
+
+    private void analyseButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_analyseButtonMouseClicked
+
+        if (selectedRows.size() == 1) {
+
+            String name = model.getValueAt(selectedRows.get(0), 1).toString();
+            HumanFace face = project.loadFace(name);
+
+            if (project.getFaceByName(name) == null) {    
+                project.addFace(face);
+            }
+            
+            
+            
+            createSingleFaceTab(face, name, false);
+        } else {
+            JOptionPane.showMessageDialog(this, "Select one model");
+        }
+    }//GEN-LAST:event_analyseButtonMouseClicked
+
     private void manyToManyButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_manyToManyButtonMouseClicked
-       createManyToManyTab("N:N");
+        createManyToManyTab("N:N");
     }//GEN-LAST:event_manyToManyButtonMouseClicked
 
-    /**
-     * Opens 1:1 tab with two selected faces, otherwise pops message that you
-     * should select two faces
-     * @param evt 
-     */
-    private void oneOnOneButton1MouseClicked(java.awt.event.MouseEvent evt) {                                             
-        //loadTwoModels();
+    private void oneOnOneButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_oneOnOneButtonMouseClicked
 
         if (selectedRows.size() == 2) {
 
             String name1 = model.getValueAt(selectedRows.get(0), 1).toString();
             String name2 = model.getValueAt(selectedRows.get(1), 1).toString();
-            HumanFace face1 = project.getFaceByName(name1);
-            HumanFace face2 = project.getFaceByName(name2);
+
+            HumanFace face1 = project.loadFace(name1);
+            HumanFace face2 = project.loadFace(name2);
+
+            if (project.getFaceByName(name1) == null) {
+                project.addFace(face1);
+            }
+
+            if (project.getFaceByName(name2) == null) {
+                project.addFace(face2);
+            }
+
             createFaceToFaceTab(face1, face2, name1 + ":" + name2, false);
         } else {
             JOptionPane.showMessageDialog(this, "Select two models");
         }
-    }                                            
+    }//GEN-LAST:event_oneOnOneButtonMouseClicked
 
-    /**
-     * Inflates models (selected will be deselected and vice versa)
-     * @param evt 
-     */
     private void inflateButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_inflateButtonMouseClicked
 
         for (int i = 0; i < model.getRowCount(); i++) {
@@ -450,45 +396,59 @@ public final class ProjectTopComp extends TopComponent {
         }
     }//GEN-LAST:event_inflateButtonMouseClicked
 
-    /**
-     * Deselects all models from list of models
-     * @param evt 
-     */
     private void deselectAllButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_deselectAllButtonMouseClicked
         deselectAllRows();
     }//GEN-LAST:event_deselectAllButtonMouseClicked
 
-    /**
-     * Deselects all rows
-     * TODO : deselect only rows which are selected (checking row by row is slow)
-     */
-    private void deselectAllRows() {
-        for (int i = 0; i < model.getRowCount(); i++) {
-            model.setValueAt(false, i, 0);
-        }
-    }
-    
-    /**
-     * Selects all models from list of models
-     * @param evt 
-     */
     private void selectAllButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_selectAllButtonMouseClicked
         for (int i = 0; i < model.getRowCount(); i++) {
             model.setValueAt(true, i, 0);
         }
     }//GEN-LAST:event_selectAllButtonMouseClicked
 
-//GEN-FIRST:event_removeButton1MouseClicked
-     /**
-     * Removes selected models from list and project
-     * @param evt Removes selected faces
-     */
-    private void removeButtonMouseClicked(java.awt.event.MouseEvent evt) {                                           
+    private void removeButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_removeButtonMouseClicked
         removeSelectedFaces();
-    }    
-//GEN-LAST:event_removeButton1MouseClicked
+    }//GEN-LAST:event_removeButtonMouseClicked
+
+    private void addButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_addButtonMouseClicked
+        loadModel(false);
+    }//GEN-LAST:event_addButtonMouseClicked
 
     /**
+     * Registers listeners (objects concerned in the project changes) to receive events.
+     * If listener is {@code null}, no exception is thrown and no action is taken.
+     * 
+     * @param listener Listener concerned in the project changes.
+     */
+    public void registerListener(ProjectListener listener) {
+        if (eventBus != null) {
+            eventBus.register(listener);
+        }
+    }
+     
+    /**
+     * Unregisters listeners from receiving events.
+     * 
+     * @param listener Registered listener
+     */
+    public void unregisterListener(ProjectListener listener) {
+        if (eventBus != null) {
+            eventBus.unregister(listener);
+        }
+    }
+    
+    /**
+     * Broadcast event to registered listeners.
+     * 
+     * @param evt Event to be triggered.
+     */
+    public void announceEvent(HumanFaceEvent evt) {
+        if (evt != null && eventBus != null) {
+            eventBus.post(evt);
+        }
+    }
+    
+        /**
      * Removes selected faces (those which are checked in check boxes)
      */
     private void removeSelectedFaces() {
@@ -507,120 +467,19 @@ public final class ProjectTopComp extends TopComponent {
             project.removeFaceByName(name);
             model.removeRow(row);
         });
-        selectedRows.clear();        
-        this.requestActive();
+        selectedRows.clear();  
     }
-    
-    /**
-     * Adds new model
-     * @param evt 
-     */
-    private void addButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_addButtonMouseClicked
-        loadModel(true);
-    }//GEN-LAST:event_addButtonMouseClicked
-
-    /**
-     * Shows face state panel after clicking on face in list. Also double-click
-     * on face opens Analyze tab for clicked face
-     * @param evt 
-     */
-    private void tableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tableMouseClicked
-        if (table.getSelectedRow() == -1) {
-            infoPanel.setVisible(false);
-        } else {
-            
-            if (evt.getClickCount() == 2) {
-                deselectAllRows();
-                model.setValueAt(true, table.getSelectedRow(), 0);
-                analyseButtonMouseClicked(evt);
-            }
-            infoPanel.setVisible(true);
-            checkFaceState(table.getValueAt(table.getSelectedRow(), 1).toString());       
-        }
-    }//GEN-LAST:event_tableMouseClicked
-
-    /**
-     * Saves current project
-     * @param evt 
-     */
-    private void saveProjectButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_saveProjectButtonMouseClicked
-        saveProject();
-    }//GEN-LAST:event_saveProjectButtonMouseClicked
-
-    /**
-     * Open new project
-     * @param evt 
-     */
-    private void openProjectButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_openProjectButtonMouseClicked
-        if (loadNewProject()) {
-            openProject();
-        }
-    }//GEN-LAST:event_openProjectButtonMouseClicked
-
-    /**
-     * Creates new project
-     * @param evt 
-     */
-    private void newProjectButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_newProjectButtonMouseClicked
-        if (loadNewProject()) {
-            newProject();
-        }
-    }//GEN-LAST:event_newProjectButtonMouseClicked
-    
+        
     /**
-     * Opens 1:1 tab with two selected faces, otherwise pops message that you
-     * should select two faces
-     * @param evt 
+     * Deselects all rows
+     * TODO : deselect only rows which are selected (checking row by row is slow)
      */
-    private void oneOnOneButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_oneOnOneButtonMouseClicked
-
-        if (selectedRows.size() == 2) {
-
-            String name1 = model.getValueAt(selectedRows.get(0), 1).toString();
-            String name2 = model.getValueAt(selectedRows.get(1), 1).toString();
-
-            HumanFace face1 = project.loadFace(name1);
-            HumanFace face2 = project.loadFace(name2);
-            
-            if (project.getFaceByName(name1) == null) {
-                face1.registerListener(model);
-                project.addFace(face1);
-            }
-            
-            if (project.getFaceByName(name2) == null) {
-                face2.registerListener(model);
-                project.addFace(face2);
-            } 
-            
-            createFaceToFaceTab(face1, face2, name1 + ":" + name2, false);
-        } else {
-            JOptionPane.showMessageDialog(this, "Select two models");
+    private void deselectAllRows() {
+        for (int i = 0; i < model.getRowCount(); i++) {
+            model.setValueAt(false, i, 0);
         }
-    }//GEN-LAST:event_oneOnOneButtonMouseClicked
-
+    }
     
-    /**
-     * Opens analysis of one selected face, otherwise pops message dialog that
-     * you should select just one face
-     * @param evt 
-     */
-    private void analyseButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_analyseButtonMouseClicked
-        
-        if (selectedRows.size() == 1) {
-
-            String name = model.getValueAt(selectedRows.get(0), 1).toString();
-            HumanFace face = project.loadFace(name);
-            if (project.getFaceByName(name) == null) {
-                face.registerListener(model);
-                project.addFace(face);
-            }
-            
-            createSingleFaceTab(face, name, false);
-        } else {
-            JOptionPane.showMessageDialog(this, "Select one model");
-        }
-    }//GEN-LAST:event_analyseButtonMouseClicked
-
     /**
      * Updates selectedRows - adds new selected rows or removes deselected rows
      * @param e TableModelEvent
@@ -643,49 +502,8 @@ public final class ProjectTopComp extends TopComponent {
             project.setSaved(false);
         }
     } 
-   
-    // Variables declaration - do not modify//GEN-BEGIN:variables
-    private javax.swing.JButton addButton;
-    private javax.swing.JButton analyseButton;
-    private javax.swing.JPanel buttonsPanel;
-    private javax.swing.JButton deselectAllButton;
-    private javax.swing.JScrollPane faceTableScrollPanel;
-    private javax.swing.JPanel filterPanel;
-    private javax.swing.JButton inflateButton;
-    private javax.swing.JPanel infoPanel;
-    private javax.swing.JPanel mainPanel;
-    private javax.swing.JScrollPane mainScrollPanel;
-    private javax.swing.JButton manyToManyButton;
-    private javax.swing.JButton newProjectButton;
-    private javax.swing.JButton oneOnOneButton;
-    private javax.swing.JButton openProjectButton;
-    private javax.swing.JButton removeButton;
-    private javax.swing.JButton saveProjectButton;
-    private javax.swing.JButton selectAllButton;
-    private javax.swing.JTable table;
-    // End of variables declaration//GEN-END:variables
-    @Override
-    public void componentOpened() {
-        // TODO add custom code on component opening
-    }
-
-    @Override
-    public void componentClosed() {
-        // TODO add custom code on component closing
-    }
-
-    void writeProperties(java.util.Properties p) {
-        // better to version settings since initial version as advocated at
-        // http://wiki.apidesign.org/wiki/PropertyFiles
-        p.setProperty("version", "1.0");
-        // TODO store your settings
-    }
-
-    void readProperties(java.util.Properties p) {
-        String version = p.getProperty("version");
-        // TODO read your settings according to their version
-    }
 
+    
     /**
      * Loads model selected in file chooser by user
      * @param loadFromFile true if models are loaded from file, else user chooses
@@ -695,7 +513,7 @@ public final class ProjectTopComp extends TopComponent {
         File[] files;
         
         // Selects files with faces (by dialog or from JSON file)
-        if (loadFromFile) {
+        if (!loadFromFile) {
             files = new FileChooserBuilder(ProjectTopComp.class)
                 .setTitle("Open human face(s)")
                 .setDefaultWorkingDirectory(new File(System.getProperty("user.home")))
@@ -716,8 +534,17 @@ public final class ProjectTopComp extends TopComponent {
                 
                 Path path = Paths.get(file.getAbsolutePath());
                 String name = path.toString().substring(path.toString().lastIndexOf(File.separatorChar) + 1, path.toString().lastIndexOf('.'));
+                
                 if (project.addNewPath(path)) {  
-                    model.addRowWithName(name, false);
+                    
+                    String pathString = path.toString();
+                    Path preview = Paths.get(pathString.substring(0, pathString.lastIndexOf(".")).concat("_preview_small.png"));
+                    
+                    model.addRowWithName(name, preview);
+                    
+                    if (eventBus != null) {
+                        eventBus.post(new AllFacesLoaded(false));
+                    }
                 } else {
                     JOptionPane.showMessageDialog(this, String.format("Model with name %s is already loaded", name));
                 }
@@ -743,13 +570,32 @@ public final class ProjectTopComp extends TopComponent {
             });
         });
         
-        this.toFront();
-        this.openAtTabPosition(0);
-        this.requestActive();
-        
     }
-
-   /**
+    
+    /**
+     * Checks whether face is already loaded in some tab and if it is different tab
+     * (different tabName) than opens this face again from file (copy of face)
+     * @param tabName String name of tab which is about to be opened
+     * @param face HumanFace which will be in tab
+     * @return either loaded face from project or newly opened face from file
+     */
+    private HumanFace getLoadedOrNewFace(String tabName, HumanFace face) {
+        for (FaceTab t : tabs) {
+            
+            if (t.hasFace(face.getShortName()) && !t.getName().equals(tabName)) {
+                
+                try {
+                    return new HumanFace(Paths.get(face.getPath()).toFile(), true);
+                   
+                } catch (IOException ex) {
+                    Exceptions.printStackTrace(ex);
+                }
+            }
+        }
+        return face;
+    }
+    
+    /**
     * Creates and opens tab with one face
     * @param face which will be analyzed
     * @param name name of the tab (name of the model)
@@ -760,8 +606,12 @@ public final class ProjectTopComp extends TopComponent {
             public void actionPerformed(ActionEvent e) {
                 closeTab(e);
             }
+        
         };
+        
+        face = getLoadedOrNewFace(name, face);
         FaceTab newTab = new FaceTab(face, null, name, tabCloseListener);
+
         
         if (!tabs.contains(newTab)) {
             tabs.add(newTab);
@@ -771,9 +621,15 @@ public final class ProjectTopComp extends TopComponent {
             newTab.open();
             newTab.requestActive();
             this.project.setSaved(false);    
+            areAllFacesLoadedToProject();
+            
+        } else {
+            
+            tabs.stream().filter(t -> (t.equals(newTab))).forEachOrdered(t -> {
+                t.requestActive();
+            });
         }
     }
-
     /**
      * Creates and opens tab with two faces (1:1 analysis)
      * @param face1 which will be analyzed
@@ -788,17 +644,25 @@ public final class ProjectTopComp extends TopComponent {
             }
         };
         
+        face1 = getLoadedOrNewFace(nameOfTab, face1);
+        face2 = getLoadedOrNewFace(nameOfTab, face2);
         FaceTab newTab = new FaceTab(face1, face2, nameOfTab, tabCloseListener);
         
         if (!tabs.contains(newTab)) {
-            tabs.add(newTab);
 
+            
+            tabs.add(newTab);
             if (!loadFromFile) {
                 project.addNewFaceToFaceTabFace(face1.getShortName(), face2.getShortName());
             }
             newTab.open();
             newTab.requestActive();
             this.project.setSaved(false);
+            areAllFacesLoadedToProject();
+        } else {
+            tabs.stream().filter(t -> (t.equals(newTab))).forEachOrdered(t -> {
+                t.requestActive();
+            });
         }
     }
     
@@ -825,10 +689,21 @@ public final class ProjectTopComp extends TopComponent {
     /**
      * Opens info panel with face state information
      * @param faceName String name of face
+     * @param selected Boolean true if some face is selected from list, false otherwise
      */
-    private void checkFaceState(String faceName) {
-        HumanFace face = project.getFaceByName(faceName);
-        //FaceStatePanel fsp = new FaceStatePanel(infoPanel, face);
+    private void checkFaceState(String faceName, boolean selected) {
+        
+        if (eventBus != null) {
+            
+            if (selected) {
+                HumanFace face = project.getFaceByName(faceName);
+                Path path = project.getCfg().getPathToFaceByName(faceName);
+                eventBus.post(new FaceSelected(face, faceName, path));        
+            } else {
+                eventBus.post(new FaceDeselected());
+            }
+            
+        }
         
     }
     
@@ -853,7 +728,9 @@ public final class ProjectTopComp extends TopComponent {
         Collections.sort(names);
         names.forEach(name -> {
             HumanFace face = project.getFaceByName(name);
-            model.addRowWithName(name, face.hasKdTree());
+            String pathString = face.getPath();
+            Path preview = Paths.get(pathString.substring(0, pathString.lastIndexOf(".")).concat("_preview.jpg"));
+            model.addRowWithName(name, preview);
         });
         
     }
@@ -861,19 +738,19 @@ public final class ProjectTopComp extends TopComponent {
     /**
      * Removes faces from project (and table of faces) based on filter configuration
      */
-    private void applyFilter() {
+    public void applyFilter(boolean isFeaturePointsFilter, boolean isKdTreeFilter, boolean isAlphaBeticalFilter) {
         deselectAllRows();
-                
+        
         for (int i = 0; i < model.getRowCount(); i++) { 
             HumanFace face = project.getFaceByName(model.getValueAt(i, 1).toString());
             
-            if ((fp.isKdTreeFilter() && !face.hasKdTree()) || (fp.isFeaturePointsFilter() && !face.hasFeaturePoints())) {
+            if ((isKdTreeFilter && !face.hasKdTree()) || (isFeaturePointsFilter && !face.hasFeaturePoints())) {
                 model.setValueAt(true, i, 0);
             }
         } 
         removeSelectedFaces();
         
-        if (fp.isAlphaBeticalFilter()) {
+        if (isAlphaBeticalFilter) {
             alphabeticalFilter();
         }
     }
@@ -911,6 +788,7 @@ public final class ProjectTopComp extends TopComponent {
         }
         project.removeAll();
         model.setRowCount(0);
+        checkFaceState(null, false);
         selectedRows.clear();        
     }
     
@@ -941,7 +819,7 @@ public final class ProjectTopComp extends TopComponent {
     /**
      * Saves current project
      */
-    private void saveProject() {
+    public void saveProject() {
         
         JFileChooser chooser = new JFileChooser();
         //chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
@@ -984,7 +862,7 @@ public final class ProjectTopComp extends TopComponent {
             try {
                 resetProject();
                 project.setCfg(mapper.readValue(f, ProjectConfiguration.class));
-                loadModel(false);    
+                loadModel(true);    
                 loadTabs();
                 project.setSaved(true);
             } catch (IOException ex) {
@@ -1023,21 +901,71 @@ public final class ProjectTopComp extends TopComponent {
             }
         }
         
-        this.requestActive();
+        //this.requestActive();
     }
     
-    @Override
-    public boolean canClose() {
-        if (!project.isSaved()) {
-
-            int save = JOptionPane.showConfirmDialog(null,
-                    "Project is not saved. Would you like to save project?", "Save project", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
-
-            if (save == JOptionPane.YES_OPTION) {
-                saveProject();
+    /**
+     * Loads currently selected (clicked in table) face to project
+     */
+    public void loadCurrentlySelectedFace() {
+        String name = table.getValueAt(table.getSelectedRow(), 1).toString();
+        project.loadFace(name);
+        checkFaceState(name, true);
+        areAllFacesLoadedToProject();
+    }
+    
+    /**
+     * Checks whether all faces from list are loaded to project and informs listeners
+     */
+    public void areAllFacesLoadedToProject() {
+        
+        for (int i = 0; i < model.getRowCount(); i++) {
+            HumanFace face = project.getFaceByName(model.getValueAt(i, 1).toString());
+            
+            if (face == null) {
+                if (eventBus != null) {
+                    eventBus.post(new AllFacesLoaded(false));
+                }
+                return;
             }
         }
-        return super.canClose(); //To change body of generated methods, choose Tools | Templates.
+        
+        if (eventBus != null) {
+            eventBus.post(new AllFacesLoaded(true));
+        }
     }
+    
+    /**
+     * Loads all faces from list to project and informs project listeners about it
+     */
+    public void loadAllFaces() {
+        
+        for (int i = 0; i < model.getRowCount(); i++) {
+            
+            String name = model.getValueAt(i, 1).toString();
+            project.loadFace(name);
 
+        }
+
+        if (eventBus != null) {
+            eventBus.post(new AllFacesLoaded(true));
+        }
+    }
+    
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton addButton;
+    private javax.swing.JButton analyseButton;
+    private javax.swing.JPanel buttonsPanel;
+    private javax.swing.JButton deselectAllButton;
+    private javax.swing.JScrollPane faceTableScrollPanel;
+    private javax.swing.JButton inflateButton;
+    private javax.swing.JButton manyToManyButton;
+    private javax.swing.JButton newProjectButton;
+    private javax.swing.JButton oneOnOneButton;
+    private javax.swing.JButton openProjectButton;
+    private javax.swing.JButton removeButton;
+    private javax.swing.JButton saveProjectButton;
+    private javax.swing.JButton selectAllButton;
+    private javax.swing.JTable table;
+    // End of variables declaration//GEN-END:variables
 }
diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/ProjectTopComp.java b/GUI/src/main/java/cz/fidentis/analyst/project/ProjectTopComp.java
new file mode 100644
index 00000000..f2b68bd7
--- /dev/null
+++ b/GUI/src/main/java/cz/fidentis/analyst/project/ProjectTopComp.java
@@ -0,0 +1,184 @@
+package cz.fidentis.analyst.project;
+
+import cz.fidentis.analyst.core.ControlPanel;
+import cz.fidentis.analyst.core.OutputWindowThread;
+import cz.fidentis.analyst.core.TopControlPanel;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import javax.swing.AbstractAction;
+import javax.swing.GroupLayout;
+import javax.swing.JScrollPane;
+import javax.swing.LayoutStyle;
+import org.netbeans.api.settings.ConvertAsProperties;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.util.NbBundle.Messages;
+import org.openide.windows.TopComponent;
+
+/**
+ * The main panel enabling analysts to select the primary and secondary faces,
+ * and to perform basic batch processing. This panel also serves as an entry
+ * point for detailed face analysis and face-to-face comparison.
+ *
+ * @author Matej Kovar
+ */
+@ConvertAsProperties(
+        dtd = "-//cz.fidentis.analyst.gui//Dashboard//EN",
+        autostore = false
+)
+@TopComponent.Description(
+        preferredID = "ProjectTopComp",
+        //iconBase="SET/PATH/TO/ICON/HERE",
+        persistenceType = TopComponent.PERSISTENCE_ALWAYS
+)
+@TopComponent.Registration(mode = "editor", openAtStartup = true)
+@ActionID(category = "Window", id = "cz.fidentis.analyst.gui.ProjectTopComp")
+@ActionReference(path = "Menu/Window" /*, position = 333 */)
+@TopComponent.OpenActionRegistration(
+        displayName = "#CTL_ProjectTopCompAction",
+        preferredID = "ProjectTopComp"
+)
+@Messages({
+    "CTL_ProjectTopCompAction=Project",
+    "CTL_ProjectTopCompTopComponent=Project",
+    "HINT_ProjectTopCompTopComponent=This is a Project window"
+})
+public final class ProjectTopComp extends TopComponent {
+    
+    private final ProjectPanel projectPanel;
+    private final TopControlPanel controlPanel;
+    private final JScrollPane projectPanelScrollPane;
+    private final JScrollPane controlPanelScrollPane;
+    
+    /**
+     * Project Top Component
+     */
+    public ProjectTopComp() {
+        
+        setName(Bundle.CTL_ProjectTopCompTopComponent());
+        setToolTipText(Bundle.HINT_ProjectTopCompTopComponent());
+        putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE);
+        putClientProperty(TopComponent.PROP_DRAGGING_DISABLED, Boolean.TRUE);
+        putClientProperty(TopComponent.PROP_UNDOCKING_DISABLED, Boolean.TRUE);
+        
+        projectPanel = new ProjectPanel();
+        controlPanel = new TopControlPanel();
+        projectPanelScrollPane = new JScrollPane(projectPanel);
+        controlPanelScrollPane = new JScrollPane(controlPanel);
+        
+        initComponents();
+        
+        
+        OutputWindowThread.execute();
+        
+        // Face State Panel
+        
+        // Listener for loading currently selected face (to show face state)
+        ActionListener listenerLoadFace = new AbstractAction() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                projectPanel.loadCurrentlySelectedFace();
+            }
+        };
+        
+        FaceStatePanel facePanel = new FaceStatePanel(listenerLoadFace);
+        this.controlPanel.addTab(facePanel.getName(), facePanel.getIcon(), facePanel);
+        this.controlPanel.setSelectedComponent(facePanel);
+        projectPanel.registerListener(facePanel);
+        
+        // Filter Panel
+        
+        // Listener for loading all faces - to enable filtering
+        ActionListener listenerLoadAllFaces = new AbstractAction() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                projectPanel.loadAllFaces();
+            }
+        };
+        
+        FilterPanel filterPanel = new FilterPanel(listenerLoadAllFaces);
+        this.controlPanel.addTab(filterPanel.getName(), filterPanel.getIcon(), filterPanel);
+        
+        // Listener for applying filter on faces
+        ActionListener listenerFilter = new AbstractAction() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                projectPanel.applyFilter(filterPanel.isFeaturePointsFilter(), filterPanel.isKdTreeFilter(), filterPanel.isAlphabeticalFilter());
+            }
+        };
+                
+        projectPanel.registerListener(filterPanel);
+        filterPanel.setFilterActionListener(listenerFilter);
+        
+        this.openAtTabPosition(0);
+        this.toFront();
+        this.requestActive();
+        
+    }
+    
+        private void initComponents() {
+        GroupLayout layout = new GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+                layout.createParallelGroup(GroupLayout.Alignment.LEADING)
+                        .addGroup(layout.createSequentialGroup()
+                                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+                                .addComponent(projectPanelScrollPane, GroupLayout.DEFAULT_SIZE, 651, Short.MAX_VALUE)
+                                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
+//                                .addComponent(renderingToolBar, GroupLayout.PREFERRED_SIZE, RenderingToolBar.WIDTH, GroupLayout.PREFERRED_SIZE)
+                                .addComponent(
+                                        controlPanelScrollPane,
+                                        ControlPanel.CONTROL_PANEL_WIDTH, 
+                                        ControlPanel.CONTROL_PANEL_WIDTH, 
+                                        ControlPanel.CONTROL_PANEL_WIDTH
+                                )
+                        )
+        );
+        layout.setVerticalGroup(
+                layout.createParallelGroup(GroupLayout.Alignment.LEADING)
+                        .addGroup(layout.createSequentialGroup()
+                                .addGroup(layout.createBaselineGroup(true, true)
+                                        .addComponent(projectPanelScrollPane)
+//                                        .addComponent(renderingToolBar)
+                                        .addComponent(controlPanelScrollPane)
+                                ))
+        );
+    }
+    
+    @Override
+    public void componentOpened() {
+        // TODO add custom code on component opening
+    }
+
+    @Override
+    public void componentClosed() {
+        // TODO add custom code on component closing
+    }
+
+    void writeProperties(java.util.Properties p) {
+        // better to version settings since initial version as advocated at
+        // http://wiki.apidesign.org/wiki/PropertyFiles
+        p.setProperty("version", "1.0");
+        // TODO store your settings
+    }
+
+    void readProperties(java.util.Properties p) {
+        String version = p.getProperty("version");
+        // TODO read your settings according to their version
+    }
+    
+    /*
+    @Override
+    public boolean canClose() {
+        if (!projectPanel.isProjectSaved()) {
+
+            int save = JOptionPane.showConfirmDialog(null,
+                    "Project is not saved. Would you like to save project?", "Save project", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
+
+            if (save == JOptionPane.YES_OPTION) {
+                projectPanel.saveProject();
+            }
+        }
+        return super.canClose(); //To change body of generated methods, choose Tools | Templates.
+    }*/
+}
diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/events/AllFacesLoaded.java b/GUI/src/main/java/cz/fidentis/analyst/project/events/AllFacesLoaded.java
new file mode 100644
index 00000000..437dc46d
--- /dev/null
+++ b/GUI/src/main/java/cz/fidentis/analyst/project/events/AllFacesLoaded.java
@@ -0,0 +1,28 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package cz.fidentis.analyst.project.events;
+
+/**
+ *
+ * @author Matej Kovar
+ */
+public class AllFacesLoaded extends ProjectEvent {
+    
+    private boolean allFacesLoaded;
+    
+    /**
+     * All faces loaded event constructor
+     * @param allFacesLoaded Boolean
+     */
+    public AllFacesLoaded(boolean allFacesLoaded) {
+        this.allFacesLoaded = allFacesLoaded;
+    }
+
+    public boolean isAllFacesLoaded() {
+        return allFacesLoaded;
+    }
+    
+}
diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/events/FaceDeselected.java b/GUI/src/main/java/cz/fidentis/analyst/project/events/FaceDeselected.java
new file mode 100644
index 00000000..89cf01a5
--- /dev/null
+++ b/GUI/src/main/java/cz/fidentis/analyst/project/events/FaceDeselected.java
@@ -0,0 +1,14 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package cz.fidentis.analyst.project.events;
+
+/**
+ *
+ * @author Matej Kovar
+ */
+public class FaceDeselected extends ProjectEvent {
+    
+}
diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/events/FaceSelected.java b/GUI/src/main/java/cz/fidentis/analyst/project/events/FaceSelected.java
new file mode 100644
index 00000000..be9579a7
--- /dev/null
+++ b/GUI/src/main/java/cz/fidentis/analyst/project/events/FaceSelected.java
@@ -0,0 +1,44 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package cz.fidentis.analyst.project.events;
+
+import cz.fidentis.analyst.face.HumanFace;
+import java.nio.file.Path;
+
+/**
+ *
+ * @author Matej Kovar
+ */
+public class FaceSelected extends ProjectEvent {
+    
+    private HumanFace face;
+    private String name;
+    private Path path;
+
+    /**
+     * Face selected event constructor
+     * @param face HumanFace
+     * @param name String
+     * @param path Path
+     */
+    public FaceSelected(HumanFace face, String name, Path path) {
+        this.face = face;
+        this.name = name;
+        this.path = path;
+    }
+
+    public HumanFace getFace() {
+        return face;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Path getPath() {
+        return path;
+    }
+}
diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/events/ProjectEvent.java b/GUI/src/main/java/cz/fidentis/analyst/project/events/ProjectEvent.java
new file mode 100644
index 00000000..be8fbabc
--- /dev/null
+++ b/GUI/src/main/java/cz/fidentis/analyst/project/events/ProjectEvent.java
@@ -0,0 +1,14 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package cz.fidentis.analyst.project.events;
+
+/**
+ *
+ * @author Matej Kovar
+ */
+public class ProjectEvent {
+
+}
diff --git a/GUI/src/main/java/cz/fidentis/analyst/project/events/ProjectListener.java b/GUI/src/main/java/cz/fidentis/analyst/project/events/ProjectListener.java
new file mode 100644
index 00000000..24097e6d
--- /dev/null
+++ b/GUI/src/main/java/cz/fidentis/analyst/project/events/ProjectListener.java
@@ -0,0 +1,23 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package cz.fidentis.analyst.project.events;
+
+import com.google.common.eventbus.Subscribe;
+
+/**
+ *
+ * @author Matej Kovar
+ */
+public interface ProjectListener {
+    
+    /**
+     * Subscription method, which is invoked when an event appears.
+     * 
+     * @param event A fired event.
+     */
+    @Subscribe
+    void acceptEvent(ProjectEvent event);
+}
diff --git a/GUI/src/main/resources/cz/fidentis/analyst/project/Bundle.properties b/GUI/src/main/resources/cz/fidentis/analyst/project/Bundle.properties
new file mode 100644
index 00000000..0b7316a4
--- /dev/null
+++ b/GUI/src/main/resources/cz/fidentis/analyst/project/Bundle.properties
@@ -0,0 +1,35 @@
+FaceStatePanel.filePanel.AccessibleContext.accessibleName=File info
+FaceStatePanel.filePanel.border.title=File info
+FaceStatePanel.pathLabel.text=Path :
+FaceStatePanel.sizeLabel.text=Size :
+FaceStatePanel.pathOutput.text=
+FaceStatePanel.sizeOutput.text=
+FaceStatePanel.facePanel.border.title=Face info
+FaceStatePanel.kdTreeLabel.text=Has KD - tree :
+FaceStatePanel.featurePointsLoadedLabel.text=Feature points loaded :
+FaceStatePanel.photoPanel.border.title=Photo
+FaceStatePanel.photo.text=
+FaceStatePanel.hasKDOutput.text=
+FaceStatePanel.hasFPOutput.text=
+FaceStatePanel.warningLabel.text=
+FaceStatePanel.faceNotLoadedLabel.text=Face not loaded
+FaceStatePanel.loadFaceButton.text=Load face
+FilterPanel.filterPanel.border.title=Filter settings
+FilterPanel.hasFP.text=has feature points
+FilterPanel.hasKD.text=has kd-tree
+FilterPanel.alphabetical.text=alphabetical
+FilterPanel.applyFilterButton.text=Apply filter
+FilterPanel.warningLabel.text=
+FilterPanel.faceNotLoadedLabel.text=All models must be loaded for filtering
+FilterPanel.loadAllModelsButton.text=Load all models
+ProjectPanel.newProjectButton.text=
+ProjectPanel.openProjectButton.text=
+ProjectPanel.saveProjectButton.text=
+ProjectPanel.analyseButton.text=Analyse
+ProjectPanel.manyToManyButton.text=N:N
+ProjectPanel.oneOnOneButton.text=Open 1:1
+ProjectPanel.inflateButton.text=Inflate
+ProjectPanel.deselectAllButton.text=Deselect all
+ProjectPanel.selectAllButton.text=Select all
+ProjectPanel.removeButton.text=Remove
+ProjectPanel.addButton.text=Add
diff --git a/GUI/src/main/resources/face160x160.png b/GUI/src/main/resources/face160x160.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce753351ef1d0d43fd85baac2c0e3672b0951f43
GIT binary patch
literal 4468
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
GLSTaSN@~pj

literal 0
HcmV?d00001

diff --git a/GUI/src/main/resources/face16x16.png b/GUI/src/main/resources/face16x16.png
new file mode 100644
index 0000000000000000000000000000000000000000..26bee8f05a6d3fa98e2aebeda660e27c76643c8d
GIT binary patch
literal 365
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl
z_H+M9WCij$3p^r=85sBugD~Uq{1quc4NRUcjv*HQQzv_K9WoGToBbtGKE!)r*e<;t
z#g|*vFKEBWJ)&G8A^zyt?2ZRsEaqKYi~cocW_qmn+Whj*8SRq}yt0WBeU{IyZ#d7$
zoMnCf^RX#;Y-gR1-QfKcY<^^&68l{qzvzRWXO{;0HBDZBS#|wl_kB+051iuKCtc<Z
z@LT!uH`}({d=D*?r&^zE-X}cv_sDGQxZAyG!@~OH$ZJx5QVtu-Tmns+CbI?jIBs`Q
z?t9F9vP<W5pUP~{%Uj-CoMQ^w#VEGJXHp8oTBT`^cfI3ze<vYQzh%j@OD=q-(O1r`
zZe?>cILN<Qzx&p#7awcuvmEA>u;%jYO>a9dZNT!ct@z(hrU`#zzuH$$egh0522WQ%
Jmvv4FO#qYil|}#n

literal 0
HcmV?d00001

diff --git a/GUI/src/main/resources/face200x200.png b/GUI/src/main/resources/face200x200.png
new file mode 100644
index 0000000000000000000000000000000000000000..597ba22fc1ded7778d29a02604ada767622102bc
GIT binary patch
literal 4801
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
BWM}{Y

literal 0
HcmV?d00001

diff --git a/GUI/src/main/resources/face32x32.png b/GUI/src/main/resources/face32x32.png
new file mode 100644
index 0000000000000000000000000000000000000000..175f3a590d67aefd1dec061e56d471c922824320
GIT binary patch
literal 745
zcmV<F0v7#=P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800001b5ch_0Itp)
z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0)9zEK~z{r#g<Kr
z(?A%<H)-0&z9fCwzGzDerL+>ngN3@D3Sz}W53<-VB3{HpuO1Zi6NrKb59)VV@gs;Q
zvA!d=1qo}hBwhcbPeJQU)7hQf{lTB-Kf{xGCYebx8#46!{g7?j+tFzBc{m*Y914Ye
zCg#!iER)G>vm8oSOS9QLg(5Ft_f`oxJJo8n2(OM>t!CpcU&C^XE(^J@9LGt(t05MP
z-9z9O6Dg5M+($e(?RMM3I{$#>77|I<b+_B?#^Db}Hk-YOz%3FaY|2ZBE72(mnayS<
zS!t%z=?Stz0w)lOM81)g#<HxhWQ7DyAe~NsAuCO>So}m*NZ<tK^Lb#72wba?6%si3
zWHLERR+`~(c#f=)zzHOi$+u*sNu^S6$nGEZZ8r?#BP{n-6A53#4~T(Fuoid<*Acjd
zM8Y*U5Y<qrR8DG|HizXFTNZNtR;#rMuZF>3pko=>>&Pv*EabjNRP*>3n5Ovvfm?7{
z_$5C?R7*ae-(rszmRoco<amWb;XJ&0@Qb~Jz%9HGa_%A?4%mzi0=Mu&<#PE9;@U`k
zW<Aey$qFfzN<Yc2h13MFyA85JMxzmX5^Ezh0oQf6$O;*c#}~+|q0{M@IEr7ztMvrO
zEDv4(t^40%Zvk?j;xu%v*Xza5Cl87mxm@lt26}|^;CFO!iv<bSx)|dz#=64BMBi!}
zjm9QUz&Ekf@6hB9x?i!M6UM%UBYqz3f2r5&Ry-cRjT!Hv$sItIu#CH`7CUXD{rlMD
z;EvfppL@Y!2{nh<Ck{Jw?(h<hLf9WKb)4Hyqj4<wzTafufz+Sov0!W16nl6I)IM5t
bUElZxm=$pP5U*9w00000NkvXXu0mjfsDn}B

literal 0
HcmV?d00001

diff --git a/GUI/src/main/resources/filter28x28.png b/GUI/src/main/resources/filter28x28.png
new file mode 100644
index 0000000000000000000000000000000000000000..af4f1891a89a28ea0b74dd7cc528ce08212a0099
GIT binary patch
literal 885
zcmV-*1B(2KP)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00001b5ch_0Itp)
z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0}4q*K~zXfwU#@J
z6JZpFXL2{2Y%aUGv0=9`g`_axvWk|1g%<?TN)Rn%J3Gb3LToH;#ljz;qSY$?02Nfw
zLIhFVYC*-qB&+5&iO)ICj9GP)Np|zX;k=o1=Dgqe=DWnqX0y3kt#-B3=^Qf*Bi8M9
zeSW_`gg1M=o*@<t2E)XZ_j}Vc)eD4EqfM;q^Z5)h%d%SdF3-ME;{jUNj8G`_n0%=)
zaSMmTD<<7A5X;91yVxtNC!-VecOY;&bHFU9@9$hJ5C{aRVNzFq`>`@+^30OpN68hN
znwq-4xVRXEi_(@&YDJ^b8*r_U)~XSY$IsA7+kR+CLb+TH!MB8BvA6@=hN>7E%|s$`
zQeysCEOrIov4d7561in}Iu;6rLX_`y7b<fuVhtKQ2bazjCh8aQnjoIh-5E!8d3iaA
z*gdGzSu2@Lo`t(&E)YFW!Vjn>^Wy!PnVGl-Jz#!*KE>=jgzEb&l6AyRYj6`tr>97)
z!?jbk&7*~dg``FYfSf#g?J3j|`^sPsYH$e5bUJ;gPqas&CzVQNQ_)hXlp*IORP)(t
zUl3c;pjYJc`6XWb40S|b<Z`*J2K&G?7Fh1Dp^n(6+1c4W8XOhO|85GbLY-pIrl+UV
z8U%B5b4A47LNyM5lgVUuYH(aophTf}P%WBDrH*I-a8O*pIWzE_&I%gXD%eAZak^z>
zQRzd#ioA>y!4^3O^x+WvJ~W4b(OWh(n$4#Bj&qi>mBhI@gWyRJNEZsGQLie2BRC2?
z30A9BIcpWIR?BAN!E1*u+HF^R1DJN34TdK{7KhFFP?q)YnK%MQ?vR`1kNQTq-+2&5
z?$B8%9A{znr)~vq^IpAP|NmV71y6!3dw2Bm4LPVIYinya8;!<sc_#NA`*U3rwgYx2
zy7B4u61E~-46&d59(V<f3<~bYsi53(;>8gA&e5lT8@3f3TdtsEh}F5qPQbSx2=2qV
zf^=EsCOImxiGbo2oC?Yv$-TH&1CxUM#o#3QfW7A**)IF>7%+@q3P~Lwb_|X;00000
LNkvXXu0mjf;wqEI

literal 0
HcmV?d00001

diff --git a/GUI/src/main/resources/warning16x16.png b/GUI/src/main/resources/warning16x16.png
new file mode 100644
index 0000000000000000000000000000000000000000..136173d381479e8f3f2c179dbe866dd9c777ca07
GIT binary patch
literal 411
zcmV;M0c8G(P)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00001b5ch_0Itp)
z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGikpKV=kpT{*K287t0We8KK~y+Tjgvhu
zLtz+(U&4Sy6Qhqm;47?*tPCU-egeONl~vRx5(AS6gT%)mBw~<|kg#^r#i#~CT=(;w
zmeX@u=Sr^hzE7XGZ~NwLQ>afXj(ZH(_~|hl-S~vxk<Zby1kKTFEd|t$J*b5rxQUsV
zK<!%j`eF?AY|>f-TJQn)ti{>IN7PJR7O{+d)<RgrRga+;-*CxV3SIb$E7qJly!B`-
zqh>UlU>%FtX3e?4bB~7J)69moKlGzcea_l1hq&*tN**;kU@hVludw!F?clb@Dw?^(
zGixw~UpQ(l&JYfIjG<YrnO4z3Z7HO1ga;lIXwAKXZrO}N3JW;zF~KZqZMeZ>>{Q7}
z4o^^jvM_=r)Nj%!W>MGr1&1rA-hsON?biP19oapUe*k%ELxy^ZXJY^W002ovPDHLk
FV1f<Tu_6Ef

literal 0
HcmV?d00001

-- 
GitLab