我有这个适用于TableView的应用程序。它添加/删除新的行或列并存储每个单元格的数据。
public class MyTable extends Application {
private BorderPane root;
private HBox hBox;
private TableView<MyData> tableView;
private Button buttAddColumn, buttDeleteColumn;
private Button buttAddRow, buttDeleteRow;
private int numberOfColumns = 0;
private ObservableList<MyData> dataList = FXCollections.observableArrayList();
@Override
public void init() throws Exception {
root = new BorderPane();
hBox = new HBox();
buttAddColumn = new Button("Add columns");
buttDeleteColumn = new Button("Delete columns");
buttAddRow = new Button("Add rows");
buttDeleteRow = new Button("Delete rows");
tableView = new TableView<>();
tableView.setEditable(true);
tableView.setItems(dataList);
hBox.getChildren().addAll(buttAddColumn,buttDeleteColumn,buttAddRow,buttDeleteRow);
root.setTop(hBox);
root.setCenter(tableView);
//----------------------------------------------------------------
buttAddColumn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
buttAddColumnAction(event);
}
});
buttDeleteColumn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
buttDeleteColumnAction(event);
}
});
buttAddRow.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
buttAddRowAction(event);
}
});
buttDeleteRow.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
buttDeleteRowAction(event);
}
});
}
private void buttAddColumnAction(ActionEvent event){
int i = numberOfColumns;// thats the key for lambda expression. Unicate number for column to access its variable;
if(dataList.size() > 0)//resizing each data object with new variable
for(MyData x: dataList)
x.addNew(i);
TableColumn<MyData, Integer> newColumn = new TableColumn<>("#" + String.valueOf(++numberOfColumns));
newColumn.setCellValueFactory(cellData -> cellData.getValue().getCellValue(i).asObject());
newColumn.setCellFactory(TextFieldTableCell.<MyData, Integer>forTableColumn(new IntegerStringConverter()));
tableView.getColumns().add(newColumn);
}
private void buttDeleteColumnAction(ActionEvent event){
if(numberOfColumns > 0){
tableView.getColumns().remove(numberOfColumns-1);
--numberOfColumns;
if(dataList.size() > 0)
for(MyData x: dataList) //deleting unnecesary variable
x.deleteLast();
}
}
private void buttAddRowAction(ActionEvent event){
dataList.add(new MyData(numberOfColumns));
}
private void buttDeleteRowAction(ActionEvent event){
if(dataList.size() > 0){//resizing each data object with new variable
dataList.remove(dataList.size()-1);
}
}
//*******************************************************************
public class MyData{ //dont forget about public because you wont get acces to properties
private ObservableList<SimpleIntegerProperty> cellValue = FXCollections.observableArrayList();
public MyData(int howManyColumns) {
for(int i=0; i<howManyColumns; ++i)
this.cellValue.add(new SimpleIntegerProperty(new Random().nextInt(10)));
}
public SimpleIntegerProperty getCellValue(int whichOne) {
return cellValue.get(whichOne);
}
public void setCellValue(int cellValue, int whichOne) {
this.cellValue.set(whichOne, new SimpleIntegerProperty(cellValue));
}
public void addNew(int numberOfNewElement){ //ads another variable for another column
cellValue.add(new SimpleIntegerProperty(new Random().nextInt(10)));
}
public void deleteLast(){ //deletes last variable when column is deleted
cellValue.remove(cellValue.size()-1);
}
}
//*******************************************************************
@Override
public void start(Stage primaryStage) throws Exception {
try {
Scene scene = new Scene(root,400,400);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
如何更改它,所以当用户双击单元格时,程序会等待直到他从0-9按下单个数字,然后自动接受它并打开下一个单元格以放入另一个数字(所以他不需要手动打开/关闭它们?
我目前不知道如何做到这一点。甚至如何使空单元格等待数据(也许数据类应该包含char
变量而不是Integer
,那么我可以将值""
放到单元格中???)
答案 0 :(得分:1)
6个小时左右,我已经做到了......
我必须在每个列中添加类似这样的内容,这些列是使用单元格编辑事件的类。
Callback<TableColumn<MyData, Integer>, TableCell<MyData, Integer>> cellFactoryInt = (TableColumn<MyData, Integer> p) -> new EditingCellNumbers(tableView);
newColumn.setCellFactory(cellFactoryInt);
此类的实现:
package application;
import application.MyTable.MyData;
import javafx.beans.value.ObservableValue;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
//Klasa ta pozwala na definiowania zachowania komórek, które edytuje użytkownik
public class EditingCellNumbers extends TableCell<MyData, Integer>{
private TextField textField;
private TableView<MyData> parentTableView;
public static int numberOfColumns;
public EditingCellNumbers(TableView<MyData> parent) {
this.parentTableView = parent;
numberOfColumns = parent.getColumns().size();
}
@Override
public void startEdit(){
if (!isEmpty()) {
super.startEdit();
createTextField();
setText(null);
setGraphic(textField);
textField.selectAll();
textField.requestFocus();
}
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText(String.valueOf(getItem()));
setGraphic(null);
}
@Override
public void updateItem(Integer 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(
(ObservableValue<? extends Boolean> arg0,
Boolean arg1, Boolean arg2) -> {
if (!arg2) {
commitEdit(Integer.valueOf(textField.getText()));
}
});
textField.setOnKeyReleased(new EventHandler<Event>() {
@Override
public void handle(Event event) {
try{
int i = Integer.valueOf(textField.getText());
//digit given...
if( (i>=0) && (i<10) ){//making sure cell is filled with just one digit
commitEdit(Integer.valueOf(textField.getText()));
int selectedColumn = parentTableView.getSelectionModel().getSelectedCells().get(0).getColumn(); // gets the number of selected column
int selectedRow = parentTableView.getSelectionModel().getSelectedCells().get(0).getRow();
if(selectedColumn < numberOfColumns-1){
parentTableView.getSelectionModel().selectNext();
parentTableView.edit(selectedRow, parentTableView.getColumns().get(selectedColumn+1));
}else{
parentTableView.getSelectionModel().select(selectedRow+1, parentTableView.getColumns().get(0));
parentTableView.edit(selectedRow+1, parentTableView.getColumns().get(0));
}
}else
textField.clear();
}catch(NumberFormatException e){
textField.clear();
}
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
}
这里有一点点编辑的应用程序类:
public class MyTable extends Application {
private BorderPane root;
private HBox hBox;
private TableView<MyData> tableView;
private Button buttAddColumn, buttDeleteColumn;
private Button buttAddRow, buttDeleteRow;
private int numberOfColumns = 0;
private ObservableList<MyData> dataList = FXCollections.observableArrayList();
@Override
public void init() throws Exception {
root = new BorderPane();
buttAddColumn = new Button("Add columns");
buttDeleteColumn = new Button("Delete columns");
buttAddRow = new Button("Add rows");
buttDeleteRow = new Button("Delete rows");
tableView = new TableView<>();
hBox = new HBox();
hBox.getChildren().addAll(buttAddColumn,buttDeleteColumn,buttAddRow,buttDeleteRow);
tableView.setEditable(true);
tableView.getSelectionModel().setCellSelectionEnabled(true);
tableView.setItems(dataList);
root.setTop(hBox);
root.setCenter(tableView);
//----------------------------------------------------------------
buttAddColumn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
buttAddColumnAction(event);
}
});
buttDeleteColumn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
buttDeleteColumnAction(event);
}
});
buttAddRow.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
buttAddRowAction(event);
}
});
buttDeleteRow.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
buttDeleteRowAction(event);
}
});
}
private void buttAddColumnAction(ActionEvent event){
int i = numberOfColumns;// thats the key for lambda expression. Unicate number for column to access its variable;
if(dataList.size() > 0)//resizing each data object with new variable
for(MyData x: dataList)
x.addNew(i);
TableColumn<MyData, Integer> newColumn = new TableColumn<>("#" + String.valueOf(++numberOfColumns));
newColumn.setCellValueFactory(cellData -> cellData.getValue().getCellValue(i).asObject());
newColumn.setCellFactory(TextFieldTableCell.<MyData, Integer>forTableColumn(new IntegerStringConverter()));
Callback<TableColumn<MyData, Integer>, TableCell<MyData, Integer>> cellFactoryInt = (TableColumn<MyData, Integer> p) -> new EditingCellNumbers(tableView);
newColumn.setCellFactory(cellFactoryInt);
tableView.getColumns().add(newColumn);
}
private void buttDeleteColumnAction(ActionEvent event){
if(numberOfColumns > 0){
tableView.getColumns().remove(numberOfColumns-1);
--numberOfColumns;
--EditingCellNumbers.numberOfColumns;
if(dataList.size() > 0)
for(MyData x: dataList) //deleting unnecesary variable
x.deleteLast();
}
}
private void buttAddRowAction(ActionEvent event){
dataList.add(new MyData(numberOfColumns));
}
private void buttDeleteRowAction(ActionEvent event){
if(dataList.size() > 0){//resizing each data object with new variable
dataList.remove(dataList.size()-1);
}
}
//*******************************************************************
public class MyData{ //dont forget about public because you wont get acces to properties
private ObservableList<SimpleIntegerProperty> cellValue = FXCollections.observableArrayList();
public MyData(int howManyColumns) {
for(int i=0; i<howManyColumns; ++i)
this.cellValue.add(new SimpleIntegerProperty(new Random().nextInt(10)));
}
public SimpleIntegerProperty getCellValue(int whichOne) {
return cellValue.get(whichOne);
}
public void setCellValue(int cellValue, int whichOne) {
this.cellValue.set(whichOne, new SimpleIntegerProperty(cellValue));
}
public void addNew(int numberOfNewElement){ //ads another variable for another column
cellValue.add(new SimpleIntegerProperty(new Random().nextInt(10)));
}
public void deleteLast(){ //deletes last variable when column is deleted
cellValue.remove(cellValue.size()-1);
}
}
//*******************************************************************
@Override
public void start(Stage primaryStage) throws Exception {
try {
Scene scene = new Scene(root,400,400);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
很多代码,但也许有人会在将来使用它:P