JavaFX empty tableview with numbers - javafx

I have a tableview that has columns of types (SimpleStringProperty, SimpleIntegerProperty)
STRING1 STRING2 INTEGER1 INTEGER2
####### ####### ######## ########
a b 9 10
a c 9 12
b d 0 0
Now, in the 3rd row, the 3rd and 4th column have values as 0. The type of which is SimpleIntegerProperty.
I would like it if the 0s don't show up in the table and the cell appears empty.
Can you please advice on how i may do this?
P.S: I am using property listeners for making an editable table.
Strings are initialized to null and hence the table is blank but integers are getting initialized to 0.

I think you have to extend from ListCell and override the updateItem method.
In that method you have to check if the SimpleIntegerProperty equals 0 and probably call setText("") then.

You have to provide a TableCellFactory which returns your customized TableCell-Object. In the TableCell's updateItem()-method you can call setText() as suggested by Lukas Leitinger.
TableColumn columnInteger2 = new TableColumn("Integer2");
columnInteger2.setCellValueFactory(
new PropertyValueFactory<MyVo,String>("fieldInteger2"));
columnInteger2.setCellFactory(new Callback<TableColumn, TableCell>() {
#Override
public TableCell call(TableColumn tableColumn) {
return new TableCell<String, Integer>(){
#Override
protected void updateItem(Integer integer, boolean b) {
if (integer != null) {
super.setText(integer == 0?"":integer.toString());
}
}
};
}
});

Related

javafx How to get specific tabvleview cell index?

i have create a TableView with Columns and fill it with my sql database table data.
my qz is :
when i change the cell value in column 0 to XXX i want to cell value in column 1 to change with YYYY value
how can i get the cell 1 index to insert the new value after edit commit cell 0 >?
I had a similar "problem".
TablePosition pos = tableView.getSelectionModel().getSelectedCells().get(0);
int row = pos.getRow();
int col = pos.getColumn();
TableColumn column = pos.getTableColumn();
Object o = column.getCellData(row); //getting the Value from the specific Cell
I used this method, after double clicking a cell. You have to modfiy this solution that it fits to your problem, but it should help you.
To edit the specific cell i used the method setCellFactory from the TableColumn class.
column.setCellFactory(factory -> new TableCell<ObservableList<Object>, Object>() {
#Override
protected void updateItem(Object item, boolean empty) {
//Do something
}
});
At least at the end and after a week of searching for an answer, I found a solution and it is:
TablePosition TPOS = (TablePosition) table.getSelectionModel().getSelectedCells().get(5);
int rowIndex = TPOS.getRow();
int colIndex = TPOS.getColumn();
TableColumn COLP = (TableColumn) table.getColumns().get(5);
TableCell cell = (TableCell)table.queryAccessibleAttribute(AccessibleAttribute.CELL_AT_ROW_COLUMN,rowIndex,colIndex);
cell.setText(String.valueOf(getPrice()));
// getPrice() is the return method to find the price of edited item cell value

JavaFX Observable List Boolean attributes not reflected on CheckBoxes

I am trying to display a list of users on a table. I write the following code in order to complete the table, however the Boolean values are not displayed on checkboxes (they are always populated as empty / false when there are actually several that are true). As a test I an just adding a single object that I am creating "manually"
Below is the code:
TableView<User> objTable = new TableView<User>();
objTable.setEditable(true);
ObservableList<User> objList = FXCollections.observableArrayList(new User("User 1", true);
TableColumn objColumnName = new TableColumn<User, String>("Column Name");
TableColumn objColumnActive = new TableColumn<User, Boolean>("Active");
objColumnName.setCellValueFactory(new PropertyValueFactory<User, String>("DisplayName"));
objColumnActive.setCellValueFactory(new PropertyValueFactory<UserRequestVO, Boolean>("Active"));
objTable.getColumns().addAll(objColumn);
objTable.setItems(objList);
User Class
public class user
{
private String strFirstName;
private Boolean bolActive;
public Boolean getActive()
{
return this.bolActive
}
}
I also try renaming getActive function as isActive, but there were no changes
You should use properties,
In your user class, you would store your boolean as a SimpleBooleanProperty :
private SimpleBooleanProperty bolActive;
Instantiated like so : this.bolActive = new SimpleBooleanProperty(false); //Or true instead of false
Now create a getter for the property, the property value, and a setter for the property value :
public BooleanProperty bolActiveProperty(){
return bolActive;
}
public final Boolean getBolActive() {
return bolActive.get();
}
public final void setBolActive(Boolean bolActive) {
this.bolActive.set(bolActive);
}
Now when you create your table columns, you do this :
objColumnActive.setCellValueFactory(cellData -> cellData.getValue().bolActiveProperty());
Or if you prefer old school java :
objColumnActive.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<User,Boolean>, ObservableValue<Boolean>>() {
#Override
public ObservableValue<Boolean> call(CellDataFeatures<User, Boolean> cellData) {
return cellData.getValue().bolActiveProperty();
}
});
This also work I think, might be wrong though :
objColumnActive.setCellValueFactory(new PropertyValueFactory<User, Boolean>("bolActive"));
This will allow you to bind the User property to the column, so that any modification of the column will affect the value in the user.
Nice thing is you can listen to the value modification using myProperty.addListener((obs, oldV, newV) -> { /* Your code */ });
Where obs is the value observed, oldV the old value, and newV the new value (obviously)
Does that help/work for you?

JavaFX8: How to create listener for selection of row in Tableview?

I currently have two tableviews in one screen, which results in both TableViews have rows which the user can select.
Now I want only one row to be selected at the same time (doesn't matter which TableView it is selected from). I was thinking about some kind of listener which deselects the other row when a row is selected. This is my initial setup:
Step 1
Search for a way to bind a method to the selection of a row (there is not something like tableview.setOnRowSelected(method))
Step 2
Create the method which acts like a kind of listener: when a row is selected, deselect the other row (I know how to do this part)
Class1 selectedObject1 = (Class1)tableview1.getSelectionModel().getSelectedItem();
Class2 selectedObject2 = (Class2)tableview2.getSelectionModel().getSelectedItem();
if(selectedObject1 != null && selectedObject2 != null) {
tableview1.getSelectionModel().clearSelection();
}
So, step one is the problem. I was thinking of an observable list on which a listener can be created, and then add the selected row to the list. When this happens, the listener can call the method.
Anyone any clue how to make this?
Any help is greatly appreciated.
The selectedItem in the selection model is an observable property, so you should be able to achieve this with:
tableview1.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) -> {
if (newSelection != null) {
tableview2.getSelectionModel().clearSelection();
}
});
tableview2.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) -> {
if (newSelection != null) {
tableview1.getSelectionModel().clearSelection();
}
});
My solution would be creating custom cell factory for table and set it for each table columns.
Callback<TableColumn<..., ...>, TableCell<..., ...>> value = param -> {
TextFieldTableCell cell = new TextFieldTableCell<>();
cell.addEventFilter(MouseEvent.MOUSE_CLICKED, event -> {
//your code
}
);
return cell;
};
packageName.setCellFactory(value);
table1.column1.setCellFactory();
table2.column1.setCellFactory();
...
I use it for deleting the chosen row.
public void ButtonClicked()
{
ObservableList<Names> row , allRows;
allRows = table.getItems();
row = table.getSelectionModel().getSelectedItems();
row.forEach(allRows::remove);
}
This question helped me but during experiment in javafx and jfoenix this also works for me.
deleteSingle.addEventHandler(MouseEvent.MOUSE_CLICKED, (e) -> {
StringProperty selectedItem = table.getSelectionModel().getSelectedItem().getValue().link1;
System.out.println("That is selected item : "+selectedItem);
if (selectedItem.equals(null)) {
System.out.println(" No item selected");
} else {
System.out.println("Index to be deleted:" + selectedItem.getValue());
//Here was my database data retrieving and selectd
// item deleted and then table refresh
table.refresh();
return;
}
});
In case you need not only the row, but the x|y position of the table cell, do this:
table.getFocusModel().focusedCellProperty().addListener(
new ChangeListener<TablePosition>() {
#Override
public void changed(ObservableValue<? extends TablePosition> observable,
TablePosition oldPos, TablePosition pos) {
int row = pos.getRow();
int column = pos.getColumn();
String selectedValue = "";
if (table.getItems().size() > row
&& table.getItems().get(row).size() > column) {
selectedValue = table.getItems().get(row).get(column);
}
label.setText(selectedValue);
}
});
In this example, I am using a "classic" TableView with List<String> as column model. And, of course, that label is just an example from my code.

Calculated value passed as parameter to data model not showing on tableview

I have a form that has 4 TextFields which I'm trying to track with an ObservableList that has 5 columns. The TableView has an extra column to hold a calculated value (the 5th column in my ObservableList).
The data is dumping fine from the 4 TextFields, but the calculated column comes out blank. I assume this is a problem with my getters and setters, because the value is calculated before I pass it to my data model, AND I just tested the data model, and it is GETTING the value (passed as a parameter).
To not put extraneous code here, I think these are the relevant parts:
// This is (part of) my data model
public static class ItemSale {
private ItemSale (Double barC, String itemm, Double pricee,
Integer quant, Double totsP) {
this.barCode = new SimpleDoubleProperty(barC);
this.item = new SimpleStringProperty(itemm);
this.price = new SimpleDoubleProperty(pricee);
this.quantity = new SimpleIntegerProperty(quant);
this.rowPrice = new SimpleDoubleProperty(totsP);
System.out.println(totsP); // this (also) prints the correct value to the screen
// price * quantity = rowPrice, the calculated value that doesn't show up later
// getter & setter for quantity (works, is a textfield in my form)
public SimpleIntegerProperty getQuantity() {
return quantity;
}
public void setQuantity(Integer quant) {
quantity.set(quant);
}
// getter & setter for rowPrice (doesn't work, is calculated, see below)
public SimpleDoubleProperty getRowPrice(Double totsP) {
return rowPrice;
}
public void setRowPrice(Double totsP) {
rowPrice.set(totsP);
}
// in the Add button action handler, I have this:
Double rowPP;
rowPP = qua * pr; //qua = variable for quantity, pr = variable for price
System.out.println(rowPP); //prints to screen fine
data.add(new ItemSale(
bcode,
item.getText(),
pr,
qua,
rowPP
));
Ooops...got it figured out. I was researching another problem and found the answer on JavaFx - How to display SimpleStringProperty value in TableView and, in going through my code, I noticed I had the getter with parameters. Removed the parameters and BOOM! it worked.

How to create table with dynamic amount of columns

Thare is a tutorial at javaFX documentation page. This example describes how to make tableView, if you have some sertain java class, which can tell you which columns you are going to have. (That is a Person class in this example).
But what if i do not have any specific class, and number of columns can vary from time to time?
In my case i have such data structure:
class TableData{
List<Row> rows; //A list with all my rows i need to have in my table
}
class Row{
List<Column> columns; //Cells\Columns for every row.
}
class Column{
Attribute attr; //Each column - is somethig like a wrapper for the real data i need to show in a cell;
}
class Attribute{ //My precues data
String name;
SupportingInfo info;
}
class SupportingInfo{//Some supporting fields...
String name;
String value;
//...etc....
}
So, my case is very similar to this one.
The only differents is that data from the case above is not binded with its representation in javaFX table (so, even if some one will make extra controls to edit this data in a tableView, the actual object with that data will never know about it.), because it(data) goes to the table like some strings, not like some objects;
So, what do i need - is to push data to the table (like that: table.setItems(tableData)), set some set Factories, to give user ability to edit data, and to have this edited data in my tableData object;
Here are some code ive tried to make for this purpose:
//prepare my table
private void createTableHeader(TableView table, List<Attribute> ias) {
int i = 0;
for (final Attribute ia : ias) {
final int j = i;
i++;
TableColumn tc = new TableColumn(ia.getName());
tc.setSortable(true);
tc.setCellValueFactory(new Callback<CellDataFeatures<List<Attribute>, String>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(CellDataFeatures<List<Attribute>, String> arg0) {
if(arg0.getValue().get(j).getSupportingInfo() == null){
arg0.getValue().get(j).setSupportingInfo(new SupportingInfo());
}
return new SimpleObjectProperty(arg0.getValue().get(j),"value");
}
});
table.getColumns().add(tc);
}
}
//loading some data to my tableView
private void createTableBody(TableView curTable, List<Row> rows) {
ObservableList<List<Attribute>> data = FXCollections.observableArrayList();
for (Row row : rows) {
data.add(row.getColumns());
}
curTable.setItems(data);
}
//this one is to define some extra controls for editing data in a table by users
private void makeCellFactory(TableColumn curTableCol, final Attribute templateIa, final Document doc) {
curTableCol.setCellFactory(new Callback<TableColumn, TableCell>() {
public TableCell call(TableColumn p) {
final EditingCell cell = new EditingCell(templateIa, doc);
return cell;
}
});
}
But, as a result, i have just empty rows in my table, with an ability to click some cell and recieve table editing controls. But there is not defult values in by table;
What am i doing wrong in my code?
Ok, i've found a solution:
ts.setCellFactory should look like this:
tc.setCellValueFactory(new Callback<CellDataFeatures<List<Attribute>, SupportingInfo>, ObservableValue<Attribute>>() {
#Override
public ObservableValue<Attribute> call(CellDataFeatures<List<Attribute>, SupportingInfo> arg0) {
return new SimpleObjectProperty(arg0.getValue().get(j),"value",arg0.getValue().get(j));
}
});
Also, this code is needed to catch new values and put the incoming data to the table:
tc.setOnEditCommit(new EventHandler<CellEditEvent<List<Attribute>, Attribute>>() {
#Override
public void handle(CellEditEvent<List<Attribute>, Attribute> t) { t.getTableView().getItems().get(t.getTablePosition().getRow()).get(j).setSupportingInfo(t.getNewValue().getSupportingInfo());
}
});

Resources