Solution
You can retrieve the relevant field by calling the getter on the model object corresponding to the selected row.
In the code below the newValue.getId()
call is the key.
Without Java 8 lambdas:
final Label selected = new Label();
table.getSelectionModel().selectedItemProperty().addListener(
new ChangeListener<IdentifiedName>() {
@Override
public void changed(
ObservableValue<? extends IdentifiedName> observable,
IdentifiedName oldValue,
IdentifiedName newValue
) {
if (newValue == null) {
selected.setText("");
return;
}
selected.setText("Selected Number: " + newValue.getId());
}
}
);
With Java 8 lambdas:
final Label selected = new Label();
table.getSelectionModel().selectedItemProperty().addListener(
(observable, oldValue, newValue) -> {
if (newValue == null) {
selected.setText("");
return;
}
selected.setText("Selected Number: " + newValue.getId());
}
);
Sample Code
import javafx.application.Application;
import javafx.collections.*;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class TableViewSample extends Application {
private TableView<IdentifiedName> table = new TableView<>();
private final ObservableList<IdentifiedName> data =
FXCollections.observableArrayList(
new IdentifiedName(3, "three"),
new IdentifiedName(4, "four"),
new IdentifiedName(7, "seven"),
new IdentifiedName(8, "eight"),
new IdentifiedName(9, "nineses")
);
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
TableColumn<IdentifiedName, Integer> idColumn = new TableColumn<>("No");
idColumn.setMinWidth(100);
idColumn.setCellValueFactory(
new PropertyValueFactory<>("id")
);
TableColumn<IdentifiedName, String> nameColumn = new TableColumn<>("Name");
nameColumn.setMinWidth(100);
nameColumn.setCellValueFactory(
new PropertyValueFactory<>("name")
);
table.setItems(data);
table.getColumns().setAll(idColumn, nameColumn);
table.setPrefHeight(180);
final Label selected = new Label();
table.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
if (newValue == null) {
selected.setText("");
return;
}
selected.setText("Selected Number: " + newValue.getId());
});
final VBox layout = new VBox(10);
layout.setPadding(new Insets(10));
layout.getChildren().addAll(table, selected);
VBox.setVgrow(table, Priority.ALWAYS);
stage.setScene(new Scene(layout));
stage.show();
}
public static class IdentifiedName {
private final int id;
private final String name;
private IdentifiedName(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}
}
Answers to Additional Questions
check my updated question so I can't use this?
So in your update you can see that the type of each row's data is ObservableList<String>
, whereas in my answer the type is IdentifiedName
. To get the posted solution to work for your data type, the change is trivial. The equivalent of newValue.getId()
would be newValue.get(0)
, to return the first item in your list for the selected row.
final Label selected = new Label();
table.getSelectionModel().selectedItemProperty().addListener(
(observable, oldValue, newValue) -> {
if (newValue == null) {
selected.setText("");
return;
}
selected.setText("Selected Number: " + newValue.get(0));
}
);
or is it possible to use identifiedname class? then how?
Yes you could, but you would have to make extensive changes to your database fetching code to load the data created into an IdentifiedName
class rather than an ObservableList<String>
and doing so would lose the generic nature of your database loading code.
I implement your code into my project I got ... java.lang.ClassCastException:
You need to setup the type of your Table and columns correctly for your data types, not the sample ones I provided for my use case.
Replace these types:
TableView<IdentifiedName>
TableColumn<IdentifiedName, Integer>
With these types:
TableView<ObservableList<String>>
TableColumn<ObservableList<String>, String>
Minor advice
I advise taking a refresher by reading up on the Java Generics Trail. Tables in JavaFX are pretty complicated in their use of generics, but using correct generics in your table code can make it easier to write (as long as you are using a good IDE which is good at guessing the generics when needed).
You also might want to provide an minimal, complete, tested and readable example with future questions of this type (not all questions). Construction of one could help you solve your issues quicker. Also, ensuring your code has consistent indentation makes it easier to read.