Я создаю класс ExtendedTableView
путем расширения TableView
, я хочу разрешить пользователям создавать extendedTableView с предварительно установленными настройками и разрешать редактирование ячеек.Ниже приведен фрагмент кода, в котором кратко показано, как редактируется ячейка:
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
//Create a customer cell factory so that cells can support editing.
Callback<TableColumn, TableCell> cellFactory = new Callback<TableColumn, TableCell>() {
@Override
public TableCell call(TableColumn p) {
return new EditingCell();
}
};
//Set up the columns
TableColumn firstNameCol = new TableColumn("First Name");
firstNameCol.setMinWidth( 100 );
firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));
firstNameCol.setCellFactory(cellFactory);
TableColumn lastNameCol = new TableColumn("Last Name");
lastNameCol.setMinWidth( 100 );
lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName"));
lastNameCol.setCellFactory(cellFactory);
// lastNameCol.setEditable( false );
TableColumn emailCol = new TableColumn("Email");
emailCol.setMinWidth(400);
TableColumn primaryEmailCol = new TableColumn("Primary Email");
primaryEmailCol.setMinWidth(200);
primaryEmailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("primaryEmail"));
primaryEmailCol.setCellFactory(cellFactory);
//Make this column un-editable
primaryEmailCol.setEditable( false );
TableColumn secondaryEmailCol = new TableColumn("Secondary Email");
secondaryEmailCol.setMinWidth(200);
secondaryEmailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("secondaryEmail"));
secondaryEmailCol.setCellFactory(cellFactory);
// secondaryEmailCol.setEditable( false );
emailCol.getColumns().addAll(primaryEmailCol, secondaryEmailCol);
//Add the columns and data to the table.
table.setItems(data);
table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
//Make the table editable
table.setEditable(true);
//Modifying the firstName property
firstNameCol.setOnEditCommit(new EventHandler<CellEditEvent<Person, String>>() {
@Override
public void handle(CellEditEvent<Person, String> t) {
((Person) t.getTableView().getItems().get(t.getTablePosition().getRow())).setFirstName(t.getNewValue());
}
});
//Modifying the lastName property
lastNameCol.setOnEditCommit(new EventHandler<CellEditEvent<Person, String>>() {
@Override
public void handle(CellEditEvent<Person, String> t) {
((Person) t.getTableView().getItems().get(t.getTablePosition().getRow())).setLastName(t.getNewValue());
}
});
//Modifying the primary email property
primaryEmailCol.setOnEditCommit(new EventHandler<CellEditEvent<Person, String>>() {
@Override
public void handle(CellEditEvent<Person, String> t) {
((Person) t.getTableView().getItems().get(t.getTablePosition().getRow())).setPrimaryEmail(t.getNewValue());
}
});
//Modifying the secondary email property
secondaryEmailCol.setOnEditCommit(new EventHandler<CellEditEvent<Person, String>>() {
@Override
public void handle(CellEditEvent<Person, String> t) {
((Person) t.getTableView().getItems().get(t.getTablePosition().getRow())).setSecondaryEmail(t.getNewValue());
}
});
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.getChildren().addAll(label, table);
vbox.setPadding(new Insets(10, 0, 0, 10));
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
public class EditingCell extends TableCell<Person, String> {
private TextField textField;
public EditingCell() {
}
@Override
public void startEdit() {
super.startEdit();
if (textField == null) {
createTextField();
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
Platform.runLater(new Runnable() {
@Override
public void run() {
textField.requestFocus();
textField.selectAll();
}
});
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText((String) getItem());
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
@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());
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
} else {
setText(getString());
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}
}
private void createTextField() {
textField = new TextField(getString());
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
textField.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
commitEdit(textField.getText());
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
} else if (t.getCode() == KeyCode.TAB) {
commitEdit(textField.getText());
TableColumn nextColumn = getNextColumn(!t.isShiftDown());
if (nextColumn != null) {
getTableView().edit(getTableRow().getIndex(), nextColumn);
}
}
}
});
textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (!newValue && textField != null) {
commitEdit(textField.getText());
}
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
/**
*
* @param forward true gets the column to the right, false the column to the left of the current column
* @return
*/
private TableColumn<Person, ?> getNextColumn(boolean forward) {
List<TableColumn<Person, ?>> columns = new ArrayList<>();
for (TableColumn<Person, ?> column : getTableView().getColumns()) {
columns.addAll(getLeaves(column));
}
//There is no other column that supports editing.
if (columns.size() < 2) {
return null;
}
int currentIndex = columns.indexOf(getTableColumn());
int nextIndex = currentIndex;
if (forward) {
nextIndex++;
if (nextIndex > columns.size() - 1) {
nextIndex = 0;
}
} else {
nextIndex--;
if (nextIndex < 0) {
nextIndex = columns.size() - 1;
}
}
return columns.get(nextIndex);
}
private List<TableColumn<Person, ?>> getLeaves(TableColumn<Person, ?> root) {
List<TableColumn<Person, ?>> columns = new ArrayList<>();
if (root.getColumns().isEmpty()) {
//We only want the leaves that are editable.
if (root.isEditable()) {
columns.add(root);
}
return columns;
} else {
for (TableColumn<Person, ?> column : root.getColumns()) {
columns.addAll(getLeaves(column));
}
return columns;
}
}
}
В приведенном выше примере показано, что класс EditingCell extends TableCell<Person, String>
, но я пытаюсь сделать что-то вроде этого:
public class ExtendedTableView extends TableView{
public ExtendedTableView(){
init();
}
private void init(){
this.setEditable(true);
this.setTableMenuButtonVisible(true);
}
}
public class EditingCell extends TableCell<UNKNOWN, String>{
private TableColumn<UNKNOWN, ?> getNextColumn(boolean forward) {
}
}
Я хочу, чтобы пользователи могли делать что-то вроде ExtendedTableView table = new ExtendedTableView()
, чтобы получить таблицу, в которой все предварительно настроенные параметры и ячейки доступны для редактирования.Не имеет значения, нужно ли мне добавить еще несколько строк, таких как передача в классе / classtype (вместо Person
class).Но идея состоит в том, чтобы создать настраиваемое представление таблицы так, чтобы оно было достаточно общим, и пользователям не нужно было знать коды, необходимые для редактирования ячеек и т. Д.
public class MyClass{
public MyClass(){
}
public void createTable(){
ExtendedTableView tableA = new ExtendedTableView();
ExtendedTableView tableB = new ExtendedTableView();
/*somehow find a way to pass classA into tableA so that class table cell can be something like this: "TableCell < ClassA, String>"*/
}
}
public class classA{
}
public class classB{
}