javafx 8 - Apply table filter -
i have example of java table generates values every second.
short example:
mainapp.java
public class mainapp extends application { private tableview<employee> table; private textfield txtfield; private observablelist<employee> data; myservice myservice; @override public void start(stage stage) throws exception { label lbl = new label("enter text below filter: "); initfilter(); inittable(); myservice = new myservice(); myservice.setdelay(new duration(300)); myservice.setperiod(new duration(1000)); myservice.start(); vbox container = new vbox(); container.getchildren().addall(lbl, txtfield, table); stackpane root = new stackpane(); root.getchildren().add(container); scene scene = new scene(root, 500, 400); stage.setscene(scene); stage.show(); } class myservice extends scheduledservice<void> { @override protected task<void> createtask() { return new task<void>() { @override protected void call() throws exception { data = gettabledata(); table.setitems(fxcollections.observablearraylist(data)); return null; } }; } } public static void main(string[] args) { launch(args); } private void inittable() { table = new tableview<>(); table.setcolumnresizepolicy(tableview.constrained_resize_policy); tablecolumn<employee, string> empidcol = new tablecolumn<>("employee id"); empidcol.setcellvaluefactory(new callback<tablecolumn.celldatafeatures<employee, string>, observablevalue<string>>() { @override public observablevalue<string> call(tablecolumn.celldatafeatures<employee, string> p) { return p.getvalue().empidproperty(); } }); tablecolumn<employee, string> namecol = new tablecolumn<>("name"); namecol.setcellvaluefactory(new callback<tablecolumn.celldatafeatures<employee, string>, observablevalue<string>>() { @override public observablevalue<string> call(tablecolumn.celldatafeatures<employee, string> p) { return p.getvalue().nameproperty(); } }); tablecolumn<employee, number> agecol = new tablecolumn<>("age"); agecol.setcellvaluefactory(new callback<tablecolumn.celldatafeatures<employee, number>, observablevalue<number>>() { @override public observablevalue<number> call(tablecolumn.celldatafeatures<employee, number> p) { return p.getvalue().ageproperty(); } }); tablecolumn<employee, string> citycol = new tablecolumn<>("city"); citycol.setcellvaluefactory(new callback<tablecolumn.celldatafeatures<employee, string>, observablevalue<string>>() { @override public observablevalue<string> call(tablecolumn.celldatafeatures<employee, string> p) { return p.getvalue().cityproperty(); } }); table.getcolumns().setall(empidcol, namecol, agecol, citycol); } private void initfilter() { txtfield = new textfield(); txtfield.setprompttext("filter"); txtfield.textproperty().addlistener(new invalidationlistener() { @override public void invalidated(observable o) { if (txtfield.textproperty().get().isempty()) { table.setitems(data); return; } observablelist<employee> tableitems = fxcollections.observablearraylist(); observablelist<tablecolumn<employee, ?>> cols = table.getcolumns(); (int = 0; < data.size(); i++) { (int j = 0; j < cols.size(); j++) { tablecolumn col = cols.get(j); string cellvalue = col.getcelldata(data.get(i)).tostring(); cellvalue = cellvalue.tolowercase(); if (cellvalue.contains(txtfield.textproperty().get().tolowercase())) { tableitems.add(data.get(i)); break; } } } table.setitems(tableitems); } }); } private observablelist<employee> gettabledata() { observablelist<employee> list = fxcollections.observablearraylist(); string[] name = { "sriram", "pete", "eric", "dawson", "john" }; string[] city = { "new york", "chicago", "little rock", "los angeles", "oakland" }; (int = 0; < 5; i++) { employee emp = new employee(); emp.setname(name[i]); emp.setage((int) (math.random() * 100)); emp.setcity(city[i]); emp.setempid(string.valueof(i + 1000)); list.add(emp); } return list; } }
employee.java
public class employee { private simplestringproperty name = new simplestringproperty(); private simpleintegerproperty age = new simpleintegerproperty(); private simplestringproperty city = new simplestringproperty(); private simplestringproperty empid = new simplestringproperty(); public simplestringproperty nameproperty() { return name; } public void setname(string name) { this.name.set(name); } public string getname() { return name.get(); } public simpleintegerproperty ageproperty() { return age; } public void setage(integer age) { this.age.set(age); } p ublic integer getage() { return age.get(); } public simplestringproperty cityproperty() { return city; } public string getcity() { return city.get(); } public void setcity(string city) { this.city.set(city); } public simplestringproperty empidproperty() { return empid; } public void setempid(string empid) { this.empid.set(empid); } public string getempid() { return empid.get(); } }
i noticed filter use filter content applied current service run. next run filter not applied.
use filteredlist
manage filtering. instead of updating list directly, replace contents of source list service. when text in text field changes, update predicate filtered list.
as aside, code updates tableview
background thread, violates threading rules of javafx. fixed in example below.
sscce:
import java.util.arraylist; import java.util.list; import javafx.application.application; import javafx.beans.property.simpleintegerproperty; import javafx.beans.property.simplestringproperty; import javafx.collections.fxcollections; import javafx.collections.observablelist; import javafx.collections.transformation.filteredlist; import javafx.concurrent.scheduledservice; import javafx.concurrent.task; import javafx.scene.scene; import javafx.scene.control.label; import javafx.scene.control.tablecolumn; import javafx.scene.control.tableview; import javafx.scene.control.textfield; import javafx.scene.layout.stackpane; import javafx.scene.layout.vbox; import javafx.stage.stage; import javafx.util.duration; public class filteredtableviewexample extends application { private tableview<employee> table; private textfield txtfield; private filteredlist<employee> tabledata; private observablelist<employee> data; myservice myservice; @override public void start(stage stage) throws exception { label lbl = new label("enter text below filter: "); initfilter(); inittable(); myservice = new myservice(); myservice.setdelay(new duration(300)); myservice.setperiod(new duration(1000)); myservice.start(); vbox container = new vbox(); container.getchildren().addall(lbl, txtfield, table); stackpane root = new stackpane(); root.getchildren().add(container); scene scene = new scene(root, 500, 400); stage.setscene(scene); stage.show(); } class myservice extends scheduledservice<list<employee>> { @override protected task<list<employee>> createtask() { task<list<employee>> task = new task<list<employee>>() { @override protected list<employee> call() throws exception { return gettabledata(); } }; task.setonsucceeded(e -> data.setall(task.getvalue())); return task ; } } public static void main(string[] args) { launch(args); } private void inittable() { table = new tableview<>(); table.setcolumnresizepolicy(tableview.constrained_resize_policy); tablecolumn<employee, string> empidcol = new tablecolumn<>("employee id"); empidcol.setcellvaluefactory(p -> p.getvalue().empidproperty()); tablecolumn<employee, string> namecol = new tablecolumn<>("name"); namecol.setcellvaluefactory(p -> p.getvalue().nameproperty()); tablecolumn<employee, number> agecol = new tablecolumn<>("age"); agecol.setcellvaluefactory(p -> p.getvalue().ageproperty()); tablecolumn<employee, string> citycol = new tablecolumn<>("city"); citycol.setcellvaluefactory(p -> p.getvalue().cityproperty()); table.getcolumns().setall(empidcol, namecol, agecol, citycol); data = fxcollections.observablearraylist(); tabledata = new filteredlist<>(data); table.setitems(tabledata); } private void initfilter() { txtfield = new textfield(); txtfield.setprompttext("filter"); txtfield.textproperty().addlistener((obs, oldtext, newtext) -> { if (txtfield.textproperty().get().isempty()) { tabledata.setpredicate(employee -> true); return; } tabledata.setpredicate(employee -> { string text = newtext.tolowercase(); (tablecolumn<employee, ?> col : table.getcolumns()) { string cellvalue = col.getcelldata(employee).tostring(); cellvalue = cellvalue.tolowercase(); if (cellvalue.contains(text)) { return true; } } return false; }); }); } private list<employee> gettabledata() { list<employee> list = new arraylist<>(); string[] name = { "sriram", "pete", "eric", "dawson", "john" }; string[] city = { "new york", "chicago", "little rock", "los angeles", "oakland" }; (int = 0; < 5; i++) { employee emp = new employee(); emp.setname(name[i]); emp.setage((int) (math.random() * 100)); emp.setcity(city[i]); emp.setempid(string.valueof(i + 1000)); list.add(emp); } return list; } public static class employee { private simplestringproperty name = new simplestringproperty(); private simpleintegerproperty age = new simpleintegerproperty(); private simplestringproperty city = new simplestringproperty(); private simplestringproperty empid = new simplestringproperty(); public simplestringproperty nameproperty() { return name; } public void setname(string name) { this.name.set(name); } public string getname() { return name.get(); } public simpleintegerproperty ageproperty() { return age; } public void setage(integer age) { this.age.set(age); } public integer getage() { return age.get(); } public simplestringproperty cityproperty() { return city; } public string getcity() { return city.get(); } public void setcity(string city) { this.city.set(city); } public simplestringproperty empidproperty() { return empid; } public void setempid(string empid) { this.empid.set(empid); } public string getempid() { return empid.get(); } } }
Comments
Post a Comment