I have a TableView in my UI, it displays an user list from the database. One of the column of this table is editable, when editing is enabled the cell of this particular column becomes a treeview, listing various options which can be chosen.
Just to clarify, I am trying to implement a Datepicker or a colorpicker like functionality on a table cell, but with my own list of items as a tree.
The table is defined like this
private TableView<User> userTable;
The particular column which displays a tree view is defined like this
private TableColumn<User, TreeView> col4;
I set a setcellFactory method like this to display the tree
col4.setCellFactory(new Callback<TableColumn<User,TreeView>, TableCell<User,TreeView>>() {
@Override
public TableCell<User, TreeView> call(
TableColumn<User, TreeView> param)
{
returns a comboboxtablecell which is filled with a tree
}
});
In the table, in the corresponding column, when I click the cell, the cell shows a combo box and the combobox on opening up shows the tree value.
However when the cell is in non-editable state, I am not sure how I should set the setcellValuefactory with a string value
col4.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<User,TreeView>, ObservableValue<TreeView>>() {
@Override
public ObservableValue<TreeView> call(
CellDataFeatures< User,TreeView> param)
{
}
}
I want to display a value which is inside the treeview as a string when the cell is in a non editable state. I am at a loss as to how to return an observablevalue of type treeview as per the method signature and still display a string.
You need to distinguish between the data that your
TableView
(and it'sTableColumn
s) is presenting, and the cells that are used to present those data. ThecellValueFactory
is an object that determines how to get the value (i.e. data) for a particular column from the value for the entire row. ThecellFactory
is an object that determines how to get the cell that presents the data to the user.Any time you write something like
TableColumn<User, TreeView<...>>
it is (almost always) a mistake. The first type in the type parameters is the type of the object in each row of the table - this is fine here - and the second is the type of the data that is displayed.TreeView
is not a data type: it's the type of a UI element, i.e. the type of something that is used to display the data.So you want something along these lines. (You haven't been too specific in explaining your data model - which is fine - but this might not be quite right; it will give you the idea though.)
The
User
class will have anObjectProperty<Options>
:And obviously this depends on an Options class encapsulating the data displayed in that column:
Now you just use the default cell value factory:
(or in JavaFX 8, I prefer
which is somewhat more efficient as it avoids the reflection that the
PropertyValueFactory
uses, and is not much more code, especially if you omit the type on the parameter to the lambda expression).(You don't have to set it up like this. If the
Options
are not an intrinsic part of theUser
, then you could, for example, have aMap<User, ObjectProperty<Options>>
defined and use that to return theObjectProperty<Options>
associated with each user. The way I showed is just the most common and probably easiest way.)I don't really understand where your
ComboBox
fits in, but this answer should give you enough to work that in as you need it. ThecellFactory
now just has to return aTableCell
that uses aTreeView
to display theOptions
object:You mentioned the cell was editable, so you need to wire up all the editing stuff for the cell too (and you'll probably want to use a named [inner] class as it's going to get a bit verbose, instead of the anonymous inner class I have here). But this should give you the basic structure.