TableVew - Select and focus clicked cell - java

I have an event listener on a TableView which listens for mouse events. How can I get the mouse clicked cell index (and change focus to the new cell) when a mouse event is thrown.
public class PrnTableController
{
#FXML
private TableView<SimpleStringProperty> table;
#FXML
private TableColumn<SimpleStringProperty, String> data;
#FXML
private void initialize()
{
this.data.setCellValueFactory(cellData -> cellData.getValue());
this.data.setCellFactory(event -> new EditCell(this.observablePrnPropertyData, this.table));
// Add mouse Listener
this.table.setOnMouseClicked(event -> this.handleOnMouseClick(event));
}
private void handleOnMouseClick(MouseEvent event)
{
TableView tv = (TableView) event.getSource();
// TODO : get the mouse clicked cell index
int index = ???
if (event.getButton().equals(MouseButton.PRIMARY))
{
if (event.getClickCount() == 2)
{
LOGGER.info("Double clicked on cell");
final int focusedIndex = this.table.getSelectionModel().getFocusedIndex();
if (index == focusedIndex)
{
// TODO : Double click
}
}
else if (event.getClickCount() == 1)
{
// TODO : Single click
}
}
}
}
I have managed to get the clicked cell index when the mouse event is on the Cell but not the table.
The following code can be used to get the clicked cell index when the event is on the Cell. I've had problems with selecting and changing focus when the mouse event is on TabelCell. The focus does not change to the new cell. It changes if you double click. With a single click nothing happens. I suspect thats because I have other event listeners, there may be conflicting events. I have the following event on the TableCell - setOnDragDetected, setOnMouseDragEntered and the following event on the TableView - addEventFilter, setOnKeyPressed, setOnEditCommit.
TableCell<Map<String, SimpleStringProperty>, String> cell = (TableCell<Map<String, SimpleStringProperty>, String>) mouseEvent.getSource();
int index = cell.getIndex();
Here is an example with the problem. Basically when you click on an cell, you can see that the event is registered but nothing happens. I mean the focus does change to the newly clicked cell.
public class TableViewEditOnType extends Application
{
private TableView<Person> table;
private ObservableList<Person> observableListOfPerson;
#Override
public void start(Stage primaryStage)
{
this.table = new TableView<>();
this.table.getSelectionModel().setCellSelectionEnabled(true);
this.table.setEditable(true);
TableColumn<Person, String> firstName = this.createColumn("First Name", Person::firstNameProperty);
TableColumn<Person, String> lastName = this.createColumn("Last Name", Person::lastNameProperty);
TableColumn<Person, String> email = this.createColumn("Email", Person::emailProperty);
this.table.getColumns().add(firstName);
this.table.getColumns().add(lastName);
this.table.getColumns().add(email);
this.observableListOfPerson = FXCollections.observableArrayList();
this.observableListOfPerson.add(new Person("Jacob", "Smith", "jacob.smith#example.com"));
this.observableListOfPerson.add(new Person("Isabella", "Johnson", "isabella.johnson#example.com"));
this.observableListOfPerson.add(new Person("Ethan", "Williams", "ethan.williams#example.com"));
this.observableListOfPerson.add(new Person("Emma", "Jones", "emma.jones#example.com"));
this.observableListOfPerson.add(new Person("Michael", "Brown", "michael.brown#example.com"));
this.table.getItems().addAll(this.observableListOfPerson);
firstName.setOnEditCommit(event -> this.editCommit(event, "firstName"));
lastName.setOnEditCommit(event -> this.editCommit(event, "lastName"));
email.setOnEditCommit(event -> this.editCommit(event, "email"));
this.table.setOnKeyPressed(event -> {
TablePosition<Person, ?> pos = this.table.getFocusModel().getFocusedCell();
if (pos != null)
{
this.table.edit(pos.getRow(), pos.getTableColumn());
}
});
Scene scene = new Scene(new BorderPane(this.table), 880, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
private void editCommit(CellEditEvent<Person, String> event, String whatEdited)
{
if (whatEdited.equals("firstName"))
{
event.getTableView().getItems().get(event.getTablePosition().getRow()).setFirstName(event.getNewValue());
}
else if (whatEdited.equals("lastName"))
{
event.getTableView().getItems().get(event.getTablePosition().getRow()).setLastName(event.getNewValue());
}
else if (whatEdited.equals("email"))
{
event.getTableView().getItems().get(event.getTablePosition().getRow()).setEmail(event.getNewValue());
}
}
private TableColumn<Person, String> createColumn(String title, Function<Person, StringProperty> property)
{
TableColumn<Person, String> col = new TableColumn<>(title);
col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
col.setCellFactory(column -> new EditCell(property, this.table, this.observableListOfPerson));
return col;
}
private static class EditCell extends TableCell<Person, String>
{
private final TextField textField = new TextField();
private final Function<Person, StringProperty> property;
private TableView table;
private ObservableList<Person> observableListOfPerson;
EditCell(Function<Person, StringProperty> property, TableView table, ObservableList<Person> observableListOfPerson)
{
this.property = property;
this.table = table;
this.observableListOfPerson = observableListOfPerson;
this.textProperty().bind(this.itemProperty());
this.setGraphic(this.textField);
this.setContentDisplay(ContentDisplay.TEXT_ONLY);
this.textField.setOnAction(evt -> {
this.commitEdit(this.textField.getText());
});
this.textField.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
if (!isNowFocused)
{
this.commitEdit(this.textField.getText());
}
});
// On mouse click event
this.setOnMouseClicked(mouseEvent -> this.handleCellMouseClick(mouseEvent));
}
private void handleCellMouseClick(final MouseEvent mouseEvent)
{
System.out.println("MOUSE EVENT");
TableCell<Map<String, SimpleStringProperty>, String> cell = (TableCell<Map<String, SimpleStringProperty>, String>) mouseEvent.getSource();
int index = cell.getIndex();
// Set up the map data structure before editing
this.validCell(index);
if (mouseEvent.getButton().equals(MouseButton.PRIMARY))
{
if (mouseEvent.getClickCount() == 2)
{
System.out.println("Double clicked on cell");
final int focusedIndex = this.table.getSelectionModel().getFocusedIndex();
if (index == focusedIndex)
{
this.changeTableCellFocus(this.table, index);
}
}
else if (mouseEvent.getClickCount() == 1)
{
System.out.println("Single click on cell");
this.changeTableCellFocus(this.table, index);
}
}
}
private void validCell(final int cellIndex)
{
if (cellIndex >= this.observableListOfPerson.size())
{
for (int x = this.observableListOfPerson.size(); x <= cellIndex; x++)
{
this.observableListOfPerson.add(new Person("", "", ""));
}
}
}
public void changeTableCellFocus(final TableView<?> table, final int focusIndex)
{
table.requestFocus();
table.getSelectionModel().clearAndSelect(focusIndex);
table.getFocusModel().focus(focusIndex);
}
#Override
public void startEdit()
{
super.startEdit();
this.textField.setText(this.getItem());
this.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
this.textField.requestFocus();
}
#Override
public void cancelEdit()
{
super.cancelEdit();
this.setContentDisplay(ContentDisplay.TEXT_ONLY);
}
#Override
public void commitEdit(String text)
{
super.commitEdit(text);
Person person = this.getTableView().getItems().get(this.getIndex());
StringProperty cellProperty = this.property.apply(person);
cellProperty.set(text);
this.setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}
public static class Person
{
private final StringProperty firstName = new SimpleStringProperty();
private final StringProperty lastName = new SimpleStringProperty();
private final StringProperty email = new SimpleStringProperty();
public Person(String firstName, String lastName, String email)
{
this.setFirstName(firstName);
this.setLastName(lastName);
this.setEmail(email);
}
public final StringProperty firstNameProperty()
{
return this.firstName;
}
public final java.lang.String getFirstName()
{
return this.firstNameProperty().get();
}
public final void setFirstName(final java.lang.String firstName)
{
this.firstNameProperty().set(firstName);
}
public final StringProperty lastNameProperty()
{
return this.lastName;
}
public final java.lang.String getLastName()
{
return this.lastNameProperty().get();
}
public final void setLastName(final java.lang.String lastName)
{
this.lastNameProperty().set(lastName);
}
public final StringProperty emailProperty()
{
return this.email;
}
public final java.lang.String getEmail()
{
return this.emailProperty().get();
}
public final void setEmail(final java.lang.String email)
{
this.emailProperty().set(email);
}
}
public static void main(String[] args)
{
launch(args);
}
}

Try this :
TableCell tc = (TableCell) event.getSource();
int index = tc.getIndex();

Related

JavaFX : TreeTableView with CheckComboBoxCell not updating the cell properly

I have the following code to create a TreeTableView with a CheckComboBox in one column.
public class TreeTableViewSample extends Application {
List<Employee> employees = Arrays.<Employee>asList(
new Employee("Ethan Williams", ""),
new Employee("Emma Jones", ""),
new Employee("Michael Brown", ""),
new Employee("Anna Black", ""),
new Employee("Rodger York", ""),
new Employee("Susan Collins", ""));
final TreeItem<Employee> root = new TreeItem<>(new Employee("Department", ""));
final TreeItem<Employee> root1 = new TreeItem<>(new Employee("Executive Department", ""));
final TreeItem<Employee> root2 = new TreeItem<>(new Employee("Sales Department", ""));
public static void main(String[] args) {
Application.launch(TreeTableViewSample.class, args);
}
#Override
public void start(Stage stage) {
root.setExpanded(true);
employees.stream().forEach((employee) -> {
root1.getChildren().add(new TreeItem<>(employee));
root2.getChildren().add(new TreeItem<>(employee));
});
root.getChildren().addAll(root1, root2);
stage.setTitle("Tree Table View Sample");
final Scene scene = new Scene(new Group(), 400, 400);
scene.setFill(Color.LIGHTGRAY);
Group sceneRoot = (Group) scene.getRoot();
TreeTableColumn<Employee, String> empColumn
= new TreeTableColumn<>("Employee");
empColumn.setPrefWidth(150);
empColumn.setCellValueFactory(
(TreeTableColumn.CellDataFeatures<Employee, String> param)
-> new ReadOnlyStringWrapper(param.getValue().getValue().getName())
);
TreeTableColumn<Employee, String> emailColumn
= new TreeTableColumn<>("Email");
emailColumn.setPrefWidth(190);
emailColumn.setEditable(true);
emailColumn.setCellFactory((TreeTableColumn<Employee, String> p) -> new CheckComboCell());
emailColumn.setCellValueFactory(
(TreeTableColumn.CellDataFeatures<Employee, String> param)
-> new ReadOnlyStringWrapper(param.getValue().getValue().getEmail())
);
TreeTableView<Employee> treeTableView = new TreeTableView<>(root);
treeTableView.setEditable(true);
treeTableView.getColumns().setAll(empColumn, emailColumn);
sceneRoot.getChildren().add(treeTableView);
stage.setScene(scene);
stage.show();
}
public class Employee {
private SimpleStringProperty name;
private SimpleStringProperty email;
public SimpleStringProperty nameProperty() {
if (name == null) {
name = new SimpleStringProperty(this, "name");
}
return name;
}
public SimpleStringProperty emailProperty() {
if (email == null) {
email = new SimpleStringProperty(this, "email");
}
return email;
}
private Employee(String name, String email) {
this.name = new SimpleStringProperty(name);
this.email = new SimpleStringProperty(email);
}
public String getName() {
return name.get();
}
public void setName(String fName) {
name.set(fName);
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
}
}
Cell Factory Class
public class CheckComboCell extends TreeTableCell<TreeTableViewSample.Employee, String> {
private final ComboBox<CheckComboCellModel> cb = new ComboBox<CheckComboCellModel>() {
#SuppressWarnings("restriction")
#Override
protected javafx.scene.control.Skin<?> createDefaultSkin() {
return new ComboBoxListViewSkin<CheckComboCellModel>(this) {
#Override
protected boolean isHideOnClickEnabled() {
return false;
}
};
}
};
private final ObservableList<CheckComboCellModel> items = FXCollections.observableArrayList();
private final Tooltip tooltip = new Tooltip();
public CheckComboCell() {
super();
populateAllocationType();
cb.setItems(items);
cb.setCellFactory((ListView<CheckComboCellModel> p) -> new ListCell<CheckComboCellModel>() {
private final CheckBox checkBox = new CheckBox();
private BooleanProperty booleanProperty;
{
checkBox.setOnAction(e -> getListView().getSelectionModel().select(getItem()));
}
#Override
protected void updateItem(CheckComboCellModel item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
checkBox.setText(item.toString());
if (booleanProperty != null) {
checkBox.selectedProperty().unbindBidirectional(booleanProperty);
}
booleanProperty = item.checkProperty();
checkBox.selectedProperty().bindBidirectional(booleanProperty);
setGraphic(checkBox);
} else {
setGraphic(null);
setText(null);
}
}
});
cb.setButtonCell(new ListCell<CheckComboCellModel>() {
#Override
protected void updateItem(CheckComboCellModel item, boolean empty) {
super.updateItem(item, empty);
String selected = cb.getItems().stream().filter(i -> i.getCheck())
.map(i -> i + "").collect(Collectors.joining(","));
setText(selected);
}
});
setGraphic(null);
}
private void populateAllocationType() {
items.add(new CheckComboCellModel("mail_1"));
items.add(new CheckComboCellModel("mail_2"));
items.add(new CheckComboCellModel("mail_3"));
items.add(new CheckComboCellModel("mail_4"));
items.add(new CheckComboCellModel("mail_5"));
}
#Override
public void startEdit() {
if (!isEditable() || !getTreeTableView().isEditable() || !getTableColumn().isEditable()) {
return;
}
super.startEdit();
setGraphic(cb);
}
#Override
public void commitEdit(String value) {
super.commitEdit(value);
setGraphic(null);
setText(cb.getButtonCell().getText());
}
#Override
public void cancelEdit() {
super.cancelEdit();
setGraphic(null);
setText(cb.getButtonCell().getText());
}
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
setText(this.cb.getButtonCell().getText());
setGraphic(null);
}
}
}
Model class
public class CheckComboCellModel {
private final BooleanProperty check = new SimpleBooleanProperty(false);
private final StringProperty item = new SimpleStringProperty();
public CheckComboCellModel() {
}
public CheckComboCellModel(String item) {
this.item.set(item);
}
public CheckComboCellModel(String item, Boolean check) {
this.item.set(item);
this.check.set(check);
}
public BooleanProperty checkProperty() {
return check;
}
public Boolean getCheck() {
return check.getValue();
}
public void setCheck(Boolean value) {
check.set(value);
}
public StringProperty itemProperty() {
return item;
}
public String getItem() {
return item.getValueSafe();
}
public void setItem(String value) {
item.setValue(value);
}
#Override
public String toString() {
return item.getValue();
}
}
With this i get what i expect (i.e) a Column with CheckComboBox. But the issue is:
The application looks like this:
I selected some values
The values are updated in cell
But when the node is minimized
The updated value is displayed in next node. What i am doing wrong ? How can i solve this?

adding button to javafx table view with condition

I am new to javafx and working on to add Button to TableView with condition .
if the condition is true it will add the button and if false the button will not add to the tableView . i google it but i did not find any suggetion or solution .
is there any way to achieve it. thank in advance.
here is my controller
#FXML
TableView<Employee> employeeTable;
#FXML
TableColumn<Employee, Integer> col_id;
#FXML
TableColumn<Employee, String> col_fatherName;
#FXML
TableColumn<Employee, String> col_CNIC;
#FXML
TableColumn<Employee, String> col_gender;
#FXML
TableColumn<Employee, Button> update;
List<Employee> employees = new ArrayList<>();
ObservableList<Employee> obs = FXCollections.observableArrayList();
private Employee data;
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
setColumnProperties();
addButtonToTable();
addDeleteButton();
loadData();
}
private void loadData() {
employees = employeeDAO.findAllEmployees();
obs = FXCollections.observableArrayList(employees);
employeeTable.getItems().clear();
employeeTable.getItems().addAll(obs);
}
public void setColumnProperties() {
col_id.setCellValueFactory(new PropertyValueFactory<Employee, Integer>("id"));
col_fatherName.setCellValueFactory(new PropertyValueFactory<Employee, String>("fatherName"));
col_CNIC.setCellValueFactory(new PropertyValueFactory<Employee, String>("cnic"));
col_gender.setCellValueFactory(new PropertyValueFactory<Employee, String>("name"));
}
private void addButtonToTable() {
Callback<TableColumn<Employee, Button>, TableCell<Employee, Button>> cellFactory = new Callback<TableColumn<Employee, Button>, TableCell<Employee, Button>>() {
#Override
public TableCell<Employee, Button> call(final TableColumn<Employee, Button> param) {
final TableCell<Employee, Button> cell = new TableCell<Employee, Button>() {
Image imgEdit = new Image(getClass().getResourceAsStream("/images/download.png"));
{
}
#Override
public void updateItem(Button item, boolean empty) {
super.updateItem(item, empty);
edite=new Button("Btn"); // global btn
if (empty) {
setGraphic(null);
} else {
// here i am trying to write condition
Iterator ite= employeeDAO.findAllEmployees().iterator();
while (ite.hasNext()){
Employee employee=(Employee) ite.next();
if (employee.getName().equals("jnk"))
{
edite.setOnAction((ActionEvent event) -> {
System.out.println( edite.getId());
data = getTableView().getItems().get(getIndex());
fatherName.setText(data.getFatherName());
CNIC.setText(data.getCnic());
name.setText(data.getName());
register_btn.setText("Update");
});
edite.setStyle("-fx-background-color: transparent;");
ImageView iv = new ImageView();
iv.setFitHeight(50);
iv.setFitWidth(50);
iv.setImage(imgEdit);
iv.setPreserveRatio(true);
iv.setSmooth(true);
iv.setCache(true);
edite.setGraphic(iv);
setGraphic(edite);
setText(null);
}
else{
System.out.println("not working");
}
}
}
}
};
return cell;
}
;
};
update.setCellFactory(cellFactory);
employeeTable.getColumns().add(update);
register_btn.setText("Register");
}
my goal is add the button if the Name='jnk'
but after the condition is true it add buttons to all row.
My Employee Class
public class EMployee{
private int id;
private String name;
private String cnic;
private String skill;
private String dob;
private String fatherName;
private String gender;
private int value;
setter and getter
}
EmployeeDao Class is
Public Class EmployeeDAO extends JdbcDaoSupport {
public List<Employee> findAllEmployees() {
List<Employee> empList = new ArrayList<>();
String query = "select * from employee";
getJdbcTemplate().query(query,
new BeanPropertyRowMapper<Employee>(Employee.class));
return empList;
}
}

javafx - How to get a cell value of selected row

I am trying to solve a basic problem. Could you please have a look at this code and push me forward a little bit?
I have this
public class StrediskoController {
private Stage dialogStage;
#FXML private TableView strediskaTableView = new TableView<>();
#FXML private Label nameLabel;
private ObservableList<Stredisko> data = FXCollections.observableArrayList();
#FXML public void initialize() {
System.out.println("test");
strediskaTableView.getSelectionModel().selectedItemProperty().addListener((observableValue, oldValue, newValue) -> {
//Check whether item is selected and set value of selected item to Label
if (strediskaTableView.getSelectionModel().getSelectedItem() != null) {
nameLabel.setText(".....");
}
});
}
public void setDialogStage(Stage dialogStage) { this.dialogStage = dialogStage; }
public void GetStrediska() {
new StrediskoDAO().SeeAllStredisko(data, strediskaTableView);
}
I want to select a row in tableview and put a value of second column into label.
My StrediskoDAO looks like:
public void SeeAllStredisko(ObservableList data, TableView<Stredisko> stredisko)
{
try
{
String select = "Select * from stredisko";
PreparedStatement stmt = DatabaseConnection.prepareStatement(select);
ResultSet rst = stmt.executeQuery();
for(int i=0 ; i<rst.getMetaData().getColumnCount(); i++){
//using non property style for making dynamic table
final int j = i;
TableColumn col = new TableColumn(rst.getMetaData().getColumnName(i+1));
col.setCellValueFactory(new Callback<CellDataFeatures<ObservableList,String>,ObservableValue<String>>(){
public ObservableValue<String> call(CellDataFeatures<ObservableList, String> param) {
return new SimpleStringProperty(param.getValue().get(j).toString());
}
});
stredisko.getColumns().addAll(col);
System.out.println("Column ["+i+"] ");
}
while(rst.next())
{
ObservableList<String> row = FXCollections.observableArrayList();
for (int i = 1; i <= rst.getMetaData().getColumnCount(); i++)
{
row.add(rst.getString(i));
System.out.println(row);
}
data.add(row);
}
stredisko.setItems(data);
}
catch(ClassNotFoundException | SQLException e)
{
e.printStackTrace();
}
}
and Stredisko
public class Stredisko {
private SimpleIntegerProperty stredisko_Id;
private SimpleStringProperty name;
public Stredisko(int stredisko_Id, String name) {
this.stredisko_Id = new SimpleIntegerProperty(stredisko_Id);
this.name = new SimpleStringProperty(name);
}
public int getStredisko_Id() {
return stredisko_Id.get();
}
public SimpleIntegerProperty stredisko_IdProperty() {
return stredisko_Id;
}
public void setStredisko_Id(int stredisko_Id) {
this.stredisko_Id.set(stredisko_Id);
}
public String getName() {
return name.get();
}
public SimpleStringProperty nameProperty() {
return name;
}
public void setName(String name) {
this.name.set(name);
}
I am just a beginner in JavaFX and I would be really happy if you help me :-)
Thank you guys.

How to add button in JavaFX table view

I have searched at Google and Stackoverflow for this and I just don't get the given examples. Can someone please explain it to me.
I want to add a button to the last column of a table view and when it gets clicked it should trigger a listener and pass the object of the buttons row. I just do not get the following example from gist.github.com:
This is my full current code:
public class SchermdeelWerkplaats extends BorderPane{
//ATD moeder klasse met alle collecties etc.
private ATD $;
TableView tabel = new TableView();
Button nieuwTaak = new Button("Nieuwe taak inboeken");
final ObservableList<Task> data = FXCollections.observableArrayList();
public SchermdeelWerkplaats(ATD a) {
$ = a;
data.addAll($.agenda);
tabel.setEditable(false);
tabel.setPlaceholder(new Label("Geen taken"));
TableColumn c1 = new TableColumn("datum");
c1.setMinWidth(200);
TableColumn c2 = new TableColumn("type");
c2.setMinWidth(100);
TableColumn c3 = new TableColumn("uren");
c3.setMinWidth(100);
TableColumn c4 = new TableColumn("klaar");
c4.setMinWidth(200);
TableColumn c5 = new TableColumn("Werknemer");
c5.setMinWidth(100);
TableColumn c6= new TableColumn("Auto");
c6.setMinWidth(400);
TableColumn c7= new TableColumn("Actie");
c7.setMinWidth(400);
TableColumn col_action = new TableColumn<>("Action");
col_action.setCellValueFactory(
new Callback<TableColumn.CellDataFeatures<Task, Boolean>,
ObservableValue<Boolean>>() {
#Override
public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Task, Boolean> p) {
return new SimpleBooleanProperty(p.getValue() != null);
}
});
col_action.setCellFactory(
new Callback<TableColumn<Task, Task>, TableCell<Task, Task>>() {
#Override
public TableCell<Task, Task> call(TableColumn<Task, Task> p) {
return new ButtonCell();
}
}
);
c1.setCellValueFactory(
new PropertyValueFactory<Task,Date>("date")
);
c2.setCellValueFactory(
new PropertyValueFactory<Task,Task.TaskType>("type")
);
c3.setCellValueFactory(
new PropertyValueFactory<Task,Double>("hours")
);
c4.setCellValueFactory(
new PropertyValueFactory<Task,Boolean>("done")
);
c5.setCellValueFactory(
new PropertyValueFactory<Task,Employee>("employee")
);
c6.setCellValueFactory(
new PropertyValueFactory<Task,Car>("car")
);
tabel.getColumns().addAll(c1, c2, c3, c4, c5, c6, c7);
tabel.setItems(data);
setCenter(tabel);
setBottom(nieuwTaak);
}
//letterlijk van internet geplukt en datatype aangepast
private class ButtonCell extends TableCell<Task, Task> {
private Button cellButton;
ButtonCell(){
cellButton = new Button("jjhjhjh");
cellButton.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent t) {
// do something when button clicked
Task record = getItem();
// do something with record....
}
});
}
//Display button if the row is not empty
#Override
protected void updateItem(Task record, boolean empty) {
super.updateItem(record, empty);
if(!empty){
cellButton.setText("Something with "+record);
setGraphic(cellButton);
} else {
setGraphic(null);
}
}
}
}
Now the part where I have to create a ButtonCell extends TableCell is understandable. But how to assign this to the column?
I understand this:
c1.setCellValueFactory(
new PropertyValueFactory<Task,Date>("date")
);
But not this:
TableColumn col_action = new TableColumn<>("Action");
col_action.setCellValueFactory(
new Callback<TableColumn.CellDataFeatures<Task, Boolean>,
ObservableValue<Boolean>>() {
#Override
public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Task, Boolean> p) {
return new SimpleBooleanProperty(p.getValue() != null);
}
});
col_action.setCellFactory(
new Callback<TableColumn<Task, Task>, TableCell<Task, Task>>() {
#Override
public TableCell<Task, Task> call(TableColumn<Task, Task> p) {
return new ButtonCell();
}
}
);
To be able to render the column, TableColumn needs cellValueFactory. But the "action" column does not exist in underlying data model. In this case, I just give some dummy value to cellValueFactory and move on:
public class JustDoIt extends Application {
private final TableView<Person> table = new TableView<>();
private final ObservableList<Person> data
= FXCollections.observableArrayList(
new Person("Jacob", "Smith"),
new Person("Isabella", "Johnson"),
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) {
stage.setWidth(450);
stage.setHeight(500);
TableColumn firstNameCol = new TableColumn("First Name");
firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));
TableColumn lastNameCol = new TableColumn("Last Name");
lastNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName"));
TableColumn actionCol = new TableColumn("Action");
actionCol.setCellValueFactory(new PropertyValueFactory<>("DUMMY"));
Callback<TableColumn<Person, String>, TableCell<Person, String>> cellFactory
= //
new Callback<TableColumn<Person, String>, TableCell<Person, String>>() {
#Override
public TableCell call(final TableColumn<Person, String> param) {
final TableCell<Person, String> cell = new TableCell<Person, String>() {
final Button btn = new Button("Just Do It");
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
setText(null);
} else {
btn.setOnAction(event -> {
Person person = getTableView().getItems().get(getIndex());
System.out.println(person.getFirstName()
+ " " + person.getLastName());
});
setGraphic(btn);
setText(null);
}
}
};
return cell;
}
};
actionCol.setCellFactory(cellFactory);
table.setItems(data);
table.getColumns().addAll(firstNameCol, lastNameCol, actionCol);
Scene scene = new Scene(new Group());
((Group) scene.getRoot()).getChildren().addAll(table);
stage.setScene(scene);
stage.show();
}
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private Person(String fName, String lName) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String fName) {
lastName.set(fName);
}
}
}
Here is my example using awesome Java 8 Functionality and extending TableCell class.
Let me give a quick explanation of what I am doing:
I created a ActionButtonTableCell class that extends TableCell. And then you can use java 8 lamda functions to create an Action for the button.
import java.util.function.Function;
import javafx.event.ActionEvent;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.util.Callback;
public class ActionButtonTableCell<S> extends TableCell<S, Button> {
private final Button actionButton;
public ActionButtonTableCell(String label, Function< S, S> function) {
this.getStyleClass().add("action-button-table-cell");
this.actionButton = new Button(label);
this.actionButton.setOnAction((ActionEvent e) -> {
function.apply(getCurrentItem());
});
this.actionButton.setMaxWidth(Double.MAX_VALUE);
}
public S getCurrentItem() {
return (S) getTableView().getItems().get(getIndex());
}
public static <S> Callback<TableColumn<S, Button>, TableCell<S, Button>> forTableColumn(String label, Function< S, S> function) {
return param -> new ActionButtonTableCell<>(label, function);
}
#Override
public void updateItem(Button item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
} else {
setGraphic(actionButton);
}
}
}
The implementation is then as simple as this, This is a sample button to remove the item from the table:
column.setCellFactory(ActionButtonTableCell.<Person>forTableColumn("Remove", (Person p) -> {
table.getItems().remove(p);
return p;
}));

get string when selected from tableview javafx

So in basic form I want to get selected text from tableview.
I have my SetCoachFXML in which I have tableview, with some data in it. Next to that I have choose button. How can I get selected text from tableview when I click on choose button?
http://imgur.com/wA6n792
I tried suggestion from here but I get nothing.
Here is my setcoach controller class:
public class SetCoachController implements Initializable {
//Kolone i tabela za prikazivanje trenera
#FXML
private TableColumn<Coaches, String> coachesNameCol;
#FXML
private TableColumn<Coaches, String> coachesLNCol;
#FXML
private TableView<Coaches> coachTable;
#FXML
private Button chooseBtn;
#FXML
private Button cancelBtn;
private ObservableList<Coaches> coachesData;
#Override
public void initialize(URL url, ResourceBundle rb) {
coachesNameCol
.setCellValueFactory(new PropertyValueFactory<Coaches, String>(
"name"));
coachesLNCol
.setCellValueFactory(new PropertyValueFactory<Coaches, String>(
"lastName"));
coachesData = FXCollections.observableArrayList();
coachTable.setItems(coachesData);
coachTable.setEditable(false);
CoachBase.get();
loadCoachesData();
}
//sql upit
public void loadCoachesData() {
try {
ResultSet rs = CoachBase.query("SELECT * FROM CoachTable");
coachesData.clear();
while (rs.next()) {
coachesData.add(new Coaches(rs.getString("Name"), rs.getString("Lastname")));
}
} catch (Exception e) {
System.out.println("" + e.getMessage());
}
}
public void chooseAction(ActionEvent event) {
Coaches coach = (Coaches) coachTable.getSelectionModel().getSelectedItem();
System.out.println(coach.getcoachesName());
}
public void cancelAction(ActionEvent event) {
Stage stage = (Stage) cancelBtn.getScene().getWindow();
stage.close();
}
and my Coaches class:
public class Coaches {
private SimpleIntegerProperty id = new SimpleIntegerProperty();
private SimpleStringProperty name = new SimpleStringProperty();
private SimpleStringProperty lastName = new SimpleStringProperty();
private SimpleIntegerProperty age = new SimpleIntegerProperty();
public Coaches(Integer id, String name, String lastName, int age) {
this.name.setValue(name);
this.lastName.setValue(lastName);
this.age.setValue(age);
}
public Coaches(String name, String lastName) {
this.name.setValue(name);
this.lastName.setValue(lastName);
}
public Integer getId() {
if (id == null) {
return 0;
}
return id.getValue();
}
public String getcoachesName() {
if (name != null) {
return "";
}
return name.getValueSafe();
}
public String getlastName() {
if (lastName != null) {
return "";
}
return lastName.getValueSafe();
}
public Integer getAge() {
if (age == null) {
return 0;
}
return age.getValue();
}
public SimpleIntegerProperty IdProperty() {
return id;
}
public SimpleStringProperty nameProperty() {
return name;
}
public SimpleStringProperty lastNameProperty() {
return lastName;
}
public SimpleIntegerProperty ageProperty() {
return age;
}
}
I think what's happening is when you click on the button, your loosing focus on the selected cell which means when you try to retrieving data, nothing happens.
What you need to do is make sure that when you click on the button, the cell/row is still selected.
Then you can do something like:
// To retrieve
Person person = (Person)taview.getSelectionModel().getSelectedItem();
System.out.println(person.getName());

Categories