Adding individual item to a TableView? - javafx

I have started using JavaFX for a few weeks. Here is a code snap of a TableView
#FXML protected void handleSubmitButtonAction(ActionEvent event) {
log.debug("handleSubmitButtonAction");
service.save(new InputText(inputText.getText()));
List<OutputData> outputDataList = new ArrayList<>();
service.getAll().forEach(e -> outputDataList.add(new OutputData(e)));
ObservableList<OutputData> list = FXCollections.observableArrayList(outputDataList);
outputView.setItems(list);
inputText.setText("");
}
What it does is that
Create a new entry
Save it to DB
Fetch all entries from DB
Create TableView row data for each entry
Create an ObservableList with all of the row data
Add the list to the TableView
That certainly isn't effective. Is a way to add a newly created entry directly to the TableView?

Here is what I would do.
Have service.save(new InputText(inputText.getText())); return a
true if the data was saved to the DB and false otherwise.
If true is returned, I would then add the data to the TableView
using outputView.getItems().add(inputText.getText());
If false is retured, I would use an Alert to let the user know
that the data was not added to the DB.

Related

Adding and removing tablecolumn dynamically to Tableview Javafx

Receive my greetings everyone!I'm new to javafx.For my first project of Javafx ,I want to create a tableview which Tablecolumns changes according to an event.Suppose that first time,My tableview has 4 columns such as (name,age,email,address).After an event,I want to add the tablecolumn profession for my tableview to have now 5 columns (name,age,email,adress,profession).After an other event,I want to remove profession for my tableview to have again 4 tablecolumns.Thank you for your help.Excuse me for my english.
Your table view has four columns so you already know how to add columns to the table view. Adding another is no different,(unless you originally defined your columns using FXML). Regardless, the addition and removal of columns in code is as demonstrated below.
Create your new column (add appropriate generic type info and initialization code):
final TableColumn fifthColumn = new TableColumn("Alien resistance");
// initialize the column
When you receive an event, add the fifth column:
Button insurrection = new Button("Add"):
insurrection.setOnAction(e ->
tableView.getColumns().add(
fifthColumn
)
);
similarly for the action on a remove button:
Button failedCoup = new Button("Remove"):
failedCoup.setOnAction(e ->
tableView.getColumns().remove(
fifthColumn
)
);

Javafx tableview column value from event handler

Is it possible to take a value of table column from a event handler in Javafx?
The task is I need to click a button, calculate functions, and return the value to the column.
I have this working:
data.add(new Person(id, name));
I have this:
TableColumn nameCol = new TableColumn ("name");
nameCol.setCellValueFactory(new PropertyValueFactory<>("name"));
// And id as well.
TableColumn resultsCol = new TableColumn ("Results");
resultsCol.setCellValueFactory(new PropertyValueFactory<>("results"));
And this:
add.setOnAction (e -> {
// I don't know what to put
});
Because id and name column are already working, what should I do to separately add a new value to the column from a button?
Because your CellValueFactories are pulling values directly from your Person object you would need to update the variables in the particular row's Person object when your button is clicked. You can do this with simple setter methods.
You could also use a technique like this to create a table with cells that can be edited with a click: http://java-buddy.blogspot.com/2012/04/javafx-2-editable-tableview.html?m=1
I have successfully implemented this technique in my applications.

Can't clear all items (elements) in an ObservableList

I've a couple of copied elements in an observablelist which I use for copy/paste operations in a TableView. The name of the table is cpTable (copy and paste Table) for storing copied elements and to paste elements that are stored in the table. After each paste operation I want to clear the contents of cpTable before I copy other selected items with Ctrl+C.
But I always get the error:
JavaFX Application Thread" java.lang.UnsupportedOperationException:
Not supported.
at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.remove(ReadOnlyUnbackedObservableList.java:246)
Here is my pseudocode:
if (cpTable !=null) {
//first, get all copied items for removing all elements
ObservableList<String> copiedItems = cpTable.getItems();
int size = copiedItems.size();
// remove all elements
for(int i=0;i<size;i++) {
copiedItems.remove(i);
}
cpTable.setItems(copiedItems); //clear cpTable by setting an empty list
}
This is a method that copies the contents of selected items and puts it in a cpTable
public TableView<String> copySelectionToClipboard(TableView<String> table) {
ObservableList<String> data = table.getSelectionModel().getSelectedItems();
TableView<String> tmp = new TableView<>();
tmp.setItems(data);
return tmp;
}
When Ctrl+C is pressed the following line puts all copied items in a cpTable:
cpTable = copySelectionToClipboard( (TableView<String>) keyEvent.getSource());
As mentioned I want to clear all cpTable contents immediately after pasting
the items in a table.
Just clear your Observable List. It looks like you should use copiedItems.clear();
That should clear your table.
As James_D already mentioned, you haven't cleared exactly what's the point.
If you want to delete selected items from a table, you need to delete them from the table item list itself and not from the selection model.
A possible solution looks like this:
TableView<String> table = new TableView<>();
ObservableList<String> tableItems = table.getItems();
// needs multirowselection is set to true
ObservableList<String> readOnlyItems = table.getSelectionModel().getSelectedItems();
// removes all selected elements for the table
readOnlyItems.stream().forEach((item) -> {
tableItems.remove(item);
});
// clear the selection
table.getSelectionModel().clearSelection();
Update
This method get's an TableView, calls it's selection model to get all selected items. And then you add the data to a new TableView. And there is the problem! It's an unmodifiable read only list that you attached to your new table. First make it modifiable, like in the code below:
public TableView<String> copySelectionToClipboard(TableView<String> table) {
ObservableList<String> readOnlyData = table.getSelectionModel().getSelectedItems();
ObservableList<String> writableData = FXCollections.<String>observableArrayList(readOnlyData);
TableView<String> tmp = new TableView<>();
tmp.setItems(writableData);
return tmp;
The next problem is in your call to this method. You call it with a TableView<CsvData> and with a TableView<String> as your method needs. If CsvData is a subtype of String, than you have to change your method signature to TableView<? extends String>
If you are trying to clear all the items from your tableView and want just an empty tableView. You can use this:
myTableView.getItems().clear();
This basically gets all the items from your table view which is nothing but just the observable list now it performs clear operations to remove all the items in tableView.
Assuming you mean
table.getSelectionModel().getSelectedItems()
(since the selection model has no getItems() method), according to the Javadocs, this returns a read-only list. Thus attempting to modify the list will throw an UnsupportedOperationException.
To clear the selection, do
table.getSelectionModel().clearSelection();
(And similarly, if you want to manipulate the selection in any other way, you use methods on the selection model, rather than on the list.)

Update ObservableList with data from sorted list?

I have followed this 1 tutorial to create a tableview with filtering. It works great, but the code in the tutorial creates a new SortedList (sortedData) with the sorted data and binds it with comparotorproperty to the table view, which originally uses a ObservableList as data source.
SortedList<Record> sortedData = new SortedList<Record>(filteredData);
// 4. Bind the SortedList comparator to the TableView comparator.
sortedData.comparatorProperty().bind(tableView.comparatorProperty());
// 5. Add sorted (and filtered) data to the table.
tableView.setItems(sortedData);
In my code I also have a Pie Chart and Bar Chart. They also use the ObservableList as data sources, so my question is ; how can I bind the sortedData to the ObservableList?
My code to get the data to the PieChart (and BarChart) is this:
for (Record record : dataen) {
dataList.add(new PieChart.Data(record.getFieldMonth(), record.getFieldValue()));
}
Where record is a class with Getters and Setters.
So you want to turn ObservableList<Record> into ObservableList<PieChart.Data>, correct? For that you can use EasyBind:
ObservableList<PieChart.Data> chartData = EasyBind.map(sortedData,
r -> new PieChart.Data(r.getFieldMonth(), r.getFieldValue()));
pieChart.setData(chartData);

javafx tableview detect any change upon any of rows including addition of new one

because I don't really know the sollution.
Lets say i have a TableView that holds info about product: description, quantity and the price. Also have a label that shows a sum of prices (times quantity) of all products from a table. Now i want to be notified about any changes that took affect on this component like changes in existing rows or addition of a new one. Is there any listener or sth similar to achieve it?
Usually you construct a TableView by passing an ObservableList to it. Something like this:
TableView myTable = new TableView<>(myObservableList);
ObservableList<ClassOfTheObjectsInTheList> myObservableList = FXCollections.FXCollections.observableArrayList(anyNoneObservableCollection);
TableView<ClassOfTheObjectsInTheList> myTable = new TableView<>(myObservableList);
You can add a ListChangeListener to any ObservableList at will by doing:
myObservableList.addListener(new ListChangeListener<ClassOfObjectsInTheList>(){
#Override
public void onChanged(javafx.collections.ListChangeListener.Change<? extends ClassOfObjectsInTheList> pChange) {
while(pChange.next()) {
// Do your changes here
}
}
});

Resources