Java tutorial
/** * Copyright (C) 2009 - 2014 Envidatec GmbH <info@envidatec.com> * * This file is part of JEConfig. * * JEConfig is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation in version 3. * * JEConfig is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * JEConfig. If not, see <http://www.gnu.org/licenses/>. * * JEConfig is part of the OpenJEVis project, further project information are * published at <http://www.OpenJEVis.org/>. */ package org.jevis.jeconfig.plugin.classes; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.EventHandler; import javafx.scene.control.SelectionMode; import javafx.scene.control.TreeCell; import javafx.scene.control.TreeItem; import javafx.scene.control.TreeView; import javafx.scene.input.ClipboardContent; import javafx.scene.input.DataFormat; import javafx.scene.input.DragEvent; import javafx.scene.input.Dragboard; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseEvent; import javafx.scene.input.TransferMode; import javafx.stage.FileChooser; import javafx.stage.FileChooser.ExtensionFilter; import javafx.util.Callback; import org.apache.commons.io.FilenameUtils; import org.jevis.api.JEVisClass; import org.jevis.api.JEVisClassRelationship; import org.jevis.api.JEVisConstants; import org.jevis.api.JEVisDataSource; import org.jevis.api.JEVisException; import org.jevis.application.dialog.ConfirmDialog; import org.jevis.commons.drivermanagment.ClassExporter; import org.jevis.commons.relationship.RelationshipFactory; import org.jevis.jeconfig.JEConfig; import org.jevis.jeconfig.plugin.classes.editor.ClassEditor; import org.jevis.jeconfig.tool.NewClassDialog; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; /** * * @author Florian Simon <florian.simon@envidatec.com> */ public class ClassTree extends TreeView<JEVisClass> { private ClassEditor _editor = new ClassEditor(); private boolean _editable = false; private JEVisDataSource _ds; private HashMap<String, TreeItem<JEVisClass>> _itemCache; private HashMap<String, ClassGraphic> _graphicCache; private HashMap<TreeItem<JEVisClass>, ObservableList<TreeItem<JEVisClass>>> _itemChildren; private JEVisClass _dragClass; public ClassTree() { } public ClassTree(JEVisDataSource ds) { super(); try { _ds = ds; _itemCache = new HashMap<>(); _graphicCache = new HashMap<>(); _itemChildren = new HashMap<>(); JEVisClass root = new JEVisRootClass(ds); TreeItem<JEVisClass> rootItem = buildItem(root); setShowRoot(true); rootItem.setExpanded(true); getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); _editor.setTreeView(this); setCellFactory(new Callback<TreeView<JEVisClass>, TreeCell<JEVisClass>>() { // @Override // public TreeCell<JEVisClass> call(TreeView<JEVisClass> p) { // return new ClassCell(); // } @Override public TreeCell<JEVisClass> call(TreeView<JEVisClass> param) { return new TreeCell<JEVisClass>() { // private ImageView imageView = new ImageView(); @Override protected void updateItem(JEVisClass item, boolean empty) { super.updateItem(item, empty); if (!empty) { ClassGraphic gc = getClassGraphic(item); setContextMenu(gc.getContexMenu()); // setText(item); setGraphic(gc.getGraphic()); } else { setText(null); setGraphic(null); } } }; } }); getSelectionModel().selectedItemProperty().addListener(new ChangeListener<TreeItem<JEVisClass>>() { @Override public void changed(ObservableValue<? extends TreeItem<JEVisClass>> ov, TreeItem<JEVisClass> t, TreeItem<JEVisClass> t1) { try { if (t1 != null) { _editor.setJEVisClass(t1.getValue()); } } catch (Exception ex) { System.out.println("Error while changing editor: " + ex); } } }); addEventHandler(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() { @Override public void handle(KeyEvent t) { if (t.getCode() == KeyCode.F2) { System.out.println("F2 rename event"); Platform.runLater(new Runnable() { @Override public void run() { fireEventRename(); } }); } else if (t.getCode() == KeyCode.DELETE) { fireDelete(getSelectionModel().getSelectedItem().getValue()); } } }); setId("objecttree"); getStylesheets().add("/styles/Styles.css"); setPrefWidth(500); setRoot(rootItem); setEditable(true); } catch (Exception ex) { // Logger.getLogger(ObjectTree.class.getName()).log(Level.SEVERE, null, ex); ex.printStackTrace(); } } public TreeItem<JEVisClass> buildItem(JEVisClass object) { if (object != null) { try { if (_itemCache.containsKey(object.getName())) { return _itemCache.get(object.getName()); } final TreeItem<JEVisClass> newItem = new ClassItem(object, this); _itemCache.put(object.getName(), newItem); return newItem; } catch (JEVisException ex) { Logger.getLogger(ClassTree.class.getName()).log(Level.SEVERE, null, ex); ex.printStackTrace(); } } return null; } public TreeItem<JEVisClass> getObjectTreeItem(JEVisClass object) { return buildItem(object); } public void addChildrenList(TreeItem<JEVisClass> item, ObservableList<TreeItem<JEVisClass>> list) { _itemChildren.put(item, list); try { // System.out.println("\nchildren for: " + item.getValue().getName()); for (JEVisClass child : item.getValue().getHeirs()) { // System.out.println(" posible heir: " + child.getName()); if (item.getValue().getName().equals("Classes")) { TreeItem<JEVisClass> newItem = buildItem(child); list.add(newItem); // } else if (child.getInheritance() != null && item.getValue().getName().equals(child.getInheritance().getName())) } else if (child.getInheritance() != null && item.getValue().equals(child.getInheritance())) {// && child.getInheritance().equals(item.getValue())) { // System.out.println(" is direct heir: " + child.getInheritance()); TreeItem<JEVisClass> newItem = buildItem(child); list.add(newItem); } // for (JEVisClassRelationship rel : child.getRelationships(JEVisConstants.ClassRelationship.INHERIT, JEVisConstants.Direction.FORWARD)) { // System.out.println("rel: " + rel); // if (rel.getOtherClass(item.getValue().getInheritance())) { // System.out.println("from: " +); // } else { // System.out.println("to"); // } // } } } catch (JEVisException ex) { Logger.getLogger(ClassTree.class.getName()).log(Level.SEVERE, null, ex); } // sortList(list); } private void getAllExpanded(List<TreeItem<JEVisClass>> list, TreeItem<JEVisClass> item) { if (item.isExpanded()) { list.add(item); for (TreeItem<JEVisClass> i : item.getChildren()) { getAllExpanded(list, i); } } } private void expandAll(List<TreeItem<JEVisClass>> list, TreeItem<JEVisClass> root) { // System.out.println("expand all"); for (final TreeItem<JEVisClass> item : root.getChildren()) { for (final TreeItem<JEVisClass> child : list) { try { if (item.getValue().getName().equals(child.getValue().getName())) { Platform.runLater(new Runnable() { @Override public void run() { item.setExpanded(true); } }); } } catch (JEVisException ex) { ex.printStackTrace(); } } expandAll(list, item); } } public void reload(JEVisClass jclass) { if (jclass != null) { TreeItem newItem = buildItem(jclass); newItem.expandedProperty().setValue(false); newItem.expandedProperty().setValue(true); } } public ObservableList<TreeItem<JEVisClass>> getChildrenList(TreeItem<JEVisClass> item) { if (item == null || item.getValue() == null) { return FXCollections.emptyObservableList(); } if (_itemChildren.containsKey(item)) { return _itemChildren.get(item); } ObservableList<TreeItem<JEVisClass>> list = FXCollections.observableArrayList(); try { for (JEVisClass child : item.getValue().getHeirs()) { TreeItem<JEVisClass> newItem = buildItem(child); list.add(newItem); } } catch (JEVisException ex) { Logger.getLogger(ClassTree.class.getName()).log(Level.SEVERE, null, ex); } // sortList(list); _itemChildren.put(item, list); return list; } private void expand(TreeItem<JEVisClass> item, boolean expand) { if (!item.isLeaf()) { if (item.isExpanded() && !expand) { item.setExpanded(expand); } else if (!item.isExpanded() && expand) { item.setExpanded(expand); } for (TreeItem<JEVisClass> child : item.getChildren()) { expand(child, expand); } } } public void fireEventRename() { System.out.println("fireRename"); // edit(_cl.getCurrentItem()); } public void fireSaveAttributes(boolean ask) throws JEVisException { // TreeItem<JEVisClass> selectedItem = getSelectionModel().getSelectedItem(); // getSelectionModel().getSelectedItem().getParent().setExpanded(false); if (ask) { _editor.checkIfSaved(null); } else { _editor.commitAll(); //TODO: replace this dump way of refeshing // } // getSelectionModel().getSelectedItem().setExpanded(true); // getSelectionModel().getSelectedItem().getParent().setExpanded(true); // getSelectionModel().select(selectedItem); } public void fireDelete(JEVisClass jclass) { System.out.println("delete event"); if (jclass == null) { jclass = getSelectionModel().getSelectedItem().getValue(); } if (jclass != null) { try { ConfirmDialog dia = new ConfirmDialog(); String question = "Do you want to delete the Class \"" + jclass.getName() + "\" ?"; if (dia.show(JEConfig.getStage(), "Delete Class", "Delete Class?", question) == ConfirmDialog.Response.YES) { try { System.out.println("User want to delete: " + jclass.getName()); if (jclass.getInheritance() != null) { for (JEVisClassRelationship rel : jclass .getRelationships(JEVisConstants.ClassRelationship.INHERIT)) { jclass.deleteRelationship(rel); } } final TreeItem<JEVisClass> item = getObjectTreeItem(jclass); final TreeItem<JEVisClass> parentItem = item.getParent(); jclass.delete(); deteleItemFromTree(item); // Platform.runLater(new Runnable() { // @Override // public void run() { // parentItem.getChildren().remove(item); // getSelectionModel().select(parentItem); // parentItem.setExpanded(false); // // } // }); } catch (Exception ex) { ex.printStackTrace(); } } } catch (JEVisException ex) { Logger.getLogger(ClassTree.class.getName()).log(Level.SEVERE, null, ex); } } } private void deteleItemFromTree(final TreeItem<JEVisClass> item) { try { Platform.runLater(new Runnable() { @Override public void run() { try { String className = item.getValue().getName(); _itemCache.remove(className); for (Map.Entry<TreeItem<JEVisClass>, ObservableList<TreeItem<JEVisClass>>> entry : _itemChildren .entrySet()) { if (entry.getValue().contains(item)) { entry.getValue().remove(item); } } getSelectionModel().select(item.getParent()); if (_graphicCache.containsKey(className)) { _graphicCache.remove(className); } // parentItem.setExpanded(false); } catch (JEVisException ex) { Logger.getLogger(ClassTree.class.getName()).log(Level.SEVERE, null, ex); } } }); } catch (Exception ex) { ex.printStackTrace(); } } public void fireEventExport(ObservableList<TreeItem<JEVisClass>> items) { FileChooser fileChooser = new FileChooser(); fileChooser.setTitle("Save JEVisClasses to File"); fileChooser.getExtensionFilters().addAll(new ExtensionFilter("JEVis Files", "*.jev"), new ExtensionFilter("All Files", "*.*")); DateTime now = DateTime.now(); DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyyMMdd"); if (items.size() > 1) { fileChooser.setInitialFileName("JEViClassExport_" + fmt.print(now) + ".jev"); } else { try { fileChooser.setInitialFileName(items.get(0).getValue().getName() + "_" + fmt.print(now) + ".jev"); } catch (JEVisException ex) { Logger.getLogger(ClassTree.class.getName()).log(Level.SEVERE, null, ex); } } File selectedFile = fileChooser.showSaveDialog(JEConfig.getStage()); if (selectedFile != null) { List<JEVisClass> classes = new ArrayList<>(); for (TreeItem<JEVisClass> item : items) { classes.add(item.getValue()); } String extension = FilenameUtils.getExtension(selectedFile.getName()); if (extension.isEmpty()) { selectedFile = new File(selectedFile.getAbsoluteFile() + ".jsv"); } ClassExporter ce = new ClassExporter(selectedFile, classes); // mainStage.display(selectedFile); } } public void fireEventNew(TreeItem<JEVisClass> item) { try { NewClassDialog dia = new NewClassDialog(); JEVisClass currentClass = null; if (item != null) { currentClass = item.getValue(); } else if (item == null && getSelectionModel().getSelectedItem() != null) { currentClass = getSelectionModel().getSelectedItem().getValue(); } else if (currentClass != null && currentClass.getName().equals("Classes")) { currentClass = null; } if (currentClass != null && currentClass.getName().equals("Classes")) { currentClass = null; } if (dia.show(JEConfig.getStage(), currentClass, _ds) == NewClassDialog.Response.YES && dia.getClassName() != null && !dia.getClassName().equals("")) { JEVisClass newClass = _ds.buildClass(dia.getClassName()); if (dia.getInheritance() != null && newClass != null) { newClass.setIcon(dia.getInheritance().getIcon()); newClass.commit(); } final TreeItem<JEVisClass> treeItem = buildItem(newClass); if (dia.getInheritance() != null) { //reload workaround, loading the relationship befor creation ein will execute the getFixedRelationships() function newClass.getRelationships(); JEVisClassRelationship cr = RelationshipFactory.buildInheritance(dia.getInheritance(), newClass); // newClass = null; // newClass = _ds.getJEVisClass(dia.getClassName()); // System.out.println("fixfix: " + newClass.getName()); getChildrenList(getObjectTreeItem(dia.getInheritance())).add(getObjectTreeItem(newClass)); } else { getChildrenList(getObjectTreeItem(getRoot().getValue())).add(getObjectTreeItem(newClass)); } Platform.runLater(new Runnable() { @Override public void run() { getSelectionModel().select(treeItem); } }); } } catch (JEVisException ex) { ex.printStackTrace(); Logger.getLogger(ClassTree.class.getName()).log(Level.SEVERE, null, ex); } } //TODO i dont like this way public ClassEditor getEditor() { return _editor; } public ClassGraphic getClassGraphic(JEVisClass object) { try { if (_graphicCache.containsKey(object.getName())) { return _graphicCache.get(object.getName()); } // System.out.println("grahic does not exist create for: " + object); ClassGraphic graph = new ClassGraphic(object, this); _graphicCache.put(object.getName(), graph); return graph; } catch (JEVisException ex) { Logger.getLogger(ClassTree.class.getName()).log(Level.SEVERE, null, ex); } return null; } public JEVisClass getDragItem() { return _dragClass; } public void setDragItem(JEVisClass obj) { _dragClass = obj; } public class ClassCell extends TreeCell<JEVisClass> { @Override protected void updateItem(final JEVisClass obj, boolean emty) { super.updateItem(obj, emty); if (!emty) { ClassGraphic grph = getClassGraphic(obj); setText(grph.getText()); setGraphic(grph.getGraphic()); // setTooltip(grph.getToolTip()); setContextMenu(grph.getContexMenu()); //---------------------- Drag & Drop part -------------- setOnDragDetected(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent e) { try { System.out.println("Drag Source: " + obj.getName()); ClipboardContent content = new ClipboardContent(); // content.putString(obj.getName()); Dragboard dragBoard = startDragAndDrop(TransferMode.MOVE); content.put(DataFormat.PLAIN_TEXT, obj.getName()); dragBoard.setContent(content); setDragItem(obj); e.consume(); } catch (JEVisException ex) { Logger.getLogger(ClassTree.class.getName()).log(Level.SEVERE, null, ex); } } }); setOnDragDone(new EventHandler<DragEvent>() { @Override public void handle(DragEvent dragEvent) { try { System.out.println("Drag done on " + obj.getName()); dragEvent.consume(); } catch (JEVisException ex) { Logger.getLogger(ClassTree.class.getName()).log(Level.SEVERE, null, ex); } } }); //TODO: check if its ok to move the Object here setOnDragOver(new EventHandler<DragEvent>() { @Override public void handle(DragEvent dragEvent) { try { if (obj != null) { if (!obj.equals(getDragItem()) && !getDragItem().getHeirs().contains(obj)) { System.out.println("Drag Over: " + obj.getName()); dragEvent.acceptTransferModes(TransferMode.MOVE); } } else { // System.out.println("Drag Over NULL!!"); } dragEvent.consume(); } catch (JEVisException ex) { Logger.getLogger(ClassTree.class.getName()).log(Level.SEVERE, null, ex); } } }); setOnDragDropped(new EventHandler<DragEvent>() { @Override public void handle(DragEvent dragEvent) { try { System.out.println("\nDrag dropped on " + obj.getName()); System.out.println("To Drag: " + getDragItem().getName()); System.out.println( "add new Relationship: " + getDragItem().getName() + "-> " + obj.getName()); //if the inherit is the faske root we create no now relationship but set the inherit to null if (obj.getName().equals(getRoot().getValue().getName())) { System.out.println("New root is Fake Root"); for (JEVisClassRelationship rel : getDragItem() .getRelationships(JEVisConstants.ClassRelationship.INHERIT)) { getDragItem().deleteRelationship(rel); } } else { System.out.println("new Root is NOT fake root"); JEVisClassRelationship newRel = getDragItem().buildRelationship(obj, JEVisConstants.ClassRelationship.INHERIT, JEVisConstants.Direction.FORWARD); System.out.println("new Rel: " + newRel); for (JEVisClassRelationship rel : getDragItem() .getRelationships(JEVisConstants.ClassRelationship.INHERIT)) { System.out.println("Rel: " + rel); if (!rel.equals(newRel)) { System.out.println("remove relationship " + getDragItem().getName() + " -> " + rel.getOtherClass(getDragItem()).getName()); getDragItem().deleteRelationship(rel); TreeItem<JEVisClass> dragParentItem = getObjectTreeItem( rel.getOtherClass(getDragItem().getInheritance())); getChildrenList(dragParentItem).remove(getObjectTreeItem(getDragItem())); } } } Platform.runLater(new Runnable() { @Override public void run() { try { TreeItem<JEVisClass> dragItem = getObjectTreeItem(getDragItem()); TreeItem<JEVisClass> dragParentItem = dragItem.getParent(); System.out.println("ParentItem: " + dragParentItem.getValue().getName()); TreeItem<JEVisClass> targetItem = getObjectTreeItem(obj); getChildrenList(dragParentItem).remove(dragItem); getChildrenList(targetItem).add(dragItem); targetItem.setExpanded(true); } catch (JEVisException ex) { Logger.getLogger(ClassTree.class.getName()).log(Level.SEVERE, null, ex); } } }); } catch (JEVisException ex) { Logger.getLogger(ClassCell.class.getName()).log(Level.SEVERE, null, ex); ex.printStackTrace(); } dragEvent.consume(); } }); } } } }