event handling - Issue with removing\adding items from JavaFX TableColumn's combo box CellFactory -
i have javafx tablecolumn. column has comboboxtablecell
populated observablelist pass it.
i have "active" list , "deactive" list combobox. after selection made, wish remove selected item active, "real", list (and add deactivated items list).
after selection has been made, celleditevent
being fired , sets row object selected 1 (from combobox). thing is, when remove select item list, in event handler, celleditevent
event handler got fired again - time wrong "new value"!
of course behavior breaks flow logic completely.
any ideas how solve situation? thank you
an sscce of situation:
package tableviewexample; import javafx.application.application; import javafx.beans.binding.bindings; import javafx.beans.property.*; import javafx.beans.value.observablevalue; import javafx.collections.*; import javafx.event.*; import javafx.scene.scene; import javafx.scene.control.*; import javafx.scene.control.cell.*; import javafx.scene.layout.stackpane; import javafx.stage.stage; import javafx.util.callback; import javafx.util.stringconverter; public class tableviewexample extends application { @override public void start(stage primarystage) { tableview<mappingitem> table = new tableview<>(); // first column tablecolumn<mappingitem, string> cola = new tablecolumn<>("excel column"); cola.setcellvaluefactory(new callback<tablecolumn.celldatafeatures<mappingitem, string>, observablevalue<string>> () { @override public observablevalue<string> call(tablecolumn.celldatafeatures<mappingitem, string> param) { return new readonlyobjectwrapper(param.getvalue().getexcelcolumnname()); } }); //second column tablecolumn<mappingitem, goldplusfield> colb = new tablecolumn<>("database field column"); colb.setcellvaluefactory(new callback<tablecolumn.celldatafeatures<mappingitem, goldplusfield>, observablevalue<goldplusfield>> () { @override public observablevalue<goldplusfield> call(tablecolumn.celldatafeatures<mappingitem, goldplusfield> param) { return new readonlyobjectwrapper(param.getvalue().getgpfield()); } }); goldplusfield gp1 = new goldplusfield("t1", "fname", "first name"); goldplusfield gp2 = new goldplusfield("t1", "phn", "phone"); goldplusfield gp3 = new goldplusfield("t2", "lname", "last name"); goldplusfield gp4 = new goldplusfield("t2", "adrs", "address"); observablelist<goldplusfield> deactivefieldslist = fxcollections.observablearraylist(); observablelist<goldplusfield> activefieldslist = fxcollections.observablearraylist(gp1, gp2, gp3, gp4); colb.setcellfactory(comboboxtablecell.fortablecolumn(new fieldtostringconvertor(), activefieldslist)); colb.setoneditcommit( new eventhandler<tablecolumn.celleditevent<mappingitem, goldplusfield>>() { @override public void handle(tablecolumn.celleditevent<mappingitem, goldplusfield> t) { if (t.getnewvalue() != null) { deactivefieldslist.add(t.getnewvalue()); ((mappingitem) t.gettableview().getitems().get( t.gettableposition().getrow()) ).setgpfield(t.getnewvalue()); // ******************************************************************************************** // // creates new instance of eventhandler in "next" item on list. // ******************************************************************************************** // activefieldslist.remove(t.getnewvalue()); } } } ); //third column tablecolumn<mappingitem, string> colc = new tablecolumn<>("test column"); propertyvaluefactory<mappingitem, string> namefac = new propertyvaluefactory<>("name"); colc.setcellvaluefactory(namefac); colc.setcellfactory(textfieldtablecell.fortablecolumn()); table.seteditable(true); table.getcolumns().addall(cola, colb, colc); goldplusfield gp5 = new goldplusfield("t1", "other", "other"); mappingitem mi1 = new mappingitem("name", gp5); mi1.excelcolumnname.set("name1"); mappingitem mi2 = new mappingitem("phone", gp5); mi2.excelcolumnname.set("nam2"); observablelist<mappingitem> milist = fxcollections.observablearraylist(mi1, mi2); table.setitems(milist); stackpane root = new stackpane(); root.getchildren().add(table); scene scene = new scene(root, 300, 250); primarystage.settitle("hello world!"); primarystage.setscene(scene); primarystage.show(); } /** * @param args command line arguments */ public static void main(string[] args) { launch(args); } class fieldtostringconvertor extends stringconverter<goldplusfield> { @override public string tostring(goldplusfield object) { if (object != null) return object.getgpname(); else return ""; } @override public goldplusfield fromstring(string string) { throw new unsupportedoperationexception("not supported yet."); //to change body of generated methods, choose tools | templates. } } public class mappingitem { private stringproperty excelcolumnname = new simplestringproperty(this, "excelcolumnname"); private objectproperty<goldplusfield> gpfield = new simpleobjectproperty<goldplusfield>(this, "gpfield"); public string getexcelcolumnname() { return excelcolumnname.get(); } public void setexcelcolumnname(string excelcolumnname) { this.excelcolumnname.set(excelcolumnname); } public stringproperty excelcolumnnameproperty() { return excelcolumnname; } public goldplusfield getgpfield() { return gpfield.get(); } public void setgpfield(goldplusfield gpfield) { this.gpfield.set(gpfield); } public objectproperty gpfieldproperty() { return this.gpfield; } public mappingitem(string columnname) { this.excelcolumnname.set(columnname); } public mappingitem(goldplusfield gpfield) { this.gpfield.set(gpfield); } public mappingitem(string columnname, goldplusfield gpfield) { this.excelcolumnname.set(columnname); this.gpfield.set(gpfield); } } public class goldplusfield { private stringproperty table = new simplestringproperty(this, "table"); private stringproperty dbname = new simplestringproperty(this, "dbname"); private stringproperty gpname = new simplestringproperty(this, "gpname"); public string getdbname() { return dbname.get(); } public string getgpname() { return gpname.get(); } public string gettable() { return table.get(); } public void setdbname(string dbname) { this.dbname.set(dbname); } public void setgpname(string gpname) { this.gpname.set(gpname); } public void settable(string table) { this.table.set(table); } public stringproperty tableproperty() { return this.table; } public stringproperty gpnameproperty() { return this.gpname; } public stringproperty dbnameproperty() { return this.dbname; } public goldplusfield(string table, string dbname, string gpname) { this.dbname.set(dbname); this.gpname.set(gpname); this.table.set(table); } } }
Comments
Post a Comment