java - What is right way to work with tableview? -


for time have been trying tableview work kind of spreadsheet updated background thread , when cell updated, few seconds higlights ( changes style ) , goes original style. know, can't store , set styles directly in table cell , need kind of backing class, hold data. tableview "reusing" of cells (using same cells different data) acts weird. when cells fits on screen works flawlessly me, once place around 100 cells , becomes scrollable starts being buggy, styles ( or setted graphic) disappears , after scrolling appears, if disable top cells of view, other cells after scrolling disabled , on. there right way this?

what need

background data thread ---updates--> tableview thread --after few seconds removes style--> tableview 

as have now, have model class holds data, style , reference table cell should ( disabled ordering, should ok ) , background thread updates data in model class, , model class changes style on referenced cell , register in "style remover" thread, after while removes style.

i think posting actual code won't useful, because once i've discovered cells being reused code has become complicated , little bit unreadable want redo right way.

peformance not important me, there wont more 100 cells, highlighting , having buttons in tableview must work flawlessly.

this how app looks - idea of need. enter image description here

edit: here link another question related this.

the collaborators:

  • on data side, (view) model has recentlychanged property, that's updated whenever value changed
  • on view side, custom cell listens recentlychanged property , updates style appropriate

the tricky part clean cell state when re-used or not-used: method that's (hopefully!) called cell.updateindex(int newindex), that's place un-/register listener.

below runnable (though crude ;) example

import java.util.logging.logger; import java.util.stream.collectors; import java.util.stream.stream;  import de.swingempire.fx.util.fxutils; import javafx.animation.keyframe; import javafx.animation.timeline; import javafx.application.application; import javafx.beans.property.readonlybooleanproperty; import javafx.beans.property.readonlybooleanwrapper; import javafx.beans.property.simplestringproperty; import javafx.beans.property.stringproperty; import javafx.beans.value.changelistener; import javafx.collections.fxcollections; import javafx.collections.observablelist; import javafx.scene.parent; import javafx.scene.scene; import javafx.scene.control.button; import javafx.scene.control.tablecell; import javafx.scene.control.tablecolumn; import javafx.scene.control.tableview; import javafx.scene.layout.borderpane; import javafx.scene.layout.hbox; import javafx.stage.stage; import javafx.util.duration;  public class tablecorerecentlychanged extends application {      public static class recentchanged extends tablecell<dummy, string> {          private changelistener<boolean> recentlistener = (src, ov, nv) -> updaterecentstyle(nv);         private dummy lastdummy;          /*          * see effect.          */         protected void updaterecentstyle(boolean highlight) {             if (highlight) {                 setstyle("-fx-background-color: #99ff99");             } else {                 setstyle("-fx-background-color: #009900");             }         }          @override         public void updateindex(int index) {             if (lastdummy != null) {                 lastdummy.recentlychangedproperty().removelistener(recentlistener);                 lastdummy = null;             }             updaterecentstyle(false);             super.updateindex(index);             if (gettablerow() != null && gettablerow().getitem() != null) {                 lastdummy = gettablerow().getitem();                 updaterecentstyle(lastdummy.recentlychangedproperty().get());                 lastdummy.recentlychangedproperty().addlistener(recentlistener);             }          }          @override          protected void updateitem(string item, boolean empty) {             if (item == getitem()) return;              super.updateitem(item, empty);              if (item == null) {                 super.settext(null);                 super.setgraphic(null);             } else {                 super.settext(item);                 super.setgraphic(null);             }         }      }      private parent getcontent() {         tableview<dummy> table = new tableview<>(createdata(50));         table.seteditable(true);          tablecolumn<dummy, string> column = new tablecolumn<>("value");         column.setcellvaluefactory(c -> c.getvalue().valueproperty());         column.setcellfactory(e -> new recentchanged());         column.setminwidth(200);         table.getcolumns().addall(column);          int editindex = 20;           button changevalue = new button("edit");         changevalue.setonaction(e -> {             dummy dummy = table.getitems().get(editindex);             dummy.setvalue(dummy.getvalue()+"x");         });         hbox buttons = new hbox(10, changevalue);         borderpane content = new borderpane(table);         content.setbottom(buttons);         return content;     }      private observablelist<dummy> createdata(int size) {         return fxcollections.observablearraylist(                 stream.generate(dummy::new)                 .limit(size)                 .collect(collectors.tolist()));     }      private static class dummy {         private static int count;          readonlybooleanwrapper recentlychanged = new readonlybooleanwrapper() {              timeline recenttimer;             @override             protected void invalidated() {                 if (get()) {                     if (recenttimer == null) {                         recenttimer = new timeline(new keyframe(                                 duration.millis(2500),                                 ae -> set(false)));                     }                     recenttimer.playfromstart();                 } else {                     if (recenttimer != null) recenttimer.stop();                 }             }          };         stringproperty value = new simplestringproperty(this, "value", "initial " + count++) {              @override             protected void invalidated() {                 recentlychanged.set(true);             }          };          public stringproperty valueproperty() {return value;}         public string getvalue() {return valueproperty().get(); }         public void setvalue(string text) {valueproperty().set(text); }         public readonlybooleanproperty recentlychangedproperty() { return recentlychanged.getreadonlyproperty(); }         public string tostring() {return "[dummy: " + getvalue() + "]";}     }      @override     public void start(stage primarystage) throws exception {         primarystage.setscene(new scene(getcontent()));      //   primarystage.settitle(fxutils.version());         primarystage.show();     }      public static void main(string[] args) {         launch(args);     }      @suppresswarnings("unused")     private static final logger log = logger             .getlogger(tablecorerecentlychanged.class.getname()); } 

Comments

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -