JavaFX tableView not populating, can't see mistake - javafx

I can't figure out why my TableView is not setting the data. Seemingly everything is ok, but the rows just won't appear. i looked through tutorials, but I still don't see my error.Here is my code.
The data class:
package model.elastic;
import javafx.beans.property.SimpleStringProperty;
public class ElasticAttribute {
private SimpleStringProperty name;
private SimpleStringProperty type;
private SimpleStringProperty variable;
public ElasticAttribute(String name, String type, String variable) {
this.name = new SimpleStringProperty(name);
this.type = new SimpleStringProperty(type);
this.variable = new SimpleStringProperty(variable);
}
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
public String getType() {
return type.get();
}
public void setType(String type) {
this.type.set(type);
}
public String getVariable() {
return variable.get();
}
public void setVariable(String variable) {
this.variable.set(variable);
}
}
The controller:
#FXML
private TableView<ElasticAttribute> tableView;
private TableColumn tableColumnName;
private TableColumn tableColumnType;
private TableColumn tableColumnVariable;
public void initialize() {
final ObservableList<ElasticAttribute> data = FXCollections.observableArrayList(
new ElasticAttribute("Test", "Test", "Test"),
new ElasticAttribute("Test2", "Test", "Test"),
new ElasticAttribute("Test3", "Test", "Test"),
new ElasticAttribute("Test4", "Test", "Test"),
new ElasticAttribute("Test5", "Test", "Test")
);
tableColumnName = new TableColumn("Name");
tableColumnName.setCellValueFactory(
new PropertyValueFactory<ElasticAttribute, String>("name"));
tableColumnType = new TableColumn("Type");
tableColumnType.setCellValueFactory(
new PropertyValueFactory<ElasticAttribute, String>("type"));
tableColumnVariable = new TableColumn("Variable");
tableColumnVariable.setCellValueFactory(
new PropertyValueFactory<ElasticAttribute, String>("variable"));
tableView.setItems(data);
tableView.getColumns().addAll(tableColumnName, tableColumnType, tableColumnVariable);
The fxml:
<TableView fx:id="tableView" GridPane.rowIndex="1">
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY"/>
</columnResizePolicy>
</TableView>
Thanks for help.

Related

How to change values in tableview simultaneously whenever i select an corresponding item from comboboxtablecell

I tried but I got stuck at a point where am getting the corresponding values of the selected item from comboboxtablecell but cannot add the values to the corresponding column in the table view
Controller.java
public class controller {
GetConnection gc = new GetConnection();
PreparedStatement pst;
ResultSet rs;
Statement st;
private ObservableList<Users> datas = FXCollections.observableArrayList();
public controller(){}
#FXML
private TableView<Users> table;
#FXML
private TableColumn<Users,String> c1;
#FXML
private TableColumn<Users,String> c2;
#FXML
private TableColumn<Users,String> c3;
#FXML
private void editable() {
try {
ObservableList<Users> datas = FXCollections.observableArrayList();
ObservableList<String> item = FXCollections.observableArrayList();
ObservableList<String> iprice = FXCollections.observableArrayList();
String sql = "select * from itemsadd";
pst = gc.getConnection().prepareStatement(sql);
rs = pst.executeQuery();
while (rs.next()) {
String name = rs.getString("itemcode");
String cat=rs.getString("unitprice");
item.add(name);
iprice.add(cat);
System.out.println("probs" + item);
}
ResultSet rs2 = gc.getConnection().createStatement()
.executeQuery("SELECT * FROM itemsadd WHERE itemcode=1001");
while (rs2.next()) {
datas.add(new Users(rs2.getString("itemcode"),rs2.getString("category"),rs2.getString("unitprice")));
}
c1.setCellValueFactory(new PropertyValueFactory("Itemc"));
c1.setCellFactory(ComboBoxTableCell.forTableColumn(item));
for(String name:item){
c1.setCellValueFactory(new PropertyValueFactory("Itemc"));
c1.setCellFactory(ComboBoxTableCell.forTableColumn(item));
System.out.println("hell3"+name);
}c1.setOnEditCommit( ( TableColumn.CellEditEvent<Users, String> e ) ->
{
String newValue = e.getNewValue();
int index = e.getTablePosition().getRow();
System.out.println("position"+index);
try{
System.out.println("new values"+newValue);
String dsql="SELECT category,unitprice FROM itemsadd WHERE itemcode=?;";
pst=gc.getConnection().prepareStatement(dsql);
pst.setString(1, newValue); //this replaces the 1st "?" in the query for username
rs=pst.executeQuery();
while(rs.next())
{
String category1 = rs.getString(1);
String price1 = rs.getString(2);
System.out.println("category is"+category1);
System.out.println("unitprice is"+price1);
}
}catch(Exception ed){} } );
c2.setCellValueFactory(new PropertyValueFactory("category"));
c2.setCellFactory(TextFieldTableCell.forTableColumn());
c3.setCellValueFactory(new PropertyValueFactory("unitprice"));
c3.setCellFactory(ComboBoxTableCell.forTableColumn(iprice));
table.setEditable(true);
table.getItems().clear();
table.setItems(datas);
} catch (Exception e) {
e.printStackTrace();
System.out.println("Error on Building Data");
}
}
public static class Users {
private StringProperty Itemc;
private StringProperty category;
private StringProperty unitprice;
private Users(String Itemc,String category,String unitprice) {
this.Itemc= new SimpleStringProperty(Itemc);
this.category=new SimpleStringProperty(category);
this.unitprice=new SimpleStringProperty(unitprice);
}
public String getItemc() {
return Itemc.get();
}
public void setItemc(String Itemc) {
this.Itemc.set(Itemc);
}
public StringProperty ItemcProperty() {
return Itemc;
}
public String getcategory() {
return category.get();
}
public void setcategory(String category) {
this.category.set(category);
}
public StringProperty categoryProperty() {
return category;
}
public String getunitprice() {
return unitprice.get();
}
public void setunitprice(String unitprice) {
this.unitprice.set(unitprice);
}
public StringProperty unitpriceProperty() {
return unitprice;
}}
}
Table.fxml
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication47.controller">
<children>
<TableView fx:id="table" editable="true" layoutX="136.0" layoutY="58.0" onKeyPressed="#editable" prefHeight="200.0" prefWidth="335.0">
<columns>
<TableColumn fx:id="c1" prefWidth="116.0" text="Code" />
<TableColumn fx:id="c2" prefWidth="115.0" text="Address" />
<TableColumn fx:id="c3" prefWidth="102.0" text="Price" />
</columns>
</TableView>
</children>
</AnchorPane>
Tableview.java
public class Tableveiw extends Application {
private Stage primaryStage;
private AnchorPane pane;
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("AddressApp");
showPerson();
}
public void showPerson() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Tableveiw.class
.getResource("table.fxml"));
pane= (AnchorPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(pane);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}}
public static void main(String[] args) {
launch(args);
}
}
GetConnection.java
public class GetConnection{
public Connection getConnection() throws Exception
{
Connection con=null;
try {
System.out.println("MySQL Connect Example.");
String url = "jdbc:mysql://localhost:3306/";
String dbName = "login";
String driver = "com.mysql.jdbc.Driver";
Class.forName(driver).newInstance();
con = DriverManager.getConnection(url+dbName,"root","");
} catch (Exception e) {
e.printStackTrace();
}
return con;
}
public static void main(String arg[])
{
GetConnection con =new GetConnection();
System.out.println("Connection"+con);
}
}
The above code is runnable and simplified and the program has a tableview and three column with first columncell is a comboboxtablecell having items in it.The second columncell is a editable text field and third column cell is a comboboxtablecell with its items in database.I have tried myself where am getting values of the corresponding values in the row whenever I select value in combo box table cell in category.java System.out.println("categoryis"+category1);
System.out.println("unitprice is"+price1); .Please help me to change values in tableview whenever I select item in the combobox in table view.
You need to
Go to your cell factory code
1add event handler for combobox selection change
Get current row
Get current item
Change the value you need
Sample ComboBox Selected items changing values of tableview example.
Tablecombo.java
public class Tablecombo extends Application {
Stage primaryStage;
Scene scene;
String username;
AnchorPane anchorpane;
BorderPane borderpane;
// Pane pane;
BorderPane border;
Stage sstage;
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("Login");
root();
}
public void root() {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(Tablecombo.class.getResource("tcombo.fxml"));
anchorpane = (AnchorPane) loader.load();
Stage dialogStage = new Stage();
dialogStage.setTitle("Main");
dialogStage.initModality(Modality.WINDOW_MODAL);
Scene scene = new Scene(anchorpane);
dialogStage.setScene(scene);
dialogStage.showAndWait();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
tablecontroller.java
public class tablecontroller {
Tablecombo main;
GetConnection gc = new GetConnection();
PreparedStatement pst;
ResultSet rs;
public tablecontroller(){
}
#FXML
private TableView<UserData> table4;
#FXML
private TableColumn<UserData,String> c1;
#FXML
private TableColumn<UserData,String> c2;
#FXML
private void editable() {
try {
ObservableList<UserData> datas = FXCollections.observableArrayList();
ObservableList<String> names = FXCollections.observableArrayList();
ObservableList<String> rat = FXCollections.observableArrayList();
// ObservableList<Users> datas = FXCollections.observableArrayList();
String sql = "select * from pdfs";
// String msql="select * from category";
pst = gc.getConnection().prepareStatement(sql);
rs = pst.executeQuery();
while (rs.next()) {
String name = rs.getString("name");
String cat=rs.getString("country");
rat.add(cat);
names.add(name);
System.out.println("probs" + names);
}
ResultSet rs2 = gc.getConnection().createStatement().executeQuery("SELECT * FROM pdfs LIMIT 1");
//ObservableList<Users> datas = FXCollections.observableArrayList();
while (rs2.next()) {
datas.add(new UserData(rs2.getString("name"),rs2.getString("country")));
}
c1.setCellValueFactory(new PropertyValueFactory("Itemc"));
c1.setCellFactory(ComboBoxTableCell.forTableColumn(names));
for(String name:names){
c1.setCellValueFactory(new PropertyValueFactory("Itemc"));
// System.out.println("hell2"+name);
c1.setCellFactory(ComboBoxTableCell.forTableColumn(names));
System.out.println("hell3"+name);
}
c1.setOnEditCommit( ( TableColumn.CellEditEvent<UserData, String> e ) ->
{
String newValue = e.getNewValue();
int index = e.getTablePosition().getRow();
System.out.println("position"+index);
try{
ObservableList<UserData> data = FXCollections.observableArrayList();
System.out.println("new values"+newValue);
String dsql="SELECT * FROM pdfs WHERE name=?;";
pst=gc.getConnection().prepareStatement(dsql);
System.out.println("quer"+dsql);
pst.setString(1, newValue); //this replaces the 1st "?" in the query for username
rs=pst.executeQuery();
while(rs.next())
{
data.add(new UserData(rs.getString("name"),rs.getString("country")));
}
table4.setItems(data);
String a = rs.getString(1);
String b = rs.getString(2);
String c = rs.getString(3);
System.out.println("su"+a);
System.out.println("ma"+b);
System.out.println("man"+c);
}catch(Exception ed){} } );
c2.setCellValueFactory(new PropertyValueFactory("quantity"));
c2.setCellFactory(TextFieldTableCell.forTableColumn());
table4.setEditable(true);
table4.setItems(datas);
} catch (Exception e) {
e.printStackTrace();
System.out.println("Error on Building Data");
}
}
}
UserData.java
public class UserData {
private StringProperty Itemc;
private StringProperty quantity;
public UserData(String Itemc,String quantity) {
//this.Quantity = new SimpleStringProperty(Quantity);
this.Itemc= new SimpleStringProperty(Itemc);
this.quantity = new SimpleStringProperty(quantity);
}
public String getItemc() {
return Itemc.get();
}
public void setItemc(String Itemc) {
this.Itemc.set(Itemc);
}
public StringProperty ItemcProperty() {
return Itemc;
}
public void setquantity(String quantity) {
this.quantity.set(quantity);
}
public String getquantity() {
return quantity.get();
}
public StringProperty quantityProperty() {
return quantity;
}
}
tcombo.fxml
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="tablecombo.tablecontroller">
<children>
<TableView fx:id="table4" layoutX="168.0" layoutY="81.0" onKeyPressed="#editable" prefHeight="200.0" prefWidth="230.0">
<columns>
<TableColumn fx:id="c1" prefWidth="75.0" text="name" />
<TableColumn fx:id="c2" prefWidth="75.0" text="country" />
</columns>
</TableView>
</children>
</AnchorPane>

Having trouble retrieving value from tableview

I'm having having trouble getting a correct output from tableview. I'm using a button to set one item from tableview to a label. However, it prints "StringProperty [Value pineapples]" where I would like it to be just "pineapples".
The tableview gives them correctly.
public class ProductListController implements Initializable {
#FXML public TableView<Model> tableview ;
#FXML private TableColumn<Model, Number> ProductID;
#FXML private TableColumn<Model, String> ProductName;
#FXML private TableColumn<Model, Number> ProductPrice;
#FXML private Label lblProduct;
#FXML private Label lblPrice;
#FXML
private void btnActionShow(ActionEvent event) {
assert tableview !=null : " ";
ProductID.setCellValueFactory(cellData -> cellData.getValue().ProductIDProperty());
ProductName.setCellValueFactory(cellData -> cellData.getValue().ProductNameProperty());
ProductPrice.setCellValueFactory(cellData -> cellData.getValue().ProductPriceProperty());
buildData();
}
private ObservableList<Model> data;
public void buildData(){
data = FXCollections.observableArrayList();
try{
Connection conn = DriverManager.getConnection
("jdbc:derby://localhost:1527/Stock", "*****", "*****");
Statement stmt = conn.createStatement();
String SQL = "SELECT * FROM PRODUCTS";
ResultSet rs = stmt.executeQuery(SQL);
while (rs.next()) {
Model mod = new Model();
mod.ProductID.set(rs.getInt("ID"));
mod.ProductName.set(rs.getString("NAME"));
mod.ProductPrice.set(rs.getInt("SELL_PRICE"));
data.add(mod);
}
tableview.setItems(data);
}
catch ( SQLException err) {
System.out.println(err.getMessage() );
}
}
//Button to fetch data from Tableview. Sets the data not the way I want.
#FXML
private void btnConfirmAction(ActionEvent event) {
Model model = tableview.getSelectionModel().getSelectedItem();
String prd;
prd = model.getProductName().toString();
lblProduct.setText(prd);
}
#FXML
private void btnNextAction(ActionEvent event) {
try{
FXMLLoader loader = new FXMLLoader(getClass().getResource("/appl/Discount.fxml"));
Parent parent = loader.load();
DiscountController discountcontr = loader.getController();
discountcontr.setProduct(tableview.getSelectionModel().getSelectedItem().getProductName().toString());
Stage stage = new Stage();
Scene scene = new Scene(parent);
stage.setScene(scene);
stage.show();
}
catch(IOException e){
}
}
#Override
public void initialize(URL url, ResourceBundle rb) {
}
}
Model
public class Model {
public SimpleIntegerProperty ProductID = new SimpleIntegerProperty();
public SimpleStringProperty ProductName = new SimpleStringProperty ();
public SimpleIntegerProperty ProductPrice = new SimpleIntegerProperty();
private final SimpleBooleanProperty Checked = new SimpleBooleanProperty(false);
public SimpleBooleanProperty checkedProperty() {
return this.Checked;
}
public java.lang.Boolean getChecked() {
return this.checkedProperty().get();
}
public void setChecked(final java.lang.Boolean checked) {
this.checkedProperty().set(checked);
}
public SimpleIntegerProperty getProductID() {
return ProductID;
}
public SimpleStringProperty getProductName() {
return ProductName;
}
public SimpleIntegerProperty getProductPrice() {
return ProductPrice;
}
Since getProductName() returns a SimpleStringProperty, you need to retrieve the String from it using the get(). Just use :
String prd = model.getProductName().get();
Your model is implemented incorrectly. You should use the following pattern:
public class Model {
private SimpleStringProperty productName = new SimpleStringProperty();
public SimpleStringProperty productNameProperty() {
return productName ;
}
public final String getProductName() {
return productNameProperty().get();
}
public final void setProductName(String productName) {
productNameProperty().set(productName);
}
}
and similarly for the other properties.
If you use the e(fx)clipse plugin, you can generate the methods automatically from the property definition by right-clicking, choosing "Source" and then "Generate JavaFX Getters and Setters". I think NetBeans has similar functionality.

Why isn't the TableView getting populated?

I'm trying to build an audio library using javafx and scene builder.
This is my relevant bit from my fxml file:
TableView fx:id="tableView" layoutX="45.0" layoutY="85.0" prefHeight="481.0" prefWidth="573.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn prefWidth="154.0" text="Album" />
<TableColumn prefWidth="160.0" text="Songs" />
<TableColumn prefWidth="133.0" text="Artist" />
<TableColumn prefWidth="125.0" text="Genre" />
</columns>
</TableView>
It is linked with my controller class.
This is the data I am trying to populate it with from my Controller class:
final ObservableList<Integer> ratingSample = FXCollections.observableArrayList(1, 2, 3, 4, 5);
ObservableList<String> artists = FXCollections.observableArrayList("Adele",
"Unknown", "Beyonce", "Rihanna", "Avril", "Disturbia", "Kid Rock", "Jessi J", "Unknown", "Unknown");
final ObservableList<Integer> ratingSample = FXCollections.observableArrayList(1, 2, 3, 4, 5);
ObservableList<String> artists = FXCollections.observableArrayList("Adele",
"Unknown", "Beyonce", "Rihanna", "Avril", "Disturbia", "Kid Rock", "Jessi J", "Unknown", "Unknown");
ObservableList<String> titles = FXCollections.observableArrayList("Running in the Deep",
"Title 01","Title 09","What's my name","What the Hell","Disturbia","Kid Rock","Price Tag","Title 2","09");
#FXML
TableView<Music> table = new TableView<>();
#FXML
private TableView<Music> tblViewer = new TableView<Music>();
#FXML
TableColumn<Music, Album> albumArt = new TableColumn<Music, Album>("Album Art");
#FXML
TableColumn<Music, String> title = new TableColumn<Music, String>("Title");
#FXML
TableColumn<Music, String> artist = new TableColumn<Music, String>("Artist");
#FXML
TableColumn<Music, Integer> rating = new TableColumn<Music, Integer>("Rating");
#FXML
public TableView getTableView() {
albumArt.setCellValueFactory(new PropertyValueFactory("album"));
title.setCellValueFactory(new PropertyValueFactory("title"));
artist.setCellValueFactory(new PropertyValueFactory("artist"));
rating.setCellValueFactory(new PropertyValueFactory("rating"));
// SETTING THE CELL FACTORY FOR THE ALBUM ART
albumArt.setCellFactory(new Callback<TableColumn<Music, Album>, TableCell<Music, Album>>() {
#Override
public TableCell<Music, Album> call(TableColumn<Music, Album> param) {
TableCell<Music, Album> cell = new TableCell<Music, Album>() {
#Override
public void updateItem(Album item, boolean empty) {
if (item != null) {
HBox box = new HBox();
box.setSpacing(10);
VBox vbox = new VBox();
vbox.getChildren().add(new Label(item.getArtist()));
vbox.getChildren().add(new Label(item.getAlbum()));
ImageView imageview = new ImageView();
imageview.setFitHeight(50);
imageview.setFitWidth(50);
imageview.setImage(new Image(MusicTable.class.getResource("img").toString() + "/" + item.getFilename()));
box.getChildren().addAll(imageview, vbox);
//SETTING ALL THE GRAPHICS COMPONENT FOR CELL
setGraphic(box);
}
}
};
System.out.println(cell.getIndex());
return cell;
}
});
// SETTING THE CELL FACTORY FOR THE RATINGS COLUMN
rating.setCellFactory(new Callback<TableColumn<Music, Integer>, TableCell<Music, Integer>>() {
#Override
public TableCell<Music, Integer> call(TableColumn<Music, Integer> param) {
TableCell<Music, Integer> cell = new TableCell<Music, Integer>() {
#Override
public void updateItem(Integer item, boolean empty) {
if (item != null) {
ChoiceBox choice = new ChoiceBox(ratingSample);
choice.getSelectionModel().select(ratingSample.indexOf(item));
//SETTING ALL THE GRAPHICS COMPONENT FOR CELL
setGraphic(choice);
}
}
};
return cell;
}
});
//ADDING ALL THE COLUMNS TO TABLEVIEW
table.getColumns().addAll(albumArt, title, artist, rating);
//ADDING ROWS INTO TABLEVIEW
ObservableList<Music> musics = FXCollections.observableArrayList();
for (int i = 0; i < 10; i++) {
Album al = new Album(i + 1 + ".jpg", artists.get(i), artists.get(i));
Music m = new Music(artists.get(i),al,titles.get(i),i%5);
musics.add(m);
}
table.setItems(musics);
return table;
}
Music class:
package sample;
import javafx.beans.property.*;
public class Music {
//Properties
private SimpleStringProperty artist = new SimpleStringProperty();
private ObjectProperty albumArt= new SimpleObjectProperty();
private StringProperty title= new SimpleStringProperty();
public Music(String artist, Album album, String title, int year) {
setArtist(artist);
setAlbum(album);
setTitle(title);
/*setGenre (genre);
setYear(year);
setRating(rating);*/
}
//ARTIST -----------
public void setArtist(String art){
artist.set(art);
}
public String getArtist(){
return artist.get();
}
public StringProperty artistProperty(){
return artist;
}
//ALBUM ------------
public void setAlbum(Album alb){
albumArt.set(alb);
}
public Object getAlbum(){
return albumArt.get();
}
public ObjectProperty albumProperty(){
return albumArt;
}
//TITLE -------------
public void setTitle(String tit){
title.set(tit);
}
public String getTitle(){
return title.get();
}
public StringProperty titleProperty(){
return title;
}
/*//GENRE --------------
public void setGenre(String gen){
genre.set(gen);
}
public String setGenre(){
return genre.get();
}
public StringProperty genreProperty(){
return genre;
}
//YEAR --------------
public void setYear(int yea){
year.set(yea);
}
public Integer getYear(){
return year.get();
}
public IntegerProperty yearProperty(){
return year;
}
//RATING --------------
public void setRating(int rat){
rating.set(rat);
}
public Integer getRating(){
return rating.get();
}
public IntegerProperty ratingProperty(){
return rating;
}
*/
}
So, the code runs, but no data is shown on the table.
I have tried quite a few versions of this. However nothing seems to work. Could somebody help me understand what I am doing wrong?

How see content column selecting with cursor

I need to know how I can view the contents of a cell depending on which is selected. I have to return the value of idPerson with method btnClick.
Thus goes the memory address but I want to return the id value I have selected
Thanks.
public class TablaFXML {
#FXML
TableView tablePeople;
#FXML
TableColumn idPersonColumn;
#FXML
TableColumn nameColumn;
#FXML
TableColumn surnameColumn;
#FXML
TableColumn emailColumn;
#FXML
TextArea textArea;
#FXML
Person pers;
#FXML
void initialize() {
ObservableList<Person> data = FXCollections.observableArrayList(
new Person("1", "Jacob", "Smith", "jacob.smith#example.com"),
new Person("2", "Isabella", "Johnson", "isabella.johnson#example.com"),
new Person("3", "Ethan", "Williams", "ethan.williams#example.com"),
new Person("4", "Emma", "Jones", "emma.jones#example.com"),
new Person("5", "Michael", "Brown", "michael.brown#example.com")
);
idPersonColumn
.setCellValueFactory(new PropertyValueFactory("idPerson"));
nameColumn.setCellValueFactory(new PropertyValueFactory("name"));
surnameColumn.setCellValueFactory(new PropertyValueFactory("surname"));
emailColumn.setCellValueFactory(new PropertyValueFactory("email"));
tablePeople.setItems(data);
}
#FXML public void btnIdClick(){
//int guardar = tablePeople.getSelectionModel().getFocusedIndex();
System.out.println(tablePeople.getSelectionModel().getSelectedItem());
}
}
public class Person {
private StringProperty idPerson;
private StringProperty name;
private StringProperty surname;
private StringProperty email;
public Person(String id,String fName, String lName, String email) {
this.idPerson = new SimpleStringProperty(id);
this.name = new SimpleStringProperty(fName);
this.surname = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}
public StringProperty idPersonProperty() { return idPerson; }
public StringProperty nameProperty() { return name; }
public StringProperty surnameProperty() { return surname; }
public StringProperty emailProperty() { return email; }
}
You are seeing the results of calling the toString() method on the Person object returned from the selection model. As you haven't overridden the toString() method, you are getting the result of the default toString method defined in Object, which displays the class name and hashCode.
You can either add a toString method to the Person class:
public class Person {
// ... all code as before
#Override
public String toString() {
return name.get() + " " + surname.get(); // any implementation you need
}
}
or just extract the data you need when you need it:
#FXML public void btnIdClick() {
Person selectedPerson = tablePeople.getSelectionModel().getSelectedItem() ;
System.out.println(selectedPerson.firstNameProperty().get() + " " +
selectedPerson.lastNameProperty().get());
}

Javafx Editable Table cell

I have tables with editable fields firstName,lastName and fullName.
I am creating a cellFactory and Column like this
public class SampleFX1 extends Application {
private TableView table = new TableView();
private final ObservableList<Person> data =
FXCollections.observableArrayList( new Person("balu", "Smith","1"), new Person("Isabella", "john","1"),
new Person("Ethan", "Williams","1"), new Person("Emma", "Jones","1"), new Person("Michael", "Brown","1"));
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
TableColumn firstNameCol = createSimpleFirstNameColumn();
TableColumn lastNameCol = createLastNameColumn();
TableColumn fullNameCol = createfullNameColumn();
table.setItems(data);
table.getColumns().addAll(firstNameCol, lastNameCol,fullNameCol);
table.setEditable(true);
((Group) scene.getRoot()).getChildren().addAll(table);
stage.setScene(scene);
stage.show();
}
private TableColumn createSimpleFirstNameColumn() {
TableColumn firstNameCol = new TableColumn("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));
firstNameCol.setCellFactory(TextFieldTableCell.forTableColumn());
firstNameCol.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Person, String>>() {
#Override
public void handle(TableColumn.CellEditEvent<Person, String> t) {
t.getRowValue().setFirstName(t.getNewValue());
}
});
return firstNameCol;
}
private TableColumn createLastNameColumn() {
Callback<TableColumn, TableCell> editableFactory = new Callback<TableColumn, TableCell>() {
#Override
public TableCell call(TableColumn p) {
return new EditingCell();
}
};
TableColumn lastNameCol = new TableColumn("Last Name");
lastNameCol.setMinWidth(100);
lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName"));
lastNameCol.setCellFactory(editableFactory);
lastNameCol.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Person, String>>() {
#Override
public void handle(TableColumn.CellEditEvent<Person, String> t) {
System.out.println( "Commiting last name change. Previous: " + t.getOldValue() + " New: " + t.getNewValue() );
t.getRowValue().setLastName(t.getNewValue());
}
});
return lastNameCol;
}
private TableColumn createfullNameColumn() {
TableColumn firstNameCol = new TableColumn("full Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("fullName"));
firstNameCol.setCellFactory(TextFieldTableCell.forTableColumn());
firstNameCol.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Person, String>>() {
#Override
public void handle(TableColumn.CellEditEvent<Person, String> t) {
t.getRowValue().setfullName(t.getNewValue());
}
});
return firstNameCol;
}
}
Editing Cell :
public class EditingCell extends TableCell<Person, String> {
private TextField textField;
public EditingCell() {
}
#Override
public void startEdit() {
super.startEdit();
if( textField == null ) {
createTextField();
}
setText(null);
setGraphic(textField);
textField.selectAll();
}
#Override
public void cancelEdit() {
super.cancelEdit();
setText((String) getItem());
setGraphic(null);
}
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
}
setText(null);
setGraphic(textField);
} else {
setText(getString());
setGraphic(null);
}
}
}
private void createTextField() {
textField = new TextField(getString());
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) {
if (!arg2) { commitEdit(textField.getText()); }
}
});
textField.setOnKeyReleased(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
String value = textField.getText();
if (value != null) { commitEdit(value); } else { commitEdit(null); }
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
}
Person Class:
import javafx.beans.property.SimpleStringProperty;
public class Person {
private SimpleStringProperty firstName;
private SimpleStringProperty lastName;
private SimpleStringProperty fullName;
public Person(String firstName, String lastName ,String fullName) {
this.firstName = new SimpleStringProperty(firstName);
this.lastName = new SimpleStringProperty(lastName);
this.fullName=new SimpleStringProperty(fullName);
}
public String getFirstName() { return firstName.get(); }
public void setFirstName(String firstName) { this.firstName.set(firstName); }
public SimpleStringProperty firstNameProperty() { return firstName; }
public String getLastName() { return lastName.get(); }
public void setLastName(String lastName) { this.lastName.set(lastName); }
public SimpleStringProperty lastNameProperty() { return lastName; }
public String getfullName() { return fullName.get(); }
public void setfullName(String lastName) { this.fullName.set(lastName); }
public SimpleStringProperty fullNameProperty() { return fullName; }
}
Question: How to Update fullName Column when I update firstName Column or Lastname Column (editable cells) without insert a row?
Use binding to derive the full name from first name and the last name.
fullName.bind(Bindings.concat(this.firstName, " ", this.lastName));
Person.java
import javafx.beans.binding.Bindings;
import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.property.SimpleStringProperty;
public class Person {
private SimpleStringProperty firstName;
private SimpleStringProperty lastName;
private ReadOnlyStringWrapper fullName = new ReadOnlyStringWrapper();
public Person(String firstName, String lastName) {
this.firstName = new SimpleStringProperty(firstName);
this.lastName = new SimpleStringProperty(lastName);
fullName.bind(Bindings.concat(this.firstName, " ", this.lastName));
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public SimpleStringProperty firstNameProperty() {
return firstName;
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public SimpleStringProperty lastNameProperty() {
return lastName;
}
public String getFullName() {
return fullName.get();
}
public ReadOnlyStringProperty fullNameProperty() {
return fullName.getReadOnlyProperty();
}
}
Redefine your createfullNameColumn() function. Now that fullName that it is a derived value from concatenating the firstName and the lastName, there is no need to allow a user to explicitly edit it.
private TableColumn createfullNameColumn() {
TableColumn fullNameCol = new TableColumn("Full Name");
fullNameCol.setMinWidth(100);
fullNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("fullName"));
return fullNameCol;
}
SampleFX1.java
Application code:
import javafx.application.Application;
import javafx.collections.*;
import javafx.event.EventHandler;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.control.cell.*;
import javafx.stage.Stage;
import javafx.util.Callback;
public class SampleFX1 extends Application {
private TableView table = new TableView();
private final ObservableList<Person> data =
FXCollections.observableArrayList(
new Person("balu", "Smith"),
new Person("Isabella", "john"),
new Person("Ethan", "Williams"),
new Person("Emma", "Jones"),
new Person("Michael", "Brown")
);
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
TableColumn firstNameCol = createSimpleFirstNameColumn();
TableColumn lastNameCol = createLastNameColumn();
TableColumn fullNameCol = createFullNameColumn();
table.setItems(data);
table.getColumns().addAll(firstNameCol, lastNameCol, fullNameCol);
table.setEditable(true);
((Group) scene.getRoot()).getChildren().addAll(table);
stage.setScene(scene);
stage.show();
}
private TableColumn createSimpleFirstNameColumn() {
TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));
firstNameCol.setCellFactory(TextFieldTableCell.forTableColumn());
firstNameCol.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Person, String>>() {
#Override
public void handle(TableColumn.CellEditEvent<Person, String> t) {
t.getRowValue().setFirstName(t.getNewValue());
}
});
return firstNameCol;
}
private TableColumn createLastNameColumn() {
Callback<TableColumn, TableCell> editableFactory = new Callback<TableColumn, TableCell>() {
#Override
public TableCell call(TableColumn p) {
return new EditingCell();
}
};
TableColumn lastNameCol = new TableColumn("Last Name");
lastNameCol.setMinWidth(100);
lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName"));
lastNameCol.setCellFactory(editableFactory);
lastNameCol.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Person, String>>() {
#Override
public void handle(TableColumn.CellEditEvent<Person, String> t) {
System.out.println("Commiting last name change. Previous: " + t.getOldValue() + " New: " + t.getNewValue());
t.getRowValue().setLastName(t.getNewValue());
}
});
return lastNameCol;
}
private TableColumn createFullNameColumn() {
TableColumn fullNameCol = new TableColumn("Full Name");
fullNameCol.setMinWidth(100);
fullNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("fullName"));
return fullNameCol;
}
}
EditingCell.java
(unchanged from question)
Update to answer additional user questions on the sample code
I was able to run createSimpleFirstNameColumn() even though there are plenty of warnings from eclipse, for example: TableColumn is a raw type. References to generic type TableColumn should be parameterized.
Original source code was adapted from the standard JavaFX TableView sample code, which at the time wasn't the best example of working with Generics. Generic type specification in Java is optional, but if you mix use an API which has generics specified, but don't supply the generic type information in the API usage, the compiler will issue warnings such as above. In general the warnings can be ignored or if you wish, though you do get a bit nicer type inference and compile time type checking if you explicitly specify type information.
Rather than just saying:
TableColumn firstNameCol = new TableColumn("First Name");
Warnings can be eliminated by explicitly specifying type information such as below:
TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
I have updated the sample code above to use this notation in the createSimpleFirstNameColumn() function.
Note the above code uses a Java 7 diamond notation, so the minimum language compilation level of the program must be set to at least Java 7.
However, in createLastNameColumn() the line with return new EditingCell();gives me an error that EditingCell cannot be resolved to a type.
I do not get this error. You probably have not included the EditingCell class defined in the original question in your project.
I am unable to leave a comment but in answer to this revised question :
I was able to run createSimpleFirstNameColumn() even though there are plenty of warnings from eclipse, for example: TableColumn is a raw type. References to generic type TableColumn should be parameterized.
Make sure that you have the correct import i.e.
import javafx.scene.control.TableColumn; and not anything from Java Swing.

Resources