Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

working version of the demo tableview

  • Loading branch information...
commit 5720b690fb6743adf1895f12730149cb58f2722e 1 parent 3efc59f
@Elisabeth-Engel Elisabeth-Engel authored
Showing with 1,714 additions and 1 deletion.
  1. +17 −0 .gitignore
  2. +1 −1  README.md
  3. +4 −0 README.md~
  4. +117 −0 pom.xml
  5. +21 −0 src/main/java/com/comsysto/CustomerApp.java
  6. +11 −0 src/main/java/com/comsysto/CustomerAppConfiguration.java
  7. +14 −0 src/main/java/com/comsysto/CustomerDataScreenController.java
  8. +5 −0 src/main/java/com/comsysto/DialogController.java
  9. +38 −0 src/main/java/com/comsysto/FXMLDialog.java
  10. +38 −0 src/main/java/com/comsysto/FXMLStage.java
  11. +145 −0 src/main/java/com/comsysto/MainController.java
  12. +50 −0 src/main/java/com/comsysto/ScreensConfiguration.java
  13. +5 −0 src/main/java/com/comsysto/StageController.java
  14. +31 −0 src/main/java/com/comsysto/StandardController.java
  15. +31 −0 src/main/java/com/comsysto/config/Neo4jConfig.java
  16. +140 −0 src/main/java/com/comsysto/neo4j/domain/Neo4jCustomer.java
  17. +9 −0 src/main/java/com/comsysto/neo4j/domain/Neo4jNode.java
  18. +41 −0 src/main/java/com/comsysto/neo4j/repos/Neo4jCustomerRepository.java
  19. +96 −0 src/main/java/com/comsysto/setup/DatabaseSetup.java
  20. +116 −0 src/main/java/com/comsysto/util/FXOptionPane.java
  21. +628 −0 src/main/java/com/comsysto/util/Neo4jTableBuilder.java
  22. +23 −0 src/main/java/com/comsysto/util/Neo4jTableBuilderColumnField.java
  23. +17 −0 src/main/java/com/comsysto/util/Neo4jTableBuilderColumnSetMethod.java
  24. +40 −0 src/main/resources/com/comsysto/About.fxml
  25. +53 −0 src/main/resources/com/comsysto/Main.fxml
  26. BIN  src/main/resources/com/comsysto/img/simple_header.jpg
  27. +23 −0 src/main/resources/com/comsysto/style.css
View
17 .gitignore
@@ -0,0 +1,17 @@
+*.class
+
+# Package Files #
+*.jar
+*.war
+*.ear
+*.bak
+
+*.iml
+*/.idea
+*/target
+
+.idea
+target
+data
+*.iml
+.DS_Store
View
2  README.md
@@ -1,4 +1,4 @@
spring-data-neo4j-javafx-tableview
==================================
-This is a showcase demonstrating how Spring Data Neo4j can be displayed and edited in a JavaFX TableView.
+This is a showcase demonstrating how Spring Data Neo4j nodes can be displayed and edited in a JavaFX TableView.
View
4 README.md~
@@ -0,0 +1,4 @@
+spring-data-neo4j-javafx-tableview
+==================================
+
+This is a showcase demonstrating how Spring Data Neo4j can be displayed and edited in a JavaFX TableView.
View
117 pom.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <groupId>com.comsysto</groupId>
+ <artifactId>spring-data-neo4j-javafx-tableview</artifactId>
+ <version>1.0</version>
+
+ <properties>
+ <java-version>1.6</java-version>
+ <org.springframework-version>3.1.2.RELEASE</org.springframework-version>
+ <spring.data.neo4j.version>2.1.0.RC3</spring.data.neo4j.version>
+ </properties>
+ <dependencies>
+ <!-- Java FX -->
+ <dependency>
+ <groupId>com.oracle</groupId>
+ <artifactId>javafx</artifactId>
+ <version>2.2</version>
+ <scope>system</scope>
+ <systemPath>${java.home}/lib/jfxrt.jar</systemPath>
+ </dependency>
+ <dependency>
+ <groupId>org.jfxtras</groupId>
+ <artifactId>jfxtras-labs</artifactId>
+ <version>2.2-r4</version>
+ </dependency>
+
+ <!-- Spring -->
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-core</artifactId>
+ <version>${org.springframework-version}</version>
+ </dependency>
+
+ <!-- Neo4j -->
+ <dependency>
+ <groupId>org.springframework.data</groupId>
+ <artifactId>spring-data-neo4j</artifactId>
+ <version>${spring.data.neo4j.version}</version>
+ </dependency>
+
+ <!-- other Spring stuff -->
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ <version>${org.springframework-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-beans</artifactId>
+ <version>${org.springframework-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-expression</artifactId>
+ <version>${org.springframework-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-orm</artifactId>
+ <version>${org.springframework-version}</version>
+ </dependency>
+ </dependencies>
+
+ <repositories>
+ <!-- For testing against latest Spring snapshots -->
+ <repository>
+ <id>org.springframework.maven.snapshot</id>
+ <name>Spring Maven Snapshot Repository</name>
+ <url>http://maven.springframework.org/snapshot</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ <!-- For developing against latest Spring milestones -->
+ <repository>
+ <id>org.springframework.maven.milestone</id>
+ <name>Spring Maven Milestone Repository</name>
+ <url>http://maven.springframework.org/milestone</url>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ <!-- Neo4j -->
+ <repository>
+ <id>m2.neo4j.org</id>
+ <url>http://m2.neo4j.org/content/repositories/releases</url>
+ </repository>
+ </repositories>
+ <pluginRepositories>
+ <pluginRepository>
+ <id>repository.springframework.maven.milestone</id>
+ <name>Spring Framework Maven Milestone Repository</name>
+ <url>http://maven.springframework.org/milestone</url>
+ </pluginRepository>
+ </pluginRepositories>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.3.2</version>
+ <configuration>
+ <source>${java-version}</source>
+ <target>${java-version}</target>
+ <fork>true</fork>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
View
21 src/main/java/com/comsysto/CustomerApp.java
@@ -0,0 +1,21 @@
+package com.comsysto;
+
+import javafx.application.Application;
+import javafx.stage.Stage;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+public class CustomerApp extends Application {
+ public static void main(String[] args) {
+ launch(args);
+ }
+
+ @Override
+ public void start(Stage stage) throws Exception {
+ ApplicationContext context = new AnnotationConfigApplicationContext(CustomerAppConfiguration.class);
+ ScreensConfiguration screens = context.getBean(ScreensConfiguration.class);
+
+ screens.setPrimaryStage(stage);
+ screens.mainStage().show();
+ }
+}
View
11 src/main/java/com/comsysto/CustomerAppConfiguration.java
@@ -0,0 +1,11 @@
+package com.comsysto;
+
+import com.comsysto.config.Neo4jConfig;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+@Configuration
+@Import({Neo4jConfig.class, ScreensConfiguration.class})
+public class CustomerAppConfiguration {
+
+}
View
14 src/main/java/com/comsysto/CustomerDataScreenController.java
@@ -0,0 +1,14 @@
+package com.comsysto;
+
+public class CustomerDataScreenController {
+
+ private ScreensConfiguration screens;
+
+ public CustomerDataScreenController() {
+ }
+
+ public CustomerDataScreenController(ScreensConfiguration screens) {
+ this.screens = screens;
+ }
+
+}
View
5 src/main/java/com/comsysto/DialogController.java
@@ -0,0 +1,5 @@
+package com.comsysto;
+
+public interface DialogController {
+ void setDialog(FXMLDialog dialog);
+}
View
38 src/main/java/com/comsysto/FXMLDialog.java
@@ -0,0 +1,38 @@
+package com.comsysto;
+
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.StageStyle;
+import javafx.util.Callback;
+
+import java.io.IOException;
+import java.net.URL;
+
+public class FXMLDialog extends Stage {
+ public FXMLDialog(DialogController controller, URL fxml, Stage owner) {
+ this(controller, fxml, owner, StageStyle.UTILITY);
+ }
+
+ public FXMLDialog(final DialogController controller, URL fxml, Stage owner, StageStyle style) {
+ super(style);
+ initOwner(owner);
+ initModality(Modality.WINDOW_MODAL);
+ setResizable(false);
+ FXMLLoader loader = new FXMLLoader(fxml);
+ try {
+ loader.setControllerFactory(new Callback<Class<?>, Object>() {
+ @Override
+ public Object call(Class<?> aClass) {
+ return controller;
+ }
+ });
+ controller.setDialog(this);
+ setScene(new Scene((Parent) loader.load()));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
View
38 src/main/java/com/comsysto/FXMLStage.java
@@ -0,0 +1,38 @@
+package com.comsysto;
+
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.StageStyle;
+import javafx.util.Callback;
+
+import java.io.IOException;
+import java.net.URL;
+
+public class FXMLStage extends Stage {
+ public FXMLStage(StageController controller, URL fxml, Stage owner) {
+ this(controller, fxml, owner, StageStyle.DECORATED);
+ }
+
+ public FXMLStage(final StageController controller, URL fxml, Stage owner, StageStyle style) {
+ super(style);
+ initOwner(owner);
+ initModality(Modality.APPLICATION_MODAL);
+ owner.setResizable(true);
+ FXMLLoader loader = new FXMLLoader(fxml);
+ try {
+ loader.setControllerFactory(new Callback<Class<?>, Object>() {
+ @Override
+ public Object call(Class<?> aClass) {
+ return controller;
+ }
+ });
+ controller.setStage(this);
+ setScene(new Scene((Parent) loader.load()));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
View
145 src/main/java/com/comsysto/MainController.java
@@ -0,0 +1,145 @@
+package com.comsysto;
+
+import com.comsysto.neo4j.domain.Neo4jCustomer;
+import com.comsysto.neo4j.repos.Neo4jCustomerRepository;
+import com.comsysto.util.Neo4jTableBuilder;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.scene.control.*;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.VBox;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+
+import java.net.URL;
+import java.util.ResourceBundle;
+
+/** The class is the main controller for the app connected with Main.fxml
+ *
+ */
+public class MainController implements StageController, Initializable {
+
+ private ScreensConfiguration screensConfig;
+
+ private FXMLStage stage;
+
+ @SuppressWarnings("SpringJavaAutowiringInspection")
+ @Autowired
+ Neo4jCustomerRepository neo4jCustomerRepository;
+
+ @SuppressWarnings("SpringJavaAutowiringInspection")
+ @Autowired
+ @Qualifier("aboutDialog")
+ private FXMLDialog aboutDialog;
+
+ Neo4jTableBuilder neo4jCustomerTableBuilder;
+
+ /** constructs the mainController with the given ScreensConfiguration
+ *
+ * @param screensConfig The ScreensConfiguration
+ */
+ public MainController(ScreensConfiguration screensConfig) {
+
+ super();
+ this.screensConfig = screensConfig;
+
+ }
+
+ @Override
+ public void setStage(FXMLStage stage) {
+ this.stage = stage;
+ stage.setTitle("Spring Data Neo4j JavaFX TableView Demo");
+ }
+
+ @FXML // fx:id="about_menuitem"
+ private MenuItem about_menuitem; // Value injected by FXMLLoader
+
+ @FXML // fx:id="file_menu"
+ private Menu file_menu; // Value injected by FXMLLoader
+
+ @FXML // fx:id="file_quit_menuitem"
+ private MenuItem file_quit_menuitem; // Value injected by FXMLLoader
+
+ @FXML // fx:id="help_menu"
+ private Menu help_menu; // Value injected by FXMLLoader
+
+ @FXML // fx:id="main_data_table_anchorpane"
+ private AnchorPane main_data_table_anchorpane; // Value injected by FXMLLoader
+
+ @FXML // fx:id="main_data_toolbar"
+ private ToolBar main_data_toolbar; // Value injected by FXMLLoader
+
+ @FXML // fx:id="main_data_toolbar_search_textfield"
+ private TextField main_data_toolbar_search_textfield; // Value injected by FXMLLoader
+
+ @FXML // fx:id="main_data_vbox"
+ private VBox main_data_vbox; // Value injected by FXMLLoader
+
+ @FXML // fx:id="main_menubar"
+ private MenuBar main_menubar; // Value injected by FXMLLoader
+
+ @FXML // fx:id="main_vbox"
+ private VBox main_vbox; // Value injected by FXMLLoader
+
+ @FXML // fx:id="menu_data_customers_tableview"
+ private TableView<?> menu_data_customers_tableview; // Value injected by FXMLLoader
+
+ @Override // This method is called by the FXMLLoader when initialization is complete
+ public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
+ assert about_menuitem != null : "fx:id=\"about_menuitem\" was not injected: check your FXML file 'Main.fxml'.";
+ assert file_menu != null : "fx:id=\"file_menu\" was not injected: check your FXML file 'Main.fxml'.";
+ assert file_quit_menuitem != null : "fx:id=\"file_quit_menuitem\" was not injected: check your FXML file 'Main.fxml'.";
+ assert help_menu != null : "fx:id=\"help_menu\" was not injected: check your FXML file 'Main.fxml'.";
+ assert main_data_table_anchorpane != null : "fx:id=\"main_data_table_anchorpane\" was not injected: check your FXML file 'Main.fxml'.";
+ assert main_data_toolbar != null : "fx:id=\"main_data_toolbar\" was not injected: check your FXML file 'Main.fxml'.";
+ assert main_data_toolbar_search_textfield != null : "fx:id=\"main_data_toolbar_search_textfield\" was not injected: check your FXML file 'Main.fxml'.";
+ assert main_data_vbox != null : "fx:id=\"main_data_vbox\" was not injected: check your FXML file 'Main.fxml'.";
+ assert main_menubar != null : "fx:id=\"main_menubar\" was not injected: check your FXML file 'Main.fxml'.";
+ assert main_vbox != null : "fx:id=\"main_vbox\" was not injected: check your FXML file 'Main.fxml'.";
+ assert menu_data_customers_tableview != null : "fx:id=\"menu_data_customers_tableview\" was not injected: check your FXML file 'Main.fxml'.";
+
+ // initialize your logic here: all @FXML variables will have been injected
+
+ initNeo4jDataTables();
+
+ }
+
+
+ /** inits the tableViews and the neo4j inside
+ *
+ */
+ private void initNeo4jDataTables()
+ {
+ neo4jCustomerTableBuilder = new Neo4jTableBuilder(Neo4jCustomer.class, neo4jCustomerRepository, menu_data_customers_tableview);
+ neo4jCustomerTableBuilder.initDataTable();
+ neo4jCustomerTableBuilder.setTableData(neo4jCustomerRepository.findAll());
+ }
+
+ /** cunducts the search with the search expression entered in the search field
+ *
+ */
+ @FXML
+ public void searchTextfieldKeyReleased() {
+ System.out.println("searchTextfieldKeyReleased original");
+ neo4jCustomerTableBuilder.setTableData(neo4jCustomerRepository.findByCustomerNameLike("*" + main_data_toolbar_search_textfield.getText() + "*"));
+
+ }
+
+ /** exits the programme
+ */
+ @FXML
+ public void quit() {
+
+ stage.close();
+ }
+
+ /** shows the about dialog
+ */
+ @FXML
+ public void about() {
+
+ //aboutDialog.centerOnScreen();
+ aboutDialog.showAndWait();
+
+ }
+}
View
50 src/main/java/com/comsysto/ScreensConfiguration.java
@@ -0,0 +1,50 @@
+package com.comsysto;
+
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.context.annotation.Scope;
+
+@Configuration
+@Lazy
+public class ScreensConfiguration {
+ private static Stage primaryStage;
+
+ public static void setPrimaryStage(Stage newPrimaryStage) {
+ primaryStage = newPrimaryStage;
+ }
+
+ public static Stage getPrimaryStage() {
+ return primaryStage;
+ }
+
+ public void showScreen(Parent screen) {
+ primaryStage.setScene(new Scene(screen, 777, 500));
+ primaryStage.show();
+ }
+
+ @Bean
+ MainController mainController() {
+ return new MainController(this);
+ }
+
+ @Bean
+ FXMLStage mainStage() {
+ return new FXMLStage(mainController(), getClass().getResource("Main.fxml"), primaryStage);
+ }
+
+ @Bean
+ @Scope("prototype")
+ StandardController aboutController() {
+ return new StandardController();
+ }
+
+ @Bean(name="aboutDialog")
+ FXMLDialog aboutDialog() {
+ return new FXMLDialog(aboutController(), getClass().getResource("About.fxml"), primaryStage);
+ }
+
+}
View
5 src/main/java/com/comsysto/StageController.java
@@ -0,0 +1,5 @@
+package com.comsysto;
+
+public interface StageController {
+ void setStage(FXMLStage stage);
+}
View
31 src/main/java/com/comsysto/StandardController.java
@@ -0,0 +1,31 @@
+package com.comsysto;
+
+import javafx.fxml.FXML;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+public class StandardController implements DialogController {
+ private FXMLDialog dialog;
+
+ public void setDialog(FXMLDialog dialog) {
+ this.dialog = dialog;
+ }
+
+ @FXML
+ public void email() {
+ try {
+ java.awt.Desktop.getDesktop().mail(new URI("mailto:Elisabeth.Engel@comsysto.com"));
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (URISyntaxException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @FXML
+ public void close() {
+ dialog.close();
+ }
+}
View
31 src/main/java/com/comsysto/config/Neo4jConfig.java
@@ -0,0 +1,31 @@
+package com.comsysto.config;
+
+import com.comsysto.setup.DatabaseSetup;
+import org.neo4j.graphdb.GraphDatabaseService;
+import org.neo4j.kernel.EmbeddedGraphDatabase;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.neo4j.config.EnableNeo4jRepositories;
+import org.springframework.data.neo4j.config.Neo4jConfiguration;
+
+/** @author Daniel Bartl */
+@Configuration
+@EnableNeo4jRepositories("com.comsysto.neo4j.repos")
+public class Neo4jConfig extends Neo4jConfiguration {
+
+ @Bean
+ public GraphDatabaseService graphDatabaseService() {
+
+ // removed with every maven clear
+ //return new EmbeddedGraphDatabase("./target/neo4j-testdb-2");
+ // stays after clear
+ return new EmbeddedGraphDatabase("./data/neo4j-testdb");
+ }
+
+ @Bean
+ public DatabaseSetup databaseSetup() {
+
+ return new DatabaseSetup();
+ }
+
+}
View
140 src/main/java/com/comsysto/neo4j/domain/Neo4jCustomer.java
@@ -0,0 +1,140 @@
+package com.comsysto.neo4j.domain;
+
+import com.comsysto.util.Neo4jTableBuilderColumnField;
+import com.comsysto.util.Neo4jTableBuilderColumnSetMethod;
+import org.neo4j.graphdb.Direction;
+import org.springframework.data.neo4j.annotation.*;
+import org.springframework.data.neo4j.support.index.IndexType;
+
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+/** @author Elisabeth Engel */
+@NodeEntity
+public class Neo4jCustomer implements Neo4jNode {
+
+ static private Integer nextIdValue = 1;
+
+ @GraphId
+ private Long graphId;
+
+ @Indexed(indexName = "customerIntIdIndex")
+ private Integer intId;
+
+ @Indexed(indexType = IndexType.FULLTEXT, indexName = "customerName")
+ private String customerName;
+
+ private String firstname;
+
+ private String lastname;
+
+ @Neo4jTableBuilderColumnField(columnName = "Signup Date", columnOrder = 3)
+ private Date signupDate;
+
+ @Neo4jTableBuilderColumnField(columnName = "#Knows", columnType = Neo4jTableBuilderColumnField.FieldType.readOnly, columnOrder = 10)
+ private Integer amountKnows;
+
+ @Fetch
+ @RelatedTo(type = "KNOWS", direction = Direction.BOTH)
+ private Set<Neo4jCustomer> friends = new HashSet<Neo4jCustomer>();
+
+ public Neo4jCustomer() {
+ this("[new]", "[new]");
+ }
+
+ public Neo4jCustomer(String firstname, String lastname) {
+ this(firstname, lastname, new Date());
+ }
+
+ public Neo4jCustomer(String firstname, String lastname, Date signupDate) {
+
+ this.intId = nextIdValue++;
+
+ this.customerName = firstname+" "+lastname;
+ this.firstname = firstname;
+ this.lastname = lastname;
+ this.signupDate = signupDate;
+ this.amountKnows = 0;
+ }
+
+ @Override
+ public Integer getId() {
+ return intId;
+ }
+
+ @Override
+ public boolean isSaved() {
+ return graphId != null;
+ }
+
+ public void setId(Integer id) {
+ this.intId = id;
+ }
+
+ public String getCustomerName() {
+ return customerName;
+ }
+
+ public void setCustomerName(String customerName) {
+ this.customerName = customerName;
+ }
+
+ public String getFirstname() {
+ return firstname;
+ }
+
+ @Neo4jTableBuilderColumnSetMethod(columnName = "Firstname", columnOrder = 1)
+ public void setFirstname(String firstname) {
+ this.firstname = firstname;
+ this.customerName = firstname+" "+lastname;
+ }
+
+ public String getLastname() {
+ return lastname;
+ }
+
+ @Neo4jTableBuilderColumnSetMethod(columnName = "Lastname", columnOrder = 2)
+ public void setLastname(String lastname) {
+ this.lastname = lastname;
+ this.customerName = firstname+" "+lastname;
+ }
+
+ public Date getSignupDate() {
+ return signupDate;
+ }
+
+ public void setSignupDate(Date signupDate) {
+ this.signupDate = signupDate;
+ }
+
+ public void addFriend(Neo4jCustomer newFriend) {
+ friends.add(newFriend);
+ if (!newFriend.areFriends(this)) newFriend.addFriend(this);
+ amountKnows++;
+ }
+
+ public boolean areFriends(Neo4jCustomer otherNeo4jCustomer) {
+ return friends.contains(otherNeo4jCustomer);
+ }
+
+ public Integer getAmountKnows() {
+ //return friends.size();
+ return amountKnows;
+ }
+
+
+ @Override
+ public String toString() {
+ return "Neo4jCustomer{" +
+ "graphId=" + graphId +
+ ", intId=" + intId +
+ ", customerName=" + customerName +
+ ", firstname='" + firstname + '\'' +
+ ", lastname='" + lastname + '\'' +
+ ", signupDate='" + signupDate + '\'' +
+ ", #friends=" + friends.size() +
+ ", #knows=" + getAmountKnows() +
+ '}';
+ }
+}
View
9 src/main/java/com/comsysto/neo4j/domain/Neo4jNode.java
@@ -0,0 +1,9 @@
+package com.comsysto.neo4j.domain;
+
+/** @author Elisabeth Engel */
+public interface Neo4jNode {
+
+ public abstract Integer getId();
+
+ public abstract boolean isSaved();
+}
View
41 src/main/java/com/comsysto/neo4j/repos/Neo4jCustomerRepository.java
@@ -0,0 +1,41 @@
+package com.comsysto.neo4j.repos;
+
+import com.comsysto.neo4j.domain.Neo4jCustomer;
+import org.springframework.data.neo4j.repository.GraphRepository;
+
+import java.util.List;
+
+/** @author Elisabeth Engel */
+public interface Neo4jCustomerRepository extends GraphRepository<Neo4jCustomer> {
+
+ List<Neo4jCustomer> findOneByCustomerName(String customerName);
+
+ Iterable<Neo4jCustomer> findByCustomerNameLike(String customerName);
+ /*
+ // Neo4jCustomer with firstname and lastname
+ @Query("start customer=node:Neo4jCustomer(firstname={0}) " +
+ "where customer.lastname = {1} " +
+ "return customer")
+ List<Neo4jCustomer> findCustomer(String firstname, String lastname);
+
+ // all friends of one customer
+ @Query("start customer=node:Neo4jCustomer(customerName={0}) " +
+ "match customer-[:KNOWS]-(friend) " +
+ "return friend")
+ List<Neo4jCustomer> findAllFriends(String name);
+
+ // friends of friends, that aren't already friends of this customer
+ @Query("start customer=node:Neo4jCustomer(customerName={0}) " +
+ "match customer-[:KNOWS*1..3]-(friend) " +
+ "where not(customer-[:KNOWS]-friend) and not(customer = friend) " +
+ "return distinct friend")
+ List<Neo4jCustomer> findNewFriends(String name);
+
+ // common friends
+ @Query("start customer1=node:Neo4jCustomer(customerName={0}), customer2=node:Neo4jCustomer(customerName={1}) " +
+ "match customer1-[:KNOWS]-(friend)-[:KNOWS]-customer2 " +
+ "where not(customer1 = customer2) " +
+ "return distinct friend")
+ List<Neo4jCustomer> findOurFriends(String name1, String name2);
+ */
+}
View
96 src/main/java/com/comsysto/setup/DatabaseSetup.java
@@ -0,0 +1,96 @@
+package com.comsysto.setup;
+
+import com.comsysto.neo4j.domain.Neo4jCustomer;
+import com.comsysto.neo4j.repos.Neo4jCustomerRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import javax.annotation.PostConstruct;
+import java.util.ArrayList;
+import java.util.Collection;
+
+/** @author Daniel Bartl */
+public class DatabaseSetup {
+
+ @SuppressWarnings("SpringJavaAutowiringInspection")
+ @Autowired
+ Neo4jCustomerRepository neo4jCustomerRepository;
+
+ @PostConstruct
+ public void init() {
+
+ // empty repositories
+ //neo4jCustomerRepository.deleteAll();
+
+
+ if (neo4jCustomerRepository.count() == 0)
+ {
+ // Neo4jCustomers
+ Collection<Neo4jCustomer> someNeo4jCustomers = generateSomeCustomers();
+ neo4jCustomerRepository.save(someNeo4jCustomers);
+ }
+
+ System.out.println();
+
+ System.out.println("Number of customers saved : " + neo4jCustomerRepository.count());
+
+
+ System.out.println("All customers:");
+ for (Neo4jCustomer customer : neo4jCustomerRepository.findAll()) {
+ System.out.println(customer);
+ }
+
+
+ }
+
+ public Neo4jCustomer createCustomer(String firstname, String lastname) {
+ return neo4jCustomerRepository.save(new Neo4jCustomer(firstname, lastname));
+ }
+
+
+ public ArrayList<Neo4jCustomer> generateSomeCustomers() {
+ ArrayList<Neo4jCustomer> someNeo4jCustomers = new ArrayList<Neo4jCustomer>();
+
+ // Customers
+ someNeo4jCustomers.add(createCustomer("Adam", "Bien"));
+ someNeo4jCustomers.add(createCustomer("Andres", "Almiray"));
+ someNeo4jCustomers.add(createCustomer("Ben", "Evans"));
+ someNeo4jCustomers.add(createCustomer("Bob", "Lee"));
+ someNeo4jCustomers.add(createCustomer("Chris", "Richardson"));
+ someNeo4jCustomers.add(createCustomer("Jasper", "Potts"));
+ someNeo4jCustomers.add(createCustomer("Jim", "Weaver"));
+ someNeo4jCustomers.add(createCustomer("Josh", "Long"));
+ someNeo4jCustomers.add(createCustomer("Kirk", "Pepperdine"));
+ someNeo4jCustomers.add(createCustomer("Martijn", "Verburg"));
+ someNeo4jCustomers.add(createCustomer("Richard", "Bair"));
+ someNeo4jCustomers.add(createCustomer("Stephen", "Chin"));
+ someNeo4jCustomers.add(createCustomer("Daniel", "Winges"));
+
+ // Relationships
+ someNeo4jCustomers.get(0).addFriend(someNeo4jCustomers.get(1));
+ someNeo4jCustomers.get(0).addFriend(someNeo4jCustomers.get(3));
+ someNeo4jCustomers.get(0).addFriend(someNeo4jCustomers.get(5));
+ someNeo4jCustomers.get(0).addFriend(someNeo4jCustomers.get(7));
+ someNeo4jCustomers.get(0).addFriend(someNeo4jCustomers.get(9));
+ someNeo4jCustomers.get(0).addFriend(someNeo4jCustomers.get(11));
+ someNeo4jCustomers.get(1).addFriend(someNeo4jCustomers.get(2));
+ someNeo4jCustomers.get(1).addFriend(someNeo4jCustomers.get(4));
+ someNeo4jCustomers.get(1).addFriend(someNeo4jCustomers.get(6));
+ someNeo4jCustomers.get(1).addFriend(someNeo4jCustomers.get(8));
+ someNeo4jCustomers.get(1).addFriend(someNeo4jCustomers.get(10));
+ someNeo4jCustomers.get(2).addFriend(someNeo4jCustomers.get(4));
+ someNeo4jCustomers.get(2).addFriend(someNeo4jCustomers.get(7));
+ someNeo4jCustomers.get(2).addFriend(someNeo4jCustomers.get(10));
+ someNeo4jCustomers.get(3).addFriend(someNeo4jCustomers.get(4));
+ someNeo4jCustomers.get(3).addFriend(someNeo4jCustomers.get(11));
+ someNeo4jCustomers.get(5).addFriend(someNeo4jCustomers.get(6));
+ someNeo4jCustomers.get(6).addFriend(someNeo4jCustomers.get(8));
+ someNeo4jCustomers.get(7).addFriend(someNeo4jCustomers.get(9));
+ someNeo4jCustomers.get(8).addFriend(someNeo4jCustomers.get(10));
+ someNeo4jCustomers.get(9).addFriend(someNeo4jCustomers.get(11));
+ someNeo4jCustomers.get(10).addFriend(someNeo4jCustomers.get(11));
+ someNeo4jCustomers.get(11).addFriend(someNeo4jCustomers.get(12));
+
+ return someNeo4jCustomers;
+ }
+
+}
View
116 src/main/java/com/comsysto/util/FXOptionPane.java
@@ -0,0 +1,116 @@
+package com.comsysto.util;
+
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Node;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.image.ImageView;
+import javafx.scene.layout.BorderPane;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import javafx.scene.text.Text;
+import javafx.stage.Modality;
+import javafx.stage.Stage;
+import javafx.stage.StageStyle;
+
+public class FXOptionPane {
+
+ public enum Response { NO, YES, CANCEL };
+
+ private static Response buttonSelected = Response.CANCEL;
+
+ private static ImageView icon = new ImageView();
+
+ static class Dialog extends Stage {
+ public Dialog( String title, Stage owner, Scene scene, String iconFile ) {
+ setTitle( title );
+ initStyle( StageStyle.UTILITY );
+ initModality( Modality.APPLICATION_MODAL );
+ initOwner( owner );
+ setResizable( false );
+ setScene( scene );
+ //icon.setImage( new Image( getClass().getResourceAsStream( iconFile ) ) );
+ }
+ public void showDialog() {
+ sizeToScene();
+ centerOnScreen();
+ showAndWait();
+ }
+ }
+
+ static class Message extends Text {
+ public Message( String msg ) {
+ super( msg );
+ setWrappingWidth( 250 );
+ }
+ }
+
+ public static Response showConfirmDialog( Stage owner, String message, String title ) {
+ VBox vb = new VBox();
+ Scene scene = new Scene( vb );
+ final Dialog dial = new Dialog( title, owner, scene, "" );
+ vb.setPadding( Layout.PADDING );
+ vb.setSpacing( Layout.SPACING );
+ Button yesButton = new Button( "Yes" );
+ yesButton.setOnAction( new EventHandler<ActionEvent>() {
+ @Override public void handle( ActionEvent e ) {
+ dial.close();
+ buttonSelected = Response.YES;
+ }
+ } );
+ Button noButton = new Button( "No" );
+ noButton.setOnAction( new EventHandler<ActionEvent>() {
+ @Override public void handle( ActionEvent e ) {
+ dial.close();
+ buttonSelected = Response.NO;
+ }
+ } );
+ BorderPane bp = new BorderPane();
+ HBox buttons = new HBox();
+ buttons.setAlignment( Pos.CENTER );
+ buttons.setSpacing( Layout.SPACING );
+ buttons.getChildren().addAll( yesButton, noButton );
+ bp.setCenter( buttons );
+ HBox msg = new HBox();
+ //msg.setSpacing( Layout.SPACING_SMALL );
+ msg.getChildren().addAll( icon, new Message( message ) );
+ vb.getChildren().addAll( msg, bp );
+ dial.showDialog();
+ return buttonSelected;
+ }
+
+ public static void showMessageDialog( Stage owner, String message, String title ) {
+ showMessageDialog( owner, new Message( message ), title );
+ }
+ public static void showMessageDialog( Stage owner, Node message, String title ) {
+ VBox vb = new VBox();
+ Scene scene = new Scene( vb );
+ final Dialog dial = new Dialog( title, owner, scene, "" );
+ vb.setPadding( Layout.PADDING );
+ vb.setSpacing( Layout.SPACING );
+ Button okButton = new Button( "OK" );
+ okButton.setAlignment( Pos.CENTER );
+ okButton.setOnAction( new EventHandler<ActionEvent>() {
+ @Override public void handle( ActionEvent e ) {
+ dial.close();
+ }
+ } );
+ BorderPane bp = new BorderPane();
+ bp.setCenter( okButton );
+ HBox msg = new HBox();
+ msg.setSpacing(Layout.SPACING_SMALL );
+ msg.getChildren().addAll( icon, message );
+ vb.getChildren().addAll( msg, bp );
+ dial.showDialog();
+ }
+}
+
+class Layout
+{
+ public static Insets PADDING = new Insets(10);
+ public static double SPACING = 10;
+ public static double SPACING_SMALL = 5;
+}
View
628 src/main/java/com/comsysto/util/Neo4jTableBuilder.java
@@ -0,0 +1,628 @@
+package com.comsysto.util;
+
+import com.comsysto.ScreensConfiguration;
+import com.comsysto.neo4j.domain.Neo4jNode;
+import javafx.beans.InvalidationListener;
+import javafx.beans.Observable;
+import javafx.beans.property.ObjectProperty;
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+import javafx.geometry.Pos;
+import javafx.scene.control.*;
+import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.util.Callback;
+import javafx.util.StringConverter;
+import javafx.util.converter.DateTimeStringConverter;
+import javafx.util.converter.DefaultStringConverter;
+import javafx.util.converter.IntegerStringConverter;
+import org.springframework.data.neo4j.repository.GraphRepository;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+
+/** @author Elisabeth Engel */
+public class Neo4jTableBuilder <T extends Neo4jNode> {
+
+ private Class<T> tableClass;
+
+ private GraphRepository tableRepository;
+
+ private TableView<T> tableView;
+
+ private ObservableList<T> data;
+
+ private T newNode;
+
+ private class Neo4jTableColumn implements Comparable<Neo4jTableColumn> {
+ private TableColumn tableColumn;
+ private int columnOrder;
+
+ public Neo4jTableColumn(TableColumn tableColumn, int columnOrder) {
+ this.tableColumn = tableColumn;
+ this.columnOrder = columnOrder;
+ }
+
+ public TableColumn getTableColumn() {
+ return tableColumn;
+ }
+
+ public int getColumnOrder() {
+ return columnOrder;
+ }
+
+ public void setColumnOrder(int columnOrder) {
+ this.columnOrder = columnOrder;
+ }
+
+ @Override
+ public int compareTo(Neo4jTableColumn o) {
+ return (this.columnOrder < o.columnOrder ) ? -1: (this.columnOrder > o.columnOrder) ? 1:0 ;
+ }
+ }
+
+ private class SortTypeChangeListener implements InvalidationListener {
+
+ @Override
+ public void invalidated(Observable o) {
+ if (o instanceof ObjectProperty) {
+ ObjectProperty objectProperty = (ObjectProperty)o;
+ if (objectProperty.getValue().equals(TableColumn.SortType.DESCENDING)) {
+ // only ascending order -> workaround
+ ObservableList<TableColumn<T, ?>> newSortOrder = FXCollections.observableArrayList();
+ /*
+ ObservableList<TableColumn<T, ?>> sortOrder = tableView.getSortOrder();
+ for(TableColumn column : sortOrder) {
+ newSortOrder.add(column);
+ }
+ */
+ tableView.getSortOrder().setAll(newSortOrder);
+
+ }
+ }
+ }
+ }
+
+ //@Autowired
+ //private FXMLDialog customerErrorDialog;
+
+ /** automatically generates a tableView to add, edit and remove the neo4j tableRepository fields annotated
+ * with @Neo4jTableBuilderColumnField.
+ *
+ * @param tableClass The class of the table items.
+ * @param tableRepository The repository for the table items.
+ * @param tableView The tableView that shows the table items.
+ */
+ public Neo4jTableBuilder(Class<T> tableClass, GraphRepository tableRepository, TableView<T> tableView) {
+
+ this.tableClass = tableClass;
+ this.tableRepository = tableRepository;
+ this.tableView = tableView;
+ }
+
+ /** initializes the neo4j table
+ *
+ */
+ public void initDataTable ()
+ {
+ // collect all tableColumns
+ ArrayList<Neo4jTableColumn> tableColumns = new ArrayList<Neo4jTableColumn>();
+ tableColumns.addAll(createDataColumnsFromAnnotatedFields());
+ tableColumns.addAll(createDataColumnsFromAnnotatedMethods());
+
+ // sort
+ Collections.sort(tableColumns);
+
+ // add them to tableView
+ for (Neo4jTableColumn tableColumn : tableColumns) {
+ tableView.getColumns().add(tableColumn.getTableColumn());
+ }
+
+ // last column with save or delete botton
+ TableColumn lastColumn = new TableColumn<Neo4jNode, String>();
+ lastColumn.setMinWidth(80);
+ lastColumn.setEditable(false);
+ lastColumn.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Neo4jNode, String>, ObservableValue<String>>() {
+ public ObservableValue<String> call(TableColumn.CellDataFeatures<Neo4jNode, String> p) {
+ if (!p.getValue().isSaved()){
+ return new SimpleStringProperty("saveButton");
+ }
+ return new SimpleStringProperty("deleteButton");
+ }
+ });
+ lastColumn.setCellFactory(new Callback<TableColumn<Neo4jNode, String>, TableCell<Neo4jNode, String>>() {
+
+ public TableCell<Neo4jNode, String> call(TableColumn<Neo4jNode, String> p) {
+ TableCell returnTableCell;
+
+ //System.out.println("item 0:"+Neo4jTableBuilder.this.tableView.getItems().get(0));
+
+ returnTableCell = new ButtonTableCell<Neo4jNode, String>();
+
+ return returnTableCell;
+ }
+ });
+ tableView.getColumns().add(lastColumn);
+
+ //listen to sorting type (ASC/DESC) change
+ lastColumn.sortTypeProperty().addListener(new SortTypeChangeListener());
+
+ //listen to sortorder change
+ tableView.getSortOrder().addListener(new ListChangeListener<TableColumn<T, ?>>() {
+ @Override
+ public void onChanged(Change<? extends TableColumn<T, ?>> change) {
+ /*
+ if (change.getList().size() > 0) {
+ System.out.println("getSortOrder - onChanged - column: " + change.getList().get(0).getSortType());
+ } else {
+ System.out.println("getSortOrder - onChanged - empty list");
+ }
+ */
+ resetTableData();
+ }
+ });
+
+ }
+
+ /** creates all TableColumns from the anntotated fields
+ *
+ * @return ArrayList with all Neo4jTableColumns
+ */
+ private ArrayList<Neo4jTableColumn> createDataColumnsFromAnnotatedFields() {
+
+ ArrayList<Neo4jTableColumn> tableColumns = new ArrayList<Neo4jTableColumn>();
+
+ // find annotated fields
+ Field[] fields = tableClass.getDeclaredFields();
+ for (final Field field : fields) {
+
+ field.setAccessible(true);
+
+ Neo4jTableBuilderColumnField annotation = field.getAnnotation(Neo4jTableBuilderColumnField.class);
+
+ if (annotation != null)
+ {
+ final TableColumn newColumn;
+ final String name = field.getName();
+ final String columnName = (!annotation.columnName().equals("")) ? annotation.columnName() : field.getName();
+ newColumn = new TableColumn(columnName);
+ //listen to sorting type (ASC/DESC) change
+ newColumn.sortTypeProperty().addListener(new SortTypeChangeListener());
+ newColumn.setMinWidth(columnName.length()*14);
+
+ if (annotation.columnType() == Neo4jTableBuilderColumnField.FieldType.readAndWrite)
+ {
+ createAndSetFactories(newColumn, name, field.getType());
+
+ newColumn.setOnEditCommit(
+ new EventHandler<TableColumn.CellEditEvent<Neo4jNode, String>>() {
+ @Override
+ public void handle(TableColumn.CellEditEvent<Neo4jNode, String> t) {
+ Neo4jNode neo4jNode = t.getTableView().getItems().get(t.getTablePosition().getRow());
+
+ try {
+ field.set(neo4jNode, t.getNewValue());
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+
+ if (t.getTablePosition().getRow() != 0) {
+ tableRepository.save(neo4jNode);
+ }
+
+ //System.out.println("EventHandler handle: "+neo4jNode.toString());
+ }
+ }
+ );
+
+ }
+ else {
+ // readonly field
+ newColumn.setCellValueFactory(new PropertyValueFactory<Neo4jNode, String>(name));
+
+ Callback<TableColumn, TableCell> cellFactory =
+ new Callback<TableColumn, TableCell>() {
+ public TableCell call(TableColumn p) {
+ return new NormalCell<String>();
+
+ }
+ };
+
+ newColumn.setCellFactory(cellFactory);
+ }
+
+ tableColumns.add(new Neo4jTableColumn(newColumn, annotation.columnOrder()));
+ }
+ }
+ return tableColumns;
+ }
+
+ /** creates all TableColumns from the annotated set methods
+ *
+ * @return ArrayList with all Neo4jTableColumns
+ */
+ private ArrayList<Neo4jTableColumn> createDataColumnsFromAnnotatedMethods() {
+
+ ArrayList<Neo4jTableColumn> tableColumns = new ArrayList<Neo4jTableColumn>();
+
+ // find annotated methods
+ Method[] methods = tableClass.getDeclaredMethods();
+ for (final Method method : methods) {
+
+ method.setAccessible(true);
+
+ Neo4jTableBuilderColumnSetMethod annotation = method.getAnnotation(Neo4jTableBuilderColumnSetMethod.class);
+
+ if (annotation != null & method.getName().startsWith("set")) {
+ final TableColumn newColumn;
+ final String name = method.getName().substring(3).toLowerCase();
+ final String columnName = (!annotation.columnName().equals("")) ? annotation.columnName() : method.getName().substring(3);
+ newColumn = new TableColumn(columnName);
+ //listen to sorting type (ASC/DESC) change
+ newColumn.sortTypeProperty().addListener(new SortTypeChangeListener());
+ newColumn.setMinWidth(columnName.length()*14);
+
+ createAndSetFactories(newColumn, name, method.getParameterTypes()[0]);
+
+ newColumn.setOnEditCommit(
+ new EventHandler<TableColumn.CellEditEvent<Neo4jNode, String>>() {
+ @Override
+ public void handle(TableColumn.CellEditEvent<Neo4jNode, String> t) {
+ Neo4jNode neo4jNode = t.getTableView().getItems().get(t.getTablePosition().getRow());
+
+ try {
+ method.invoke(neo4jNode, t.getNewValue());
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ }
+
+ if (t.getTablePosition().getRow() != 0) {
+ tableRepository.save(neo4jNode);
+ }
+
+ //System.out.println("EventHandler handle: "+neo4jNode.toString());
+ }
+ }
+ );
+
+ tableColumns.add(new Neo4jTableColumn(newColumn, annotation.columnOrder()));
+ }
+ }
+
+ return tableColumns;
+ }
+
+
+ private void createAndSetFactories(TableColumn newColumn, String name, Class parameterClass) {
+
+
+ Callback<TableColumn, TableCell> cellFactory;
+ if (parameterClass == Integer.class)
+ {
+ newColumn.setCellValueFactory(new PropertyValueFactory<Neo4jNode, Integer>(name));
+
+ cellFactory =
+ new Callback<TableColumn, TableCell>() {
+ public TableCell call(TableColumn p) {
+ return new EditingCell<Integer>(new IntegerStringConverter());
+ }
+ };
+ }
+ else if (parameterClass == Date.class)
+ {
+ newColumn.setCellValueFactory(new PropertyValueFactory<Neo4jNode, Date>(name));
+
+
+ final SimpleDateFormat sdfToDate = new SimpleDateFormat("dd.MM.yyyy");
+
+ cellFactory =
+ new Callback<TableColumn, TableCell>() {
+ public TableCell call(TableColumn p) {
+ return new EditingCell<Date>(new DateTimeStringConverter(sdfToDate));
+ }
+ };
+ }
+ else {
+
+ newColumn.setCellValueFactory(new PropertyValueFactory<Neo4jNode, String>(name));
+
+
+ cellFactory =
+ new Callback<TableColumn, TableCell>() {
+ public TableCell call(TableColumn p) {
+ return new EditingCell<String>(new DefaultStringConverter());
+
+ }
+ };
+
+ }
+
+ newColumn.setCellFactory(cellFactory);
+
+ }
+
+ private void resetTableData () {
+
+ data.remove(newNode);
+ data.add(0, newNode);
+
+ }
+
+ /** removes all old neo4j and inserts the new neo4j from the result parameter
+ *
+ * @param result All items that shall be shown in the table.
+ */
+ public void setTableData(Iterable<T> result)
+ {
+ tableView.getItems().removeAll();
+
+ data = FXCollections.observableArrayList();
+ this.newNode = createNewNode();
+ data.add(newNode);
+
+ for (T item : result) {
+ data.add(item);
+ }
+
+ tableView.setItems(data);
+
+ }
+
+ /** creates a new neo4j node that can be editted and afterwards stored
+ *
+ * @return new neo4j node
+ */
+ private T createNewNode () {
+ try {
+ return tableClass.newInstance();
+ } catch (InstantiationException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+
+ /** This class is for TableCells with no editing functionality
+ *
+ * @param <T>
+ */
+ private class NormalCell<T> extends TableCell<Neo4jNode, T> {
+
+
+ /** constructs the NormalCell
+ *
+ */
+ public NormalCell() {
+ }
+
+ @Override
+ public void updateItem(T item, boolean empty) {
+ super.updateItem(item, empty);
+
+ setText(getString());
+
+ // for the new column
+ //if(getIndex()==(tableView.getItems().size()-1)){
+ if (getIndex() == 0) {
+ this.getStyleClass().add("table-row-cell-new");
+ }
+ }
+
+
+ /** if the item isn't null the item is converted to String and returned
+ *
+ * @return The String value of the item.
+ */
+ private String getString() {
+ return getItem() == null ? "" : getItem().toString();
+ }
+ }
+
+
+ /** This class is for TableCells that can be editted.
+ *
+ * @param <T>
+ */
+ private class EditingCell<T> extends TableCell<Neo4jNode, T> {
+
+ private TextField textField;
+
+ private StringConverter<T> stringConverter;
+
+ private T beforeValue;
+
+ /** constructs the EditingCell with the stringConverter
+ *
+ * @param stringConverter The StringConverter for this cell.
+ */
+ public EditingCell(StringConverter<T> stringConverter) {
+ this.stringConverter = stringConverter;
+ }
+
+ @Override
+ public void startEdit() {
+ if (!isEmpty()) {
+ super.startEdit();
+ turnToEditMode();
+ }
+
+ }
+
+ /** changes the field to be editable
+ *
+ */
+ private void turnToEditMode() {
+ createTextField();
+ setText(null);
+ setGraphic(textField);
+ textField.selectAll();
+ }
+
+ @Override
+ public void cancelEdit() {
+ super.cancelEdit();
+
+ setText(getItem().toString());
+ setGraphic(null);
+ }
+
+ @Override
+ public void updateItem(T item, boolean empty) {
+ super.updateItem(item, empty);
+
+ if (empty) {
+ setText(null);
+ setGraphic(null);
+ } else {
+ if (isEditing()) {
+ if (textField != null) {
+ textField.setText(getString());
+ }
+ setText(null);
+ setGraphic(textField);
+ } else {
+ setText(getString());
+ setGraphic(null);
+ }
+ }
+ // for the new column
+ //if(getIndex()==(tableView.getItems().size()-1)){
+ if (getIndex() == 0) {
+ this.getStyleClass().add("table-row-cell-new");
+ turnToEditMode();
+ textField.setPrefWidth(getString().length());
+ }
+ }
+
+
+ /** creates a text field with a minWidth that can react to changes by commiting them
+ *
+ */
+ private void createTextField() {
+ beforeValue = getItem();
+ textField = new TextField(getString());
+ textField.setMinWidth(this.getWidth() - this.getGraphicTextGap()* 2);
+ textField.focusedProperty().addListener(new ChangeListener<Boolean>(){
+ @Override
+ public void changed(ObservableValue<? extends Boolean> arg0,
+ Boolean arg1, Boolean arg2) {
+ if (!arg2) {
+ T newValue;
+ try {
+ newValue = stringConverter.fromString(textField.getText());
+ }
+ catch (RuntimeException e) {
+ newValue = beforeValue;
+ }
+
+ getTableView().edit(EditingCell.this.getIndex(), getTableColumn());
+ commitEdit(newValue);
+ }
+ }
+ });
+ }
+
+ /** if the item isn't null the item is converted to String and returned
+ *
+ * @return The String value of the item.
+ */
+ private String getString() {
+ return getItem() == null ? "" : stringConverter.toString(getItem());
+ }
+ }
+
+ /** This class is for TableCells that consist of a Save or Delete button
+ *
+ * @param <S>
+ * @param <T> The type of the item contained within the Cell.
+ */
+ private class ButtonTableCell<S, T> extends TableCell<S, T> {
+ private Button button;
+ //private ObservableValue<T> observableValue;
+
+ /** constructs the ButtonTableCell
+ */
+ public ButtonTableCell() {
+
+ }
+
+ @Override
+ public void updateItem(T item, boolean empty) {
+ super.updateItem(item, empty);
+
+ if (empty) {
+ setText(null);
+ setGraphic(null);
+ } else {
+ if (item.toString().equals("saveButton")) {
+ button = new Button("Save");
+ button.setStyle("-fx-base: green;");
+ button.setAlignment(Pos.CENTER);
+ button.setOnAction(new EventHandler<ActionEvent>() {
+ @Override
+ public void handle(ActionEvent t) {
+ int i = getIndex();
+
+ Neo4jNode neo4jNode = tableView.getItems().get(i);
+
+ //System.out.println("save neo4jnode: "+neo4jNode.toString());
+
+ tableRepository.save(neo4jNode);
+
+ ButtonTableCell.this.updateTableView(getTableView());
+
+ data.add(tableView.getItems().get(i));
+
+ // new node
+ newNode = createNewNode();
+ data.set(0, newNode);
+ }
+ });
+ this.getStyleClass().add("table-row-cell-new");
+ }
+ else {
+ button = new Button("X");
+ button.setStyle("-fx-base: red;");
+ button.setAlignment(Pos.CENTER);
+ button.setOnAction(new EventHandler<ActionEvent>() {
+ @Override
+ public void handle(ActionEvent t) {
+ int i = getIndex();
+
+ Neo4jNode neo4jNode = tableView.getItems().get(i);
+
+ FXOptionPane.Response response = FXOptionPane.showConfirmDialog(ScreensConfiguration.getPrimaryStage(), "Are you sure you want to delete this entry?", "Confirm Delete");
+
+ if (response == FXOptionPane.Response.YES) {
+ tableRepository.delete(neo4jNode);
+ data.remove(neo4jNode);
+ }
+ }
+ });
+ this.getStyleClass().remove("table-row-cell-new");
+ }
+ setAlignment(Pos.CENTER);
+ setGraphic(button);
+ }
+ }
+ }
+
+}
+
+
+
+
View
23 src/main/java/com/comsysto/util/Neo4jTableBuilderColumnField.java
@@ -0,0 +1,23 @@
+package com.comsysto.util;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** @author Elisabeth Engel */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Neo4jTableBuilderColumnField {
+
+ FieldType columnType() default FieldType.readAndWrite;
+
+ String columnName() default "";
+
+ int columnOrder() default 10;
+
+ public enum FieldType {
+ readAndWrite, readOnly
+ }
+
+}
View
17 src/main/java/com/comsysto/util/Neo4jTableBuilderColumnSetMethod.java
@@ -0,0 +1,17 @@
+package com.comsysto.util;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** @author Elisabeth Engel */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Neo4jTableBuilderColumnSetMethod {
+
+ String columnName() default "";
+
+ int columnOrder() default 10;
+
+}
View
40 src/main/resources/com/comsysto/About.fxml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import java.lang.*?>
+<?import java.net.*?>
+<?import java.util.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.image.*?>
+<?import javafx.scene.layout.*?>
+<?import javafx.scene.paint.*?>
+<?import javafx.scene.text.*?>
+<?scenebuilder-stylesheet style.css?>
+
+<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="169.0" prefWidth="479.0" xmlns:fx="http://javafx.com/fxml" fx:controller="com.comsysto.StandardController">
+ <children>
+ <Label alignment="TOP_LEFT" layoutX="14.0" layoutY="50.0" prefHeight="22.0" prefWidth="449.0" text="This is the comSysto Spring Data Neo4j JavaFX TableView Demo." wrapText="true" />
+ <Button defaultButton="true" layoutX="400.0" layoutY="136.0" mnemonicParsing="false" onAction="#close" prefWidth="63.0" style="" text="OK" />
+ <ImageView fitHeight="41.0000114440918" fitWidth="312.7015751737502" layoutX="0.0" layoutY="-1.0" pickOnBounds="true" preserveRatio="true">
+ <image>
+ <Image url="@img/simple_header.jpg" />
+ </image>
+ </ImageView>
+ <ImageView fitHeight="41.0000114440918" fitWidth="312.7015751737502" layoutX="240.0" layoutY="-1.0" pickOnBounds="true" preserveRatio="true">
+ <image>
+ <Image url="@img/simple_header.jpg" />
+ </image>
+ </ImageView>
+ <Label layoutX="14.0" layoutY="3.0" prefWidth="198.0" text="ABOUT" textFill="#292929">
+ <font>
+ <Font size="28.0" />
+ </font>
+ </Label>
+ <Hyperlink layoutX="139.0" layoutY="76.0" onAction="#email" text="Elisabeth.Engel@comsysto.com" />
+ <Label alignment="TOP_LEFT" layoutX="14.0" layoutY="108.0" prefHeight="41.0" prefWidth="371.0" text="Enjoy!" wrapText="true" />
+ <Label alignment="TOP_LEFT" layoutX="14.0" layoutY="79.0" prefHeight="22.0" prefWidth="129.0" text="For details contact " wrapText="true" />
+ <Label alignment="TOP_LEFT" layoutX="14.0" layoutY="139.0" prefHeight="22.0" prefWidth="371.0" text="© comSysto GmbH" wrapText="true" />
+ </children>
+ <stylesheets>
+ <URL value="@style.css" />
+ </stylesheets>
+</AnchorPane>
View
53 src/main/resources/com/comsysto/Main.fxml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import java.lang.*?>
+<?import java.net.*?>
+<?import java.util.*?>
+<?import javafx.collections.*?>
+<?import javafx.geometry.*?>
+<?import javafx.scene.chart.*?>
+<?import javafx.scene.control.*?>
+<?import javafx.scene.image.*?>
+<?import javafx.scene.layout.*?>
+<?import javafx.scene.paint.*?>
+<?import javafx.scene.shape.*?>
+<?import javafx.scene.text.*?>
+<?import javafx.scene.web.*?>
+<?scenebuilder-stylesheet style.css?>
+
+<VBox fx:id="main_vbox" prefHeight="750.0" prefWidth="1000.0" xmlns:fx="http://javafx.com/fxml" fx:controller="com.comsysto.MainController">
+ <children>
+ <MenuBar fx:id="main_menubar" VBox.vgrow="NEVER">
+ <menus>
+ <Menu mnemonicParsing="false" text="File" fx:id="file_menu">
+ <items>
+ <MenuItem mnemonicParsing="false" onAction="#quit" text="Quit" fx:id="file_quit_menuitem" />
+ </items>
+ </Menu>
+ <Menu mnemonicParsing="false" text="Help" fx:id="help_menu">
+ <items>
+ <MenuItem mnemonicParsing="false" onAction="#about" text="About" fx:id="about_menuitem" />
+ </items>
+ </Menu>
+ </menus>
+ </MenuBar>
+ <VBox id="VBox" fx:id="main_data_vbox" alignment="TOP_LEFT" disable="false" snapToPixel="true" spacing="0.0">
+ <children>
+ <ToolBar fx:id="main_data_toolbar" prefWidth="435.0" VBox.vgrow="ALWAYS">
+ <items>
+ <TextField fx:id="main_data_toolbar_search_textfield" onKeyReleased="#searchTextfieldKeyReleased" prefWidth="200.0" promptText="Search Names" />
+ </items>
+ </ToolBar>
+ <AnchorPane id="AnchorPane" fx:id="main_data_table_anchorpane" prefHeight="-1.0" prefWidth="-1.0">
+ <children>
+ <TableView id="menu_data_tableview" fx:id="menu_data_customers_tableview" editable="true" prefHeight="833.0" prefWidth="817.0" visible="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
+ <stylesheets>
+ <URL value="@style.css" />
+ </stylesheets>
+ </TableView>
+ </children>
+ </AnchorPane>
+ </children>
+ </VBox>
+ </children>
+</VBox>
View
BIN  src/main/resources/com/comsysto/img/simple_header.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
23 src/main/resources/com/comsysto/style.css
@@ -0,0 +1,23 @@
+{
+ -fx-color: #292929;
+}
+
+.line {
+ -fx-background-color: #292929;
+ -fx-height: 1px;
+ -fx-fill: #292929;
+}
+
+.table-row-cell-new {
+ -fx-margin: 0 0 0 0;
+ -fx-border-width: 1px;
+ -fx-background-color: lightgreen;
+}
+
+.table-row-cell:empty {
+ -fx-background-color: white;
+}
+
+.table-row-cell:empty .table-cell {
+ -fx-border-width: 0px;
+}
Please sign in to comment.
Something went wrong with that request. Please try again.