I have a TableView with two columns, a TreeMap<String, String> and an ObservableMap. I want to fill the TableView with my TreeMap data.
But tableview.setItems(observableMap) does not work because setItems expects an ObservableList. I tried the same with observableHashMap which also didn't work. What can I do to fill my TableView with my data in the TreeMap?
Use the keys as item type for the TableView and use the cellValueFactory for the value column to extract the value:
Map<String, String> map = ...
TableView<String> tableView = new TableView();
// fill table with keys
tableView.getItems().addAll(map.keySet());
TableColumn<String, String> keyColumn = new TableColumn<>("key");
keyColumn.setCellValueFactory(cd -> new SimpleStringProperty(cd.getValue()));
TableColumn<String, String> valueColumn = new TableColumn<>("value");
valueColumn.setCellValueFactory(cd -> new SimpleStringProperty(map.get(cd.getValue())));
tableView.getColumns().addAll(keyColumn, valueColumn);
Alternatively you could also use a TableView<Map.Entry<String, String>>
...
// fill table with keys
tableView.getItems().addAll(map.entrySet());
TableColumn<Map.Entry<String, String>, String> keyColumn = new TableColumn<>("key");
keyColumn.setCellValueFactory(new PropertyValueFactory<>("key"));
TableColumn<Map.Entry<String, String>, String> valueColumn = new TableColumn<>("value");
valueColumn.setCellValueFactory(new PropertyValueFactory<>("value"));
...
Related
I have JavaFX tableview that I have created dynamically. When one double-clicks on a cell on the tableview, I need to get the name of the column the cell is in and the value of the first cell in the row this cell is in. I have tried searching over google and found no particular solution to this problem. Kindly show me some sample code.
Ok, so first, let's assume your TableView is attached to a model:
public TableView<MyModel> myTable;
where MyModel is something like:
public class MyModel {
private Integer id;
private String name;
// ... etc.
}
so, MyModel is a common POJO. You can have columns of your TableView like:
TableColumn<MyModel, Integer> id = new TableColumn<>("ID");
id.setCellValueFactory(new PropertyValueFactory<>("id"));
TableColumn<MyModel, String> name = new TableColumn<>("Name");
name.setCellValueFactory(new PropertyValueFactory<>("name"));
and then, to add the columns to your table:
myTable.getColumns().addAll(id, name);
Now, let's listen to the click event using a rowFactory:
myTable.setRowFactory(tv -> {
TableRow<MyModel> row = new TableRow<>();
row.setOnMouseClicked(event -> {
// check for non-empty rows, double-click with the primary button of the mouse
if (!row.isEmpty() && event.getClickCount() == 2 && event.getButton() == MouseButton.PRIMARY) {
MyModel element = row.getItem();
// now you can do whatever you want with the myModel variable.
System.out.println(element);
}
});
return row ;
});
That should do the work.
I have an observable List saving Author objects. The gui is able to add an author to my database. The observable list contains all the objects of the database. I want my table to update automatically if I add an Author in the databse.
I have already tried to refresh the list with table.refresh(). I am also thinking about using a change listener for the observable list.
Here the Code for creating the table. authorList is an observable list. I think I don't quite understand how to use an observable list. My suggestion was that by using "table.setItem(authorList)", my table automatically updates its entries if something is changed in the list. Obviously this is not the case.
private void createAuthorsTablePane() {
// TODO: Layout ändern
GridPane authorGridPane = new GridPane();
// create table
TableView<Author> table = new TableView<>();
// Create columns with title
TableColumn<Author, String> idColumn = new TableColumn<>("ID");
TableColumn<Author, String> nameColumn = new TableColumn<>("Name");
TableColumn<Author, String> emailColumn = new TableColumn<>("Email");
TableColumn<Author, String> publicationsColumn = new TableColumn<>("Publications");
// Add columns to table node
table.getColumns().add(idColumn);
table.getColumns().add(nameColumn);
table.getColumns().add(emailColumn);
table.getColumns().add(publicationsColumn);
// Bindings
PropertyValueFactory<Author, String> idColumnFactory = new PropertyValueFactory<>("id");
PropertyValueFactory<Author, String> nameColumnFactory = new PropertyValueFactory<>("name");
PropertyValueFactory<Author, String> emailColumnFactory = new PropertyValueFactory<>("email");
PropertyValueFactory<Author, String> publicationsColumnFactory = new PropertyValueFactory<>("publications");
idColumn.setCellValueFactory(idColumnFactory);
nameColumn.setCellValueFactory(nameColumnFactory);
emailColumn.setCellValueFactory(emailColumnFactory);
publicationsColumn.setCellValueFactory(publicationsColumnFactory);
table.setItems(authorList);
// Create Buttons
createAuthorButton = new Button("Create author");
createAuthorButton.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
mainController.createAuthorController();
}
});
deleteAuthorButton = new Button("Delete selected author");
// Add Nodes to Pane
authorGridPane.add(new Label("Authors"), 0, 0);
authorGridPane.add(table, 0, 1);
authorGridPane.add(deleteAuthorButton, 0, 2);
authorGridPane.add(createAuthorButton, 1, 2);
authorPane = authorGridPane;
}
Here is the class, where I create my authorList. I am registering the list in the class where I create the table by using a controller.
public class ObservableModel {
private ObservableList<Publication> publicationList;
private ObservableList<Author> authorList;
public ObservableModel(DatabaseService database) {
publicationList = FXCollections.observableList(database.getPublications());
authorList = FXCollections.observableList(database.getAuthors());
}
public ObservableList<Publication> getPublicationList() {
return publicationList;
}
public ObservableList<Author> getAuthorList() {
return authorList;
}
}
TableView<Author> table = new TableView<>();
private ObservableList<Author> authorList = FXCollections.observableArrayList();
private Property<ObservableList<Author>> authorListProperty = new SimpleObjectProperty<>(authorList);
table.itemsProperty().bind(authorListProperty); // The Binding
Every time you change authorList the tableview will be updated as well
idcolumnFactory.setCellValueFactory(cellData -> cellData.getValue().getIdProperty());
or if you declare simple bean
idcolumnFactory.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getId()));
don't forget
table.setItems(your_observale_list);
I used ObservableList to populate the TableView but the problem is that the data is not showing in the table I don't know what is the problem because the number of rows is exactly like I added them capture but there is nothing in the cells!
here is the code of the controller:
public class EnlistDim {
private static final String DEFAULT="-fx-text-background-color: black; -fx-background-color: steelblue;-fx-fill: red ;";
#FXML
private TableView<Parameter> tab;
#FXML
public void initialize() {
final ObservableList<Parameter> data = FXCollections.observableArrayList(
new Parameter("Query","Access method","Sequential scan"),
new Parameter("Query","Access method","in memory"),
new Parameter("Query","Operation","join"),
new Parameter("Query","Operation","Scan"),
new Parameter("Query","Operation","Sort"),
new Parameter("Database","Buffer management","Without buffer"),
new Parameter("Database","Buffer management","FIFO"),
new Parameter("Database","Buffer management","LIFO"),
new Parameter("Database","Buffer management","LRU"),
new Parameter("Database","Buffer management","Other"),
new Parameter("Database","Optimization structure","Not used"),
new Parameter("Database","Optimization structure","Partionning"),
new Parameter("Database","Optimization structure","Materialized View"),
new Parameter("Database","Optimization structure","compresssion"),
new Parameter("Database","System storage type","Database SQL"),
new Parameter("Database","System storage type","New SQL"),
new Parameter("Database","System storage type","Document"),
new Parameter("Database","System storage type","Graph"),
new Parameter("Database","System storage type","NVRAM"),
new Parameter("Database","System storage type","key value store"),
new Parameter("Database","Data storage type","Row Oriented"),
new Parameter("Database","Data storage type","Column Oriented"),
new Parameter("Database","Data storage type","Hybrid Oriented"),
new Parameter("Hardware","Processing device","CPU"),
new Parameter("Hardware","Processing device","GPU"),
new Parameter("Hardware","Processing device","FPGA"),
new Parameter("Hardware","Storage device","RAM"),
new Parameter("Hardware","Storage device","SSD"),
new Parameter("Hardware","Storage device","NVRAM"),
new Parameter("Hardware","Communication device","Modem"),
new Parameter("Hardware","Communication device","Cable"),
new Parameter("Hardware","Communication device","FaxModem"),
new Parameter("Hardware","Communication device","Router")
);
tab.setEditable(true);
tab.setItems(data);
tab.setStyle(DEFAULT);
}
}
and the code of Parameter class:
class Parameter {
SimpleStringProperty cat;
SimpleStringProperty subCat;
SimpleStringProperty subSubCat;
Parameter(String cat, String subCat, String subSubCat) {
this.cat = new SimpleStringProperty(cat);
this.subCat = new SimpleStringProperty(subCat);
this.subSubCat = new SimpleStringProperty(subSubCat);
}
public String getCat() {
return cat.get();
}
public void setCat(String c) {
cat.set(c);
}
public String getSubCat() {
return subCat.get();
}
public void setSubCat(String sc) {
subCat.set(sc);
}
public String getSubSubCat() {
return subSubCat.get();
}
public void setSubSubCat(String ssc) {
subSubCat.set(ssc);
}
}
You need to actually tell the TableView HOW to display the data. This is done using a CellValueFactory. Basically, you need to tell each column of the table what type of data it holds and where it gets that data from.
You need to start by defining your columns (give them an fx:id either in the FXML file or in SceneBuilder):
#FXML
TableColumn<Parameter, String> colCategory;
#FXML
TableColumn<Parameter, String> colSubCategory;
#FXML
TableColumn<Parameter, String> colSubSubCategory;
Each TableColumn takes two Type parameters. The first defines the object being displayed (Parameter). The second is the data type for this column (all yours are String).
Once the columns are defined, you need to set their CellValueFactory in your initialize() method:
colCategory.setCellValueFactory(new PropertyValueFactory<Parameter, String>("cat"));
colSubCategory.setCellValueFactory(new PropertyValueFactory<Parameter, String>("subCat"));
colSubSubCategory.setCellValueFactory(new PropertyValueFactory<Parameter, String>("subSubCat"));
Here you are telling each column where to find the data to be displayed. The last argument on the line, in the quotes, is the name of your property within the Parameter object.
So, when JavaFX populates your table, it will takes these steps to populate each column (colCategory, for example):
Get the CellValueFactory for colCategory.
The factory is a PropertyValueFactory, so determine which class holds the property (in this case it is the Parameter class)
Look in the Parameter class for a String property by the name of "cat"
Populate the column's cell with the value of the cat property.
I am trying to use a choicebox to show specific data in a tableview.
Lets say that i have 4 columns, "name" "Price" "Category" "in Stock", in my tableview. My tableview is getting its data from an .txt document, and it is possible to add data through textfields in my GUI.
My choicebox is holding value "Category 1" "Category 2" "Category 3", and my tableview is holding data in 6 rows, where 3 rows has category 1, and 3 rows has category 2.
What i want to do is, if i choose category 1 in my choicebox my tableview should only show data which is of category 1, and so on.
I am totally lost.
My Code.
private TableView<DTOArt> table = new TableView<DTOArt>();
private ObservableList<DTOArt> data = FXCollections.observableArrayList();
private ObservableList filCat = FXCollections.observableArrayList("Category 1","Category 2","Category 3");
public VBox getTableView(){
VBox tabelView = new VBox();
tabelView.setSpacing(5);
tabelView.setPadding(new Insets(10,10,10,10));
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
table.setEditable(true);
TableColumn nameCol = new TableColumn("Name");
nameCol.setCellValueFactory(new PropertyValueFactory<DTOArt, String>("name"));
TableColumn priceCol = new TableColumn("Price");
priceCol.setCellValueFactory(new PropertyValueFactory<DTOArt, String>("price"));
TableColumn categoryCol = new TableColumn("Category");
categoryCol.setCellValueFactory(new PropertyValueFactory<DTOArt, String>("category"));
TableColumn inStockCol = new TableColumn("in Stock");
inStockCol.setCellValueFactory(new PropertyValueFactory<DTOArt, String>("inStock"));
table.setItems(data);
table.getColumns().addAll(nameCol,priceCol,categoryCol,inStockCol);
tabelView.getChildren().add(table);
return tabelView;
}
My choiceBox.
ChoiceBox categoryCB = new ChoiceBox();
categoryCB.setItems(filCat);
categoryCB.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>(){
#Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue){
}
});
Wrap the list of all items in a FilteredList. This allows you to specify a Predicate to filter the items by.
private final ObservableList<DTOArt> data = FXCollections.observableArrayList();
private final FilteredList<DTOArt> filteredData = new FilteredList<>(data);
ChoiceBox<String> categoryCB = new ChoiceBox<>();
categoryCB.setItems(filCat);
categoryCB.valueProperty().addListener(new ChangeListener<String>(){
#Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue){
filteredData.setPredicate(newValue == null ? null : (DTOArt e) -> newValue.equals(e.getCategory()));
}
});
table.setItems(filteredData);
Furthermore if you want to allow dynamically changing the category, you should use an extractor for the ObservableList
private final ObservableList<DTOArt> data = FXCollections.observableArrayList((DTOArt e) -> new Observable[] { e.categoryProperty() });
Let me first explain what I did.
I am having list of tables in the drop down
when someone select any one it will populate all the data to tableview with respect to column name
I am able to get the columns from the table and put it in the tableview but I am not able to bind the data with associated columns.
My code here is to look
this.tableName = clsComboData.getValue();
System.out.println(tableName); System.out.println("Button Pressed");
List<StaticColumnConfig> allColumns = null;
for(StaticDataTable dataTable : dropdown) {
if(dataTable.getTableName() != null && dataTable.getTableName().equalsIgnoreCase(tableName)) {
System.out.println(dataTable.getColumnConfig());
allColumns = dataTable.getColumnConfig();
}
}
switch (tableName) {
case "IOSwapCounterparties": SimpleDateFormat date = new SimpleDateFormat("2015-04-15");
System.out.println("Into the Switch");
data = FXCollections.observableArrayList(
new IOSwapCounterparties(1,"a","b","c","d","e",date),
new IOSwapCounterparties(1,"aa","bb","cv","dd","es",date),
new IOSwapCounterparties(1,"ad","bd","cd","dc","eb",date),
new IOSwapCounterparties(1,"aw","bw","cr","dt","ey",date),
new IOSwapCounterparties(1,"ag","bt","cy","du","ep",date)
);
break;
}
//System.out.println("Its in ELSE");
//"Invited" column
TableColumn checkboxCol = new TableColumn<Person, Boolean>();
checkboxCol.setText("");
checkboxCol.setMinWidth(50);
checkboxCol.setCellValueFactory(new PropertyValueFactory("checkbox"));
// Create checkboxes
checkboxCol.setCellFactory(new Callback<TableColumn<Person, Boolean>, TableCell<Person, Boolean>>() {
public TableCell<Person, Boolean> call(TableColumn<Person, Boolean> p) {
CheckBoxTableCell<Person, Boolean> checkBox = new CheckBoxTableCell();
return checkBox;
}
});
//Set cell factory for cells that allow editing
Callback<TableColumn, TableCell> cellFactory =
new Callback<TableColumn, TableCell>() {
public TableCell call(TableColumn p) {
return new EditingCell();
}
};
for(StaticColumnConfig column : allColumns){
TableColumn oneColumn = new TableColumn(column.getColumnName());
oneColumn.setCellFactory(cellFactory);
}
// Clear the tableview for next table
tblViewer.getColumns().clear();
// Push the data to the tableview
tblViewer.setItems(data);
tblViewer.setEditable(true);
tblViewer.getColumns().addAll(checkboxCol);
for(StaticColumnConfig column : allColumns){
System.out.println(column.getColumnName());
TableColumn oneColumn = new TableColumn(column.getColumnName());
tblViewer.getColumns().addAll(oneColumn);
}
// Add the columns
tblViewer.getSelectionModel().setCellSelectionEnabled(true);
tblViewer.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
There is been uppercase - lowercase mistake with my getter and setter method.