Reputation: 79
I am stuck with one point in JAVAFX tableview in one of our javaFX application.I am using one table view to show some data. In that tableView one of the column have nested columns under it. These nested columns I am creating from one of the list. Now here I am putting my scenario with one example. Now here I have two columns in tableView. Name and Skillset. The skill set column have two nested columns under it. I am reading the nested column names from nestedColumnsNameList. I am trying to fill the values in these nested columns from a list skillList, which has two values [Java, Dot Net]. Now every time I try to fill the values in these nested columns from a skillList, for every row I am getting same value as Dot Net in each nested columns. Below is my code:
package demo.tableView;
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Spinner;
import javafx.scene.control.SpinnerValueFactory;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class UpdateTableViewDynamicColumns extends Application {
private TextField firtNameField = new TextField();
private TextField lastNameField = new TextField();
private TextField emailField = new TextField();
private TextField speedField = new TextField();
private TextField stopspeedField = new TextField();
private Stage editView;
private Person fPerson;
TableView<Person> table = new TableView<Person>();;
public static class Person {
private String name;
private String skillset;
private String skills;
/**
* @return the firstName
/**
* @return the skills
*/
public String getSkills() {
return skills;
}
/**
* @param skills the skills to set
*/
public void setSkills(String skills) {
this.skills = skills;
}
/**
* @return the skillset
*/
public String getSkillset() {
return skillset;
}
/**
* @param skillset the skillset to set
*/
public void setSkillset(String skillset) {
this.skillset = skillset;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
}
private final ObservableList<Person> data =
FXCollections.observableArrayList();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
stage.setWidth(535);
stage.setHeight(535);
editView = new Stage();
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
TableColumn firstNameCol = new TableColumn("Name");
firstNameCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("name"));
firstNameCol.setMinWidth(150);
/*
* this list contains the names of nested columns
*/
List<String> nestedColumnsNameList = new ArrayList<String>();
nestedColumnsNameList.add("Skill 1");
nestedColumnsNameList.add("Skill 2");
TableColumn skillSetCol = new TableColumn("Skillset");
skillSetCol.setMinWidth(200);
skillSetCol.setCellValueFactory(new PropertyValueFactory<Person, String>("skillset"));
for(int i=0;i<nestedColumnsNameList.size();i++){
TableColumn ageValCol = new TableColumn(nestedColumnsNameList.get(i));
ageValCol.setCellValueFactory(new PropertyValueFactory<Person, String>("skills"));
skillSetCol.getColumns().add(ageValCol);
}
int count = 3;
List<String> nameList = new ArrayList<String>();
nameList.add("Ajit Patil");
nameList.add("Ketan Mehta");
nameList.add("Jacob George");
/*
* the below list values will be set in skill columns skill1 , skill2
*/
List<String> skillList = new ArrayList<String>();
skillList.add("Java");
skillList.add("Dot net");
for(int i=0; i<nameList.size(); i++){
Person p = new Person();
p.setName(nameList.get(i));
for(int x=0; x<skillList.size();x++){
p.setSkills(skillList.get(x));
}
data.add(p);
}
table.setItems(data);
table.getColumns().addAll(firstNameCol, skillSetCol);
//--- create a edit button and a editPane to edit person
Button addButton = new Button("Add");
addButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
fPerson = null;
firtNameField.setText("");
lastNameField.setText("");
emailField.setText("");
editView.show();
}
});
Button editButton = new Button("Edit");
editButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
/*if (table.getSelectionModel().getSelectedItem() != null) {
fPerson = table.getSelectionModel().getSelectedItem();
firtNameField.setText(fPerson.getFirstName());
lastNameField.setText(fPerson.getLastName());
emailField.setText(fPerson.getEmail());
editView.show();
}*/
}
});
Button deleteButton = new Button("Delete");
deleteButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if (table.getSelectionModel().getSelectedItem() != null) {
data.remove(table.getSelectionModel().getSelectedItem());
}
}
});
Button setButton = new Button("Set");
setButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
Stage primaryStage = new Stage();
Spinner<Double> dspinner = new Spinner<>();
dspinner.setValueFactory(new SpinnerValueFactory.DoubleSpinnerValueFactory(0.0, Double.MAX_VALUE, 0.0, 1));
dspinner.setMaxWidth(60);
Button setButton = new Button("Set");
setButton.setMinWidth(50);
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(10));
grid.add(new Label("Set default speed [knots] : "), 0, 1);
grid.add(dspinner, 1, 1);
grid.add(setButton, 2, 1);
Scene scene = new Scene(grid, 300, 80);
primaryStage.setTitle("Set Default value for speed");
primaryStage.setScene(scene);
primaryStage.initModality(Modality.APPLICATION_MODAL);
primaryStage.show();
setButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
try {
setDefaultSpeed(dspinner);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void setDefaultSpeed(Spinner<Double> dspinner) {
// TODO Auto-generated method stub
}
});
}
});
HBox addEditDeleteButtonBox = new HBox();
addEditDeleteButtonBox.getChildren().addAll(addButton, editButton, deleteButton,setButton);
addEditDeleteButtonBox.setAlignment(Pos.CENTER_RIGHT);
addEditDeleteButtonBox.setSpacing(3);
GridPane editPane = new GridPane();
editPane.getStyleClass().add("editView");
editPane.setPadding(new Insets(3));
editPane.setHgap(5);
editPane.setVgap(5);
Label personLbl = new Label("Person:");
editPane.add(personLbl, 0, 1);
GridPane.setHalignment(personLbl, HPos.LEFT);
firtNameField.setPrefWidth(250);
lastNameField.setPrefWidth(250);
emailField.setPrefWidth(250);
Label firstNameLabel = new Label("First Name:");
Label lastNameLabel = new Label("Last Name:");
Label emailLabel = new Label("Email:");
Label speedLabel = new Label("Start Speed:");
Label speedLabel1 = new Label("stop Speed:");
editPane.add(firstNameLabel, 0, 3);
editPane.add(firtNameField, 1, 3);
editPane.add(lastNameLabel, 0, 4);
editPane.add(lastNameField, 1, 4);
editPane.add(emailLabel, 0, 5);
editPane.add(emailField, 1, 5);
editPane.add(speedLabel, 0, 6);
editPane.add(speedField, 1, 6);
editPane.add(speedLabel1, 0, 7);
editPane.add(stopspeedField, 1, 7);
GridPane.setHalignment(firstNameLabel, HPos.RIGHT);
GridPane.setHalignment(lastNameLabel, HPos.RIGHT);
GridPane.setHalignment(emailLabel, HPos.RIGHT);
GridPane.setHalignment(speedLabel, HPos.RIGHT);
Button saveButton = new Button("Save");
saveButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if (fPerson == null) {
fPerson = new Person(
/*firtNameField.getText(),
lastNameField.getText(),
emailField.getText(),Double.parseDouble(speedField.getText()),Double.parseDouble(stopspeedField.getText()),""*/);
data.add(fPerson);
} else {
int k = -1;
if (data.size() > 0) {
for (int i = 0; i < data.size(); i++) {
if (data.get(i) == fPerson) {
k = i;
}
}
}
fPerson.setName(firtNameField.getText());
data.set(k, fPerson);
table.setItems(data);
// The following will work, but edited person has to be added to the button
//
// data.remove(fPerson);
// data.add(fPerson);
// add and remove refresh the table, but now move edited person to original spot,
// it failed again with the following code
// while (data.indexOf(fPerson) != k) {
// int i = data.indexOf(fPerson);
// Collections.swap(data, i, i - 1);
// }
}
editView.close();
}
});
Button cancelButton = new Button("Cancel");
cancelButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
editView.close();
}
});
TitledBorder b = new TitledBorder();
HBox saveCancelButtonBox = new HBox();
saveCancelButtonBox.getChildren().addAll(saveButton, cancelButton);
saveCancelButtonBox.setAlignment(Pos.CENTER_RIGHT);
saveCancelButtonBox.setSpacing(3);
// saveCancelButtonBox.setBorder( new Border(new BorderStroke(Color.BLUE, BorderStrokeStyle.SOLID, null, new BorderWidths(3))));
VBox editBox = new VBox();
editBox.getChildren().addAll(editPane, saveCancelButtonBox);
Scene editScene = new Scene(editBox);
editView.setTitle("Person");
editView.initStyle(StageStyle.UTILITY);
editView.initModality(Modality.APPLICATION_MODAL);
editView.setScene(editScene);
editView.close();
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.getChildren().addAll(label, table, addEditDeleteButtonBox);
vbox.setPadding(new Insets(10, 0, 0, 10));
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
}
I am trying to fill different values -> java and dot net in skill 1 and skill 2 column. Kindly help in the same.
Upvotes: 0
Views: 3121
Reputation: 82491
You want to use multiple values. Therefore you cannot store the elements in a single String
field (at least not in a convenient way). You need to use a data type that supports multiple values, such as List<String>
. PropertyValueFactory
cannot handle this type however, so you need to use a custom cellValueFactory
:
public static class Person {
...
private final List<String> skills = new ArrayList<>();
public List<String> getSkills() {
return skills;
}
...
}
for (int i = 0; i < nestedColumnsNameList.size(); i++) {
final int index = i;
TableColumn<Person, String> ageValCol = new TableColumn<>(nestedColumnsNameList.get(i));
// get data from list using index
ageValCol.setCellValueFactory(cellData -> Bindings.createObjectBinding(() -> cellData.getValue().getSkills().get(index)));
skillSetCol.getColumns().add(ageValCol);
}
for (int i = 0; i < nameList.size(); i++) {
Person p = new Person();
p.setName(nameList.get(i));
p.getSkills().addAll(skillList);
data.add(p);
}
Upvotes: 1