gpt4 book ai didi

java - 在 setOnEditCommit JavaFX 后禁用 TableCell

转载 作者:行者123 更新时间:2023-12-04 09:57:40 35 4
gpt4 key购买 nike

我创建了一个可编辑的表,它有一个特定的列 (quantityColumn),当 setOnEditCommit 完成时,只有该列的单元格应该被禁用并且不再可编辑。所以换句话说,他们只被允许进入一次。该程序有一个添加行按钮,用于向表中添加新行,并且 setOnEditCommit 使用来自每列中每个单元格的新值更新数据库。

示例 我的代码的样子:

public class TableViewController implements Initializable {

/**
* Initializes the controller class.
*/
private Connection c = ConnectDB.getInstance().getConnection(); // ConnectDB is a helper that connects to the database
@FXML
private TableView<Item> table;

@FXML
private TableColumn<Item, LocalDate> dateColumn;

@FXML
private TableColumn<Item, LocalTime> timeColumn;

@FXML
private TableColumn<Item, String> quantityColumn;

@Override
public void initialize(URL url, ResourceBundle rb) {


//the following three are custom TableCell classes that allows me to make my cell have a JFX date and time picker.

Callback<TableColumn<Item, LocalDate>, TableCell<Item, LocalDate>> cellFactoryDate =
(TableColumn<Item, LocalDate> param) -> new DatePickerCell();
Callback<TableColumn<Item, LocalTime>, TableCell<Item, LocalTime>> cellFactoryTime =
(TableColumn<Item, LocalTime> param) -> new TimePickerCell();
Callback<TableColumn<Item, String>, TableCell<Item, String>> cellFactoryText =
(TableColumn<Item, String> param) -> new JFXTextFieldCell();


dateColumn.setCellValueFactory(cellData -> cellData.getValue().weekDateProperty());
timeColumn.setCellValueFactory(cellData -> cellData.getValue().timeProperty());
quantityColumn.setCellValueFactory(cellData -> cellData.getValue().quantityProperty());

dateColumn.setCellFactory(cellFactoryDate);
timeColumn.setCellFactory(cellFactoryTime);
quantityColumn.setCellFactory(cellFactoryText);

table.setEditable(true);

dateColumn.setOnEditCommit(event -> {
Item user = event.getRowValue();
user.setWeekDate(event.getNewValue());
updateDate("WeekDate", event.getNewValue(), user.getID());
});
timeColumn.setOnEditCommit(event -> {
Item user = event.getRowValue();
user.setTime(event.getNewValue());
updateTime("Time", event.getNewValue(), user.getID());
});
quantityColumn.setOnEditCommit(event -> {
Item user = event.getRowValue();
user.setQuantity(event.getNewValue());
updateQuantity("Quantity", event.getNewValue(), user.getID());

//I want to disable the cell that has been committed here
});

}

private void updateDate(String column, LocalDate date, int id) {

try {

PreparedStatement stmt = c.prepareStatement("UPDATE Items SET "+column+" = ? WHERE ID = ? ");
stmt.setDate(1, java.sql.Date.valueOf(date));
stmt.setInt(2, id);
stmt.executeUpdate();
} catch (SQLException ex) {
System.err.println("Error");
ex.printStackTrace(System.err);
}
}

private void updateTime(String column, LocalTime time, int id) {

try {

PreparedStatement stmt = c.prepareStatement("UPDATE Items SET "+column+" = ? WHERE ID = ? ");
stmt.setTime(1, java.sql.Time.valueOf(time));
stmt.setInt(2, id);
stmt.executeUpdate();
} catch (SQLException ex) {
System.err.println("Error");
ex.printStackTrace(System.err);
}
}

private void updateQuantity(String column, String quantity, int id) {

try {

PreparedStatement stmt = c.prepareStatement("UPDATE Items SET "+column+" = ? WHERE ID = ? ");
stmt.setString(1, quantity);
stmt.setInt(2, id);
stmt.executeUpdate();
} catch (SQLException ex) {
System.err.println("Error");
ex.printStackTrace(System.err);
}
}
@FXML
private void addRow(ActionEvent event) {

// get current position
TablePosition pos = table.getFocusModel().getFocusedCell();

// clear current selection
table.getSelectionModel().clearSelection();

// create new record and add it to the model
Item data = new Item();
table.getItems().add(data);
// get last row
int row = table.getItems().size() - 1;
table.getSelectionModel().select( row, pos.getTableColumn());

// scroll to new row
table.scrollTo( data);

}

}

项目 :
public class Item {

private final IntegerProperty id;
private final ObjectProperty<LocalDate> weekDate;
private final ObjectProperty<LocalTime> time;
private final StringProperty quantity;


public Item() {
this(0, null, null, null);
}
/**
* Constructor with some initial data.
* @param id
* @param weekDate
* @param time
* @param quantity
*
*/
public Item(int id, LocalDate weekDate, LocalTime time, String quantity) {
this.id = new SimpleIntegerProperty(id);
this.weekDate = new SimpleObjectProperty(weekDate);
this.time = new SimpleObjectProperty(time);
this.quantity = new SimpleStringProperty(quantity);

}


public int getID() {
return id.get();
}

public void setID(int id) {
this.id.set(id);
}

public IntegerProperty idProperty() {
return id;
}

public LocalDate getWeekDate() {
return weekDate.get();
}

public void setWeekDate(LocalDate weekDate) {
this.weekDate.set(weekDate);
}

public ObjectProperty<LocalDate> weekDateProperty() {
return weekDate;
}


public LocalTime getTime() {
return time.get();
}

public void setTime(LocalTime time) {
this.time.set(time);
}

public ObjectProperty<LocalTime> timeProperty() {
return time;
}

public String getQuantity() {
return quantity.get();
}

public void setQuantity(String quantity) {
this.quantity.set(quantity);
}

public StringProperty quantityProperty() {
return quantity;
}
}

TableView FXML
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="disablecelltest.TableViewController">
<children>
<TableView fx:id="table" editable="true" layoutX="61.0" layoutY="70.0" prefHeight="292.0" prefWidth="479.0">
<columns>
<TableColumn fx:id="dateColumn" prefWidth="75.0" text="Date" />
<TableColumn fx:id="timeColumn" prefWidth="75.0" text="Time" />
<TableColumn fx:id="quantityColumn" prefWidth="75.0" text="Quantity" />
</columns>
</TableView>
<JFXButton buttonType="RAISED" contentDisplay="TEXT_ONLY" graphicTextGap="10.0" layoutX="10.0" layoutY="10.0" onAction="#addRow" text="ADD RECORD" textAlignment="CENTER">
<font>
<Font name="Dosis SemiBold" size="18.0" />
</font>
</JFXButton>
</children>
</AnchorPane>

我试过在这里寻找答案。这是 one answer我尝试并在没有条件的情况下对其进行了修改,它禁用了整个列而不是那个特定的单元格,因为我没有该项目的条件,我只想在仅输入一次时禁用该项目。我试过 this以及。

编辑:
这是我用于数量的自定义 JFXTextField:
public class JFXTextFieldCell extends TableCell<Item, String> {

private JFXTextField textField;

public JFXTextFieldCell() {
}

@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 JFXTextField(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) {
commitEdit(textField.getText());
}
});
}

private String getString() {
return getItem() == null ? "" : getItem();
}
}

最佳答案

简单地禁用(或使其不可编辑)当前单元格是行不通的;单元格将被重新分配,例如如果用户在表格周围滚动,那么错误的单元格最终将无法编辑。

您需要向模型添加一些属性(或在其他地方存储一些可以通过模型实例访问的属性)并实现一个自定义单元格来观察这些属性,从而适本地更新可编辑状态。

像下面这样的东西应该工作:

ObservableSet<Item> quantityEditedItems = FXCollections.observableSet();

quantityColumn.setCellFactory(tc -> new TextFieldTableCell<>(new IntegerStringConverter()) {
@Override
public void updateItem(Integer quantity, boolean empty) {
super.updateItem(quantity, empty) ;
editableProperty().unbind();
if (empty) {
setEditable(false);
} else {
editableProperty().bind(Bindings.createBooleanBinding(() ->
! quantityEditedItems.contains(getTableView().getItems().get(getIndex())),
quantityEditedItems));
}
}
});

然后你可以做
quantityColumn.setOnEditCommit(event -> {
StudentPresc user = event.getRowValue(); // should this be Item?
user.setQuantity(event.getNewValue());
updateQuantity("Quantity", event.getNewValue(), user.getID());

quantityEditedItems.add(event.getRowValue());
});

这是一个完整的工作示例:
import java.util.Random;

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableSet;
import javafx.collections.SetChangeListener.Change;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.converter.IntegerStringConverter;

public class EditOnceTable extends Application {

@Override
public void start(Stage primaryStage) throws Exception {

TableView<Item> table = new TableView<>();
table.setEditable(true);
TableColumn<Item, String> itemColumn = new TableColumn<>("Item");
itemColumn.setCellValueFactory(cellData -> cellData.getValue().nameProperty());

TableColumn<Item, Integer> quantityColumn = new TableColumn<>("Quantity");
quantityColumn.setCellValueFactory(cellData -> cellData.getValue().quantityProperty().asObject());
quantityColumn.setEditable(true);

table.getColumns().add(itemColumn);
table.getColumns().add(quantityColumn);

ObservableSet<Item> quantityEditedItems = FXCollections.observableSet();

quantityColumn.setCellFactory(tc -> new TextFieldTableCell<>(new IntegerStringConverter()) {
@Override
public void updateItem(Integer quantity, boolean empty) {
super.updateItem(quantity, empty) ;
editableProperty().unbind();
if (empty) {
setEditable(false);
} else {
editableProperty().bind(Bindings.createBooleanBinding(() ->
! quantityEditedItems.contains(getTableView().getItems().get(getIndex())),
quantityEditedItems));
}
}
});

quantityColumn.setOnEditCommit(event -> {
Item item = event.getRowValue(); // should this be Item?
item.setQuantity(event.getNewValue());
// updateQuantity("Quantity", event.getNewValue(), user.getID());

quantityEditedItems.add(event.getRowValue()) ;
});

ListView<Item> editedItemsView = new ListView<>();
quantityEditedItems.addListener((Change<? extends Item> change) ->
editedItemsView.getItems().setAll(quantityEditedItems)
);
editedItemsView.setCellFactory(lv -> new ListCell<>() {
@Override
protected void updateItem(Item item, boolean empty) {
super.updateItem(item, empty);
if (empty || item==null) {
setText("");
} else {
setText(item.getName());
}
}
});
Button clear = new Button("Clear edited");
clear.setOnAction(e -> quantityEditedItems.clear());

Random rng = new Random();
for (int i = 1 ; i <= 40 ; i++) {
table.getItems().add(new Item("Item "+i, rng.nextInt(100)));
}

BorderPane root = new BorderPane(table);
root.setRight(new VBox(5, new Label("Edited:"), editedItemsView, clear));

Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}


public static class Item {
private final StringProperty name = new SimpleStringProperty() ;
private final IntegerProperty quantity = new SimpleIntegerProperty();

public Item(String name, int quantity) {
setName(name);
setQuantity(quantity);
}

public StringProperty nameProperty() {
return name ;
}

public final String getName() {
return nameProperty().get();
}

public final void setName(String name) {
nameProperty().set(name);
}

public IntegerProperty quantityProperty() {
return quantity ;
}

public final int getQuantity() {
return quantityProperty().get();
}

public final void setQuantity(int quantity) {
quantityProperty().set(quantity);
}
}

public static void main(String[] args) {
Application.launch(args);
}

}

关于java - 在 setOnEditCommit JavaFX 后禁用 TableCell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61890166/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com