java - Creating a custom tree with javafx -


basically, wanted know if create tree , custom on javafx... tried it, couldn't far code...

public class main{     ......   public main() throws exception{     ......         // treeview created     treeview tv = (treeview) fxmlloader.getnamespace().get("treeview");      treeitem<string> rootitem = new treeitem<string>("liss");     rootitem.setexpanded(true);     tv.setroot(rootitem);      /*for (int = 1; < 6; i++) {         treeitem<string> item = new treeitem<string> ("message" + i);         rootitem.getchildren().add(item);     }     treeitem<string> item = new treeitem<string> ("messagewoot");     rootitem.getchildren().add(item); */     //tv.seteditable(true);      tv.setcellfactory(new callback<treeview<string>, treecell<string>>() {         @override         public treecell<string> call(treeview<string> arg0) {             // custom tree cell defines context menu root tree item             return new mytreecell();         }     });      stage.show(); }  // private static class mytreecell extends textfieldtreecell<string> {     private contextmenu addmenu = new contextmenu();     public boolean clickedfirsttime = false;      public mytreecell() {         // instantiate root context menu         menuitem addmenuitem = new menuitem("expand");         addmenu.getitems().add(addmenuitem);         addmenuitem.setonaction(new eventhandler() {              public void handle(event t) {                 treeitem n0 =                         new treeitem<string>("'program'");                 treeitem n1 =                         new treeitem<string>("<identifier>");                 treeitem n2 =                         new treeitem<string>("body");                  gettreeitem().getchildren().add(n0);                 gettreeitem().getchildren().add(n1);                 gettreeitem().getchildren().add(n2);              }         });     }      @override     public void updateitem(string item, boolean empty) {         super.updateitem(item, empty);          // if item not empty , root...         //if (!empty && gettreeitem().getparent() == null && this.clickedfirsttime) {         system.out.println("updateitem -> clickedfirsttime : "+this.clickedfirsttime);         if (!this.clickedfirsttime) {             system.out.println("woot");             setcontextmenu(addmenu);             this.clickedfirsttime = true;         }     }  } 

and i'm questioning myself if right "technology" solve i'm trying do...

what's objective in this?

firstly, i'm looking add or delete treeitem. must treeitem may added once or n times, restriction (for example: treeitem < 6 level scope , path of root of tree view).

secondly, make treeitem editable , others not editable! when editable, may pop user insert input example!

is possible ?

i saw tutorial https://docs.oracle.com/javafx/2/ui_controls/tree-view.htm#babjgggf i'm confused tutorial ... don't understand cell factory mechanism... fact apply treeview when want treeitem... or how control effect/behaviour ? mean, i'm really lost treeview. probably, treeview isn't i'm looking ...

p.s.: know cannot apply visual effect or add menus tree items , use cell factory mechanism overcome obstacle. don't understand idea , how !

sure right "technology", if want use javafx. should use more complex type parameter treeitem however. can use custom treecell allow desired user interaction.

this example allows adding children , removing nodes via context menu (unless content "nocontext") editing content (as long content not "noedit"); on root node delete option disabled:

    tv.seteditable(true);      tv.setcellfactory(new callback<treeview<string>, treecell<string>>() {          private final mycontextmenu contextmenu = new mycontextmenu();         private final stringconverter converter = new defaultstringconverter();          @override         public treecell<string> call(treeview<string> param) {             return new customtreecell(contextmenu, converter);         }      }); 
public class customtreecell extends textfieldtreecell<string> {      private final mycontextmenu contextmenu;      public customtreecell(mycontextmenu contextmenu, stringconverter<string> converter) {         super(converter);         if (contextmenu == null) {             throw new nullpointerexception();         }         this.contextmenu = contextmenu;         this.setoncontextmenurequested(evt -> {             preparecontextmenu(gettreeitem());             evt.consume();         });     }      private void preparecontextmenu(treeitem<string> item) {         menuitem delete = contextmenu.getdelete();         boolean root = item.getparent() == null;         if (!root) {             delete.setonaction(evt -> {                 item.getparent().getchildren().remove(item);                 contextmenu.freeactionlisteners();             });         }         delete.setdisable(root);         contextmenu.getadd().setonaction(evt -> {             item.getchildren().add(new treeitem<>("new item"));             contextmenu.freeactionlisteners();         });     }      @override     public void updateitem(string item, boolean empty) {         super.updateitem(item, empty);         if (!empty) {             setcontextmenu("nocontext".equals(item) ? null : contextmenu.getcontextmenu());             seteditable(!"noedit".equals(item));         }     }  } 
public class mycontextmenu {     private final contextmenu contextmenu;     private final menuitem add;     private final menuitem delete;      public mycontextmenu() {         this.add = new menuitem("add child");         this.delete = new menuitem("delete");         this.contextmenu = new contextmenu(add, delete);     }      public contextmenu getcontextmenu() {         return contextmenu;     }      public menuitem getadd() {         return add;     }      public menuitem getdelete() {         return delete;     }      /**      * method prevents memory leak setting actionlisteners null.      */     public void freeactionlisteners() {         this.add.setonaction(null);         this.delete.setonaction(null);     }  } 

of course more complex checks can done in updateitem , preparecontextmenu , different user interactions can supported (textfieldtreecell may not appropriate superclass you; use "normal" treecell , show different stage/dialog edit item when user selects menuitem in context menu).

some clarification cell factories

cell factories used create cells in class displays data (e.g. tablecolumn, treeview, listview). when such class needs display content, uses it's cell factory create cells uses display data. content displayed in such cell may changed (see updateitem method).

example

(i'm not 100% sure way it's done, should sufficiently close)

a treeview created display expanded root node 2 non expanded children.

the treeview determines needs display 3 items root node , it's 2 children. treeview therefore uses it's cell factory creates 3 cells , adds them it's layout , assigns displayed items.

now user expands first child, has 2 children of it's own. treeview determines needs 2 more cells display items. new cells added @ end of layout efficiency , items of cells updated:

  • the cell contained last child updated , contains first child of first item.
  • the 2 newly added cells updated contain second child of first child , second child of root respecitvely.

Comments

Popular posts from this blog

authentication - Mongodb revoke acccess to connect test database -

r - Update two sets of radiobuttons reactively - shiny -

ios - Realm over CoreData should I use NSFetchedResultController or a Dictionary? -