How do we use setCellValueFactory and setCellFactory?
What's difference between them?
According to the documentation :
setCellValueFactory
The cell value factory needs to be set to specify how to populate all cells within a single TableColumn. A cell value factory is a Callback that provides a TableColumn.CellDataFeatures instance, and expects an ObservableValue to be returned. The returned ObservableValue instance will be observed internally to allow for immediate updates to the value to be reflected on screen.
setCellFactory
The cell factory for all cells in this column. The cell factory is responsible for rendering the data contained within each TableCell for a single table column.
By default TableColumn uses the default cell factory, but this can be replaced with a custom implementation, for example to show data in a different way or to support editing.
Resource :http://docs.oracle.com/javase/8/javafx/api/toc.htm and http://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/TableColumn.html#setCellFactory-javafx.util.Callback-
Related
I have some data which are stored in a variable "myStorage" (a QVector).
I use a QAbstractTableModel to display these data in a QTableView : each entry in the QVector is a row in the table and each field in "myStruct" is a column.
Now I want to display more information, in a new column, without any modification to "myStruct" or to my model.
So I tried to make a new model class, derived from QAbstractProxyModel, which should add the new "virtual" column.
(For example, this column could be the average of 2 existing fields in "myStruct")
But I can't make it work : in the worst case, the program crash, in the best case, I have the right number of columns (one more than in the proxied model) and the right headers, but the data are shifted and the last column is empty.
Is there any minimal/simple example of a "add virtual column proxy model" working implementation ?
Should I use QIdentityProxyModel as a base class instead of QAbstractProxyModel ?
Thanks
Event after updating the data model javafx treetableview cell value not getting updated.
I am using the sample code here # http://docs.oracle.com/javase/8/javafx/user-interface-tutorial/tree-table-view.htm
(Example 15-2)
On click of button i m trying to update first item: employees.get(0).setName("Test");
Is there any trick using which treetableview can be updated?
The example, somewhat strangely, returns a ReadOnlyStringWrapper wrapping the property values for the cell value factories. Thus instead of binding the value displayed in the column directly to the properties in the Employee class, it binds them to a new, read-only, property wrapping the value retrieved when updateItem(..) is called on the cell. This means it won't get updated when the underlying data is updated, but only if the updateItem(...) method is invoked on the cell. (I have no idea why they would do this.) So you should find, for example, that if you change the value, then collapse the root node in the TreeTableView and expand it again, that your new value is displayed after expanding the root (because this causes the cells' updateItem(...) methods to be invoked).
To make the cells update when the data is changed, bind the cell value directly to the property defined in the model (Employee) class:
empColumn.setCellValueFactory( param -> param.getValue().getValue().nameProperty());
and
emailColumn.setCellValueFactory( param -> param.getValue().getValue().emailProperty());
I have a JavaFX TableView defined as :
TableView<MyMessage> messages;
It is supported by an ObservableList :
private ObservableList<MyMessage> messagesList;
// Allocate the message list
messagesList = FXCollections.observableArrayList();
// Set the list into place
messages.setItems( messagesList );
The MyMessage object has 10 fields all of type String. There is a background operation that inserts MyMessage objects into the ObservableList.
messages.add( new MyMessage( String ... colData ) );
Everything works as advertised. The table rows of the TableView are updated as objects are inserted into the ObservableList.
What doesn't seem to work as expected, is if I click on a column header to sort the table, the subsequent items inserted by the background thread are appended to the end of the table. Not to the proper sorted row position. If I click to resort the column, the table is resorted properly.
Do I need to some how force the re-sorting of the table each time I add something to the ObservableList? Or should the TableView take care of that for me.
Thanks.
Java FX 8 now has a .sort() method on tableView that can be called to re-trigger sorting. Some operations will trigger a re-sort automatically but external events adding/deleting entries in the observable collection do not.
should the TableView take care of that for me
No.
There was a request that TableView maintain sort order as the underlying list changes but it was closed as "not an issue". You can review the comments on the issue for more detailed information. In short, keeping the list sorted is the responsibility of the underlying ObservableList or the application maintaining the list.
Do I need to some how force the re-sorting of the table each time I add something to the ObservableList?
In essence, yes.
JavaFX was supposed to ship with a SortedObservableList implementation which effectively cooperated with the TableView to make all of the sorting handling pretty much automatic for the application. But, for JavaFX 2.2, the functionality did not make the cut for inclusion. Currently, this functionality is scheduled for delivery as part of JDK/JRE8 and can be tracked via this umbrella issue for improved sorting support in TableView.
From what I've seen, the formatter function in Dojo DataGrid is given the following arguments: cell value, cell row number, and the cell object itself. Can you suggest how to obtain data store item to which this cell refers, given these arguments? Or if you can suggest an alternative way, I'd be grateful.
Found it. The grid has a method called getItem(), which accepts row number as argument.
I have a datagrid that uses an array of objects as the data provider. The objects are essentially key/value pairs:
{ foo:"something"}
{ bar:"hello"}
{ caca:"lorem"}
The datagrid has 2 columns. The first column is the key and the second column is the value. Right now my grid looks like:
My dataFormatter function makes sure that depending on the column (i.e. the dataField value) the correct key or value gets printed out. This works fine for displaying. However, as soon as I try and edit the value field it essentially adds a new value into the object with a key of '1'. For example, if I edit the {caca:"lorem"} object it will then contain the value {caca:"lorem",1:"new value"}.
Is there any possible way I can set the DataGridColumn so that when I edit a value it will update the value associated with the key rather than inserting a new value? I've tried using a custom item editor but it still does the insert. It seems like I need to be able to update the 'dataField' with the actual key value but I'm not sure how to do that.
Looks like you need to think about where your data is going to be stored. I would recommend listening for a CollectionEvent.COLLECTION_CHANGE event on your data model. That event object will contain info about what change occurred, and you can make any updates you need to make.