Skip to content

Instantly share code, notes, and snippets.

@carlosdelfino
Forked from haisi/EditableTableFX.java
Last active June 7, 2022 15:01
Show Gist options
  • Save carlosdelfino/5db62acc58bae2de4304 to your computer and use it in GitHub Desktop.
Save carlosdelfino/5db62acc58bae2de4304 to your computer and use it in GitHub Desktop.
JavaFX TableView editável com TextField, DatePicker e Menus Dropdowns (com base no exemplo: https://gist.github.com/haisi/0a82e17daf586c9bab52)
package editabletableview;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.control.TableCell;
class ComboBoxIntegerEditingCell extends TableCell<Person, Integer> {
private ComboBox<Integer> comboBox;
ComboBoxIntegerEditingCell() {
}
@Override
public void startEdit() {
if (!isEmpty()) {
super.startEdit();
createComboBox();
setText(null);
setGraphic(comboBox);
}
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText(getValue().toString());
setGraphic(null);
}
@Override
public void updateItem(Integer item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (comboBox != null) {
comboBox.setValue(getValue());
}
setText(getValue().toString());
setGraphic(comboBox);
} else {
setText(getValue().toString() );
setGraphic(null);
}
}
}
private void createComboBox() {
comboBox = new ComboBox<>(Main.pontuacao);
comboBoxConverter(comboBox);
comboBox.valueProperty().set(getValue());
comboBox.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
comboBox.setOnAction((e) -> {
System.out.println("Committed: " + comboBox.getSelectionModel().getSelectedItem());
commitEdit(comboBox.getSelectionModel().getSelectedItem());
});
}
private void comboBoxConverter(ComboBox<Integer> comboBox) {
// Define rendering of the list of values in ComboBox drop down.
comboBox.setCellFactory((c) -> {
return new ListCell<Integer>() {
@Override
protected void updateItem(Integer item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText("0");
} else {
setText(item.toString());
}
}
};
});
}
private Integer getValue() {
return getItem() == null ? 0 : getItem();
}
}
package editabletableview;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.control.TableCell;
class ComboBoxStringEditingCell extends TableCell<Person, String> {
private ComboBox<String> comboBox;
ComboBoxStringEditingCell() {
}
@Override
public void startEdit() {
if (!isEmpty()) {
super.startEdit();
createComboBox();
setText(null);
setGraphic(comboBox);
}
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText(getValue());
setGraphic(null);
}
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (comboBox != null) {
comboBox.setValue(getValue());
}
setText(getValue() );
setGraphic(comboBox);
} else {
setText(getValue() );
setGraphic(null);
}
}
}
private void createComboBox() {
comboBox = new ComboBox<>(Main.qualificacao);
comboBoxConverter(comboBox);
comboBox.valueProperty().set(getValue());
comboBox.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
comboBox.setOnAction((e) -> {
System.out.println("Committed: " + comboBox.getSelectionModel().getSelectedItem());
commitEdit(comboBox.getSelectionModel().getSelectedItem());
});
// comboBox.focusedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
// if (!newValue) {
// commitEdit(comboBox.getSelectionModel().getSelectedItem());
// }
// });
}
private void comboBoxConverter(ComboBox<String> comboBox) {
// Define rendering of the list of values in ComboBox drop down.
comboBox.setCellFactory((c) -> {
return new ListCell<String>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText(null);
} else {
setText(item);
}
}
};
});
}
private String getValue() {
return getItem() == null ? "" : getItem();
}
}
package editabletableview;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Date;
import javafx.scene.control.DatePicker;
import javafx.scene.control.TableCell;
class DateEditingCell extends TableCell<Person, Date> {
private DatePicker datePicker;
DateEditingCell() {
}
@Override
public void startEdit() {
if (!isEmpty()) {
super.startEdit();
createDatePicker();
setText(null);
setGraphic(datePicker);
}
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText(getDate().toString());
setGraphic(null);
}
@Override
public void updateItem(Date item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (datePicker != null) {
datePicker.setValue(getDate());
}
setText(null);
setGraphic(datePicker);
} else {
setText(getDate().format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)));
setGraphic(null);
}
}
}
private void createDatePicker() {
datePicker = new DatePicker(getDate());
datePicker.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
datePicker.setOnAction((e) -> {
System.out.println("Committed: " + datePicker.getValue().toString());
commitEdit(Date.from(datePicker.getValue().atStartOfDay(ZoneId.systemDefault()).toInstant()));
});
}
private LocalDate getDate() {
return getItem() == null ? LocalDate.now()
: getItem().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
}
}
/*
* I don't care
*/
package editabletableview;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Date;
import java.util.List;
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Callback;
/**
*
* @author Hasan Kara <hasan.kara@fhnw.ch>
*/
public class Main extends Application {
private TableView<PostTrained> table = new TableView<>();
final static ObservableList<String> qualificacao = FXCollections.observableArrayList(("Positiva"), ("Neutra"),
("Negativa"));
// não será usado por enquanto, apenas para estudo.
final static ObservableList<Integer> pontuacao = FXCollections.observableArrayList(-3, -2, -1, 0, 1, 2, 3);
private final ObservableList<PostTrained> data = FXCollections.observableArrayList(
new PostTrained("Mensagem 1", qualificacao.get(0), pontuacao.get(1), new Date()),
new PostTrained("Mensagem 2", qualificacao.get(1), pontuacao.get(1), new Date()),
new PostTrained("Mensagem 3", qualificacao.get(2), pontuacao.get(1), new Date()),
new PostTrained("Mensagem 4", qualificacao.get(2), pontuacao.get(1), new Date()));
final HBox hb = new HBox();
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setWidth(800);
stage.setHeight(600);
final Label label = new Label("Seleção de Mensagens");
label.setFont(new Font("Arial", 20));
table.setEditable(true);
// Mensagem
Callback<TableColumn<PostTrained, String>, TableCell<PostTrained, String>> msgCellFactory = (
TableColumn<PostTrained, String> param) -> new TextStringEditingCell();
Callback<TableColumn<PostTrained, String>, TableCell<PostTrained, String>> qlfComboBoxCellFactory = (
TableColumn<PostTrained, String> param) -> new ComboBoxStringEditingCell();
Callback<TableColumn<PostTrained, Integer>, TableCell<PostTrained, Integer>> ptcComboBoxCellFactory = (
TableColumn<PostTrained, Integer> param) -> new ComboBoxIntegerEditingCell();
Callback<TableColumn<PostTrained, Date>, TableCell<PostTrained, Date>> crcDateCellFactory = (
TableColumn<PostTrained, Date> param) -> new DateEditingCell();
TableColumn<PostTrained, String> msgCol = new TableColumn<>("Mensagem");
msgCol.setMinWidth(500);
msgCol.setCellValueFactory(cellData -> cellData.getValue().mensagemProperty());
msgCol.setCellFactory(msgCellFactory);
msgCol.setOnEditCommit((TableColumn.CellEditEvent<PostTrained, String> t) -> {
((PostTrained) t.getTableView().getItems().get(t.getTablePosition().getRow())).setMensagem(t.getNewValue());
});
TableColumn<PostTrained, String> qualificacaoCol = new TableColumn<>("Qualificação");
qualificacaoCol.setMinWidth(80);
qualificacaoCol.setCellValueFactory(cellData -> cellData.getValue().qualificacaoProperty());
qualificacaoCol.setCellFactory(qlfComboBoxCellFactory);
qualificacaoCol.setOnEditCommit((TableColumn.CellEditEvent<PostTrained, String> t) -> {
((PostTrained) t.getTableView().getItems().get(t.getTablePosition().getRow())).setQualificacao(t.getNewValue());
});
TableColumn<PostTrained, Integer> pontuacaoCol = new TableColumn<>("Pontuacao");
pontuacaoCol.setMinWidth(10);
pontuacaoCol.setCellValueFactory(cellData -> cellData.getValue().pontuacaoProperty());
pontuacaoCol.setCellFactory(ptcComboBoxCellFactory);
pontuacaoCol.setOnEditCommit((TableColumn.CellEditEvent<PostTrained, Integer> t) -> {
((PostTrained) t.getTableView().getItems().get(t.getTablePosition().getRow())).setPontuacao(t.getNewValue());
});
TableColumn<PostTrained, Date> criacaoCol = new TableColumn<>("Data de Criação");
criacaoCol.setMinWidth(100);
criacaoCol.setCellValueFactory(cellData -> cellData.getValue().criacaoeProperty());
criacaoCol.setCellFactory(crcDateCellFactory);
criacaoCol.setOnEditCommit((TableColumn.CellEditEvent<PostTrained, Date> t) -> {
((PostTrained) t.getTableView().getItems().get(t.getTablePosition().getRow())).setCriacao(t.getNewValue());
});
table.setItems(data);
table.getColumns().addAll(msgCol, qualificacaoCol, pontuacaoCol, criacaoCol);
final TextField addMsg = new TextField();
addMsg.setPromptText("Mensagem");
addMsg.setMaxWidth(msgCol.getPrefWidth());
final TextField addLastName = new TextField();
addLastName.setPromptText("Qualificacao");
addLastName.setMaxWidth(qualificacaoCol.getPrefWidth());
final TextField addEmail = new TextField();
addEmail.setPromptText("Pontuacao");
addEmail.setMaxWidth(pontuacaoCol.getPrefWidth());
final Button addButton = new Button("Add");
addButton.setOnAction((ActionEvent e) -> {
data.add(new PostTrained(addMsg.getText(), addLastName.getText(), new Integer(addEmail.getText()), new Date()));
addMsg.clear();
addLastName.clear();
addEmail.clear();
});
hb.getChildren().addAll(addMsg, addLastName, addEmail, addButton);
hb.setSpacing(3);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(label, table, hb);
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
/**
* @param args
* the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
package editabletableview;
import java.util.Date;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class PostTrained {
private final SimpleStringProperty mensagem;
private final SimpleObjectProperty<String> qualificacao;
private final SimpleObjectProperty<Integer> pontuacao;
private final SimpleObjectProperty<Date> criacao;
public PostTrained(String p_mensagem, String p_qualificacao, Integer p_pontuacao, Date p_criacao) {
this.mensagem = new SimpleStringProperty(p_mensagem);
this.qualificacao = new SimpleObjectProperty<String>(p_qualificacao);
this.pontuacao = new SimpleObjectProperty<Integer>(p_pontuacao);
this.criacao = new SimpleObjectProperty<>(p_criacao);
}
public String getMensagem() {
return mensagem.get();
}
public StringProperty mensagemProperty() {
return this.mensagem;
}
public void setMensagem(String p_msg) {
this.mensagem.set(p_msg);
}
public Date getCriacao() {
return criacao.get();
}
public ObjectProperty<Date> criacaoeProperty() {
return this.criacao;
}
public void setCriacao(Date p_date) {
this.criacao.set(p_date);
}
public String getQualificacao() {
return qualificacao.get();
}
public ObjectProperty<String> qualificacaoProperty() {
return this.qualificacao;
}
public void setQualificacao(String typ) {
this.qualificacao.set(typ);
}
public Integer getPontuacao() {
return pontuacao.get();
}
public ObjectProperty<Integer> pontuacaoProperty() {
return this.pontuacao;
}
public void setPontuacao(Integer birthday) {
this.pontuacao.set(birthday);
}
}
package editabletableview;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.TableCell;
import javafx.scene.control.TextField;
class TextStringEditingCell extends TableCell<PostTrained, String> {
private TextField textField;
TextStringEditingCell() {
}
@Override
public void startEdit() {
if (!isEmpty()) {
super.startEdit();
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(item);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
// setGraphic(null);
}
setText(null);
setGraphic(textField);
} else {
setText(getString());
setGraphic(null);
}
}
}
private void createTextField() {
textField = new TextField(getString());
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
textField.setOnAction((e) -> commitEdit(textField.getText()));
textField.focusedProperty().addListener(
(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
if (!newValue) {
System.out.println("Commiting " + textField.getText());
commitEdit(textField.getText());
}
});
}
private String getString() {
return getItem() == null ? "" : getItem();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment