我有一个程序,我可以在其中添加行和列,它们充满了数据。用户也可以通过单击来修改单元格。问题是每当他改变一个单元格的值时,整行就会变为相同的值。我希望每个单元格都有自己独立的值(也适用于新添加的列)。
public class TableData {
public int digitCell;
public static int numberOfColumns = 0;
public TableData(int digit) {
this.digitCell = digit;
}
public int getDigitCell() {
return digitCell;
}
public void setDigitCell(int digit) {
this.digitCell = digit;
}
//this method creates and return new column and is used whenever the user clicks add new column
public static TableColumn<TableData, Integer> addNewColumn(TableView<?> table){
int columnWidth = 10;
TableColumn<TableData, Integer> newColumn = new TableColumn<>("#" + String.valueOf(numberOfColumns));
newColumn.setCellFactory(TextFieldTableCell.<TableData, Integer>forTableColumn(new IntegerStringConverter()));
//Callback<TableColumn<TableData, Integer>, TableCell<TableData,Integer>> cellCallback = (TableColumn<DataModel,Integer> p) -> new NowaKlasa();
newColumn.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<TableData,Integer>>() {
@Override
public void handle(CellEditEvent<TableData, Integer> event) {
((TableData) event.getTableView().getItems(). get(event.getTablePosition().getRow())). setDigitCell(event.getNewValue());
}
});
newColumn.prefWidthProperty().bind(table.widthProperty().divide(100/columnWidth));
newColumn.setMinWidth(25);
newColumn.setMaxWidth(50);
newColumn.setCellValueFactory(new PropertyValueFactory<TableData, Integer>("digitCell"));
++numberOfColumns;
return newColumn;
}
}
主类:
public class Main extends Application {
private BorderPane root;
private Button buttAddColumn;
private Button buttDeleteColumn;
private Button buttAddRow;
private Button buttDeleteRow;
private TableView<TableData> tableView;
private HBox hBox;
private ObservableList<TableData> dataList = FXCollections.observableArrayList(/*dodamy tutaj dane kiedy uzytkownik doda nowy rząd*/);
@Override
public void start(Stage primaryStage) {
try {
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
@Override
public void init() {
root = new BorderPane();
//buttony..................
buttAddColumn = new Button("Dodaj kolumnę");
buttAddColumn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
buttAddColumnAction(event);
}
});
buttDeleteColumn = new Button("Usuń kolumnę");
buttDeleteColumn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
buttDeleteColumnAction(event);
}
});
buttAddRow = new Button("Dodaj wiersz");
buttAddRow.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
buttAddRowAction(event);
}
});
buttDeleteRow = new Button("Usuń wiersz");
buttDeleteRow.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
buttDeleteRowAction(event);
}
});
//koniec buttonow................
hBox = new HBox();
tableView = new TableView<TableData>();
hBox.getChildren().addAll(buttAddColumn, buttAddRow, buttDeleteColumn, buttDeleteRow);
tableView.setItems(dataList);
tableView.setPlaceholder(new Label("Click button to add new columns."));
tableView.setEditable(true);
root.setCenter(tableView);
root.setBottom(hBox);
}
private void buttAddRowAction(ActionEvent event) {
Random rand = new Random();
dataList.add(new TableData(rand.nextInt(10)));
}
private void buttDeleteRowAction(ActionEvent event) {
dataList.remove(dataList.size()-1);
}
private void buttAddColumnAction(ActionEvent event) {
tableView.getColumns().add(TableData.addNewColumn(tableView));
}
private void buttDeleteColumnAction(ActionEvent event) {
tableView.getColumns().remove(TableData.numberOfColumns -1);
TableData.numberOfColumns--;
}
}
我认为问题是,如果我想要存储每个单元格值,那么我需要在数据类中有与行中的单元格一样多的变量。但是我不知道如何重新实现程序来做类似的事情。 ?????
答案 0 :(得分:0)
做到了!
在此程序中,用户可以添加行和列,每个单元格都有自己的变量。当用户添加新列时,程序会动态地为每个数据对象创建另一个变量(在数组中)并存储来自此单元格的值。所以改变一个细胞,对任何其他细胞都没有影响...... :)
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. Unique number for each 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){
}
private void buttAddRowAction(ActionEvent event){
dataList.add(new MyData(numberOfColumns));
}
private void buttDeleteRowAction(ActionEvent event){
}
//*******************************************************************
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)));
}
}
//*******************************************************************
@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);
}
}