英文:
Javafx adding row dynamically duplicates data
问题
以下是您提供的代码的翻译部分:
<TableView fx:id="tblPersonalExterno" prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
<columns>
<TableColumn prefWidth="781.0000244379044">
<graphic>
<Label text="Externo" />
</graphic>
<columns>
<TableColumn fx:id="tblcNombreExterno" prefWidth="270" text="Nombre"/>
<TableColumn fx:id="tblcEmpresaExterno" prefWidth="270" text="Empresa" />
<TableColumn fx:id="tblcInfPRLExterno" minWidth="0.0" prefWidth="59.0">
<graphic>
<Label text="Inf. PRL">
<tooltip>
<Tooltip text="Informado PRL" />
</tooltip>
</Label>
</graphic>
</TableColumn>
<TableColumn fx:id="tblcAprobadoPRLExterno" minWidth="0.0" prefWidth="73.00003051757812">
<graphic>
<Label text="Apr. Cl. PRL">
<tooltip>
<Tooltip text="Aprobado cliente PRL" />
</tooltip>
</Label>
</graphic>
</TableColumn>
<TableColumn fx:id="tblcFechaAprPRLExterno" prefWidth="100.0">
<graphic>
<Label text="Fecha apr.">
<tooltip>
<Tooltip text="Fecha de aprobación" />
</tooltip>
</Label>
</graphic>
</TableColumn>
<TableColumn prefWidth="60.0" text="Validez PRL">
<columns>
<TableColumn fx:id="tblcFechaDesdePRLExterno" prefWidth="100.0" text="Desde" />
<TableColumn fx:id="tblcFechaHastaPRLExterno" prefWidth="100.0" text="Hasta" />
</columns>
</TableColumn>
</columns>
</TableColumn>
</columns>
</TableView>
<ToolBar prefHeight="40.0" prefWidth="200.0">
<items>
<Button fx:id="btnAñadirExterno" mnemonicParsing="false" onAction="#addExterno">
<graphic>
<FontIcon iconLiteral="mdi-account-plus"
iconSize="16" />
</graphic>
<tooltip>
<Tooltip text="Añadir Personal Externo" />
</tooltip>
</Button>
<Button fx:id="btnEliminarExterno" mnemonicParsing="false">
<graphic>
<FontIcon iconLiteral="mdi-delete-forever"
iconSize="16" />
</graphic>
<tooltip>
<Tooltip text="Eliminar Personal Externo" />
</tooltip>
</Button>
</items>
</ToolBar>
public class DetailsController {
private ObservableList<Responsable> listaPersonalExterno = FXCollections.observableArrayList();
@FXML
private TableView<Responsable> tblPersonalExterno;
@FXML
private TableColumn<Responsable, String> tblcNombreExterno;
@FXML
private TableColumn<Responsable, String> tblcEmpresaExterno;
@FXML
private TableColumn<Responsable, Boolean> tblcInfPRLExterno;
@FXML
private TableColumn<Responsable, Boolean> tblcAprobadoPRLExterno;
@FXML
private TableColumn<Responsable, LocalDate> tblcFechaAprPRLExterno;
@FXML
private TableColumn<Responsable, LocalDate> tblcFechaDesdePRLExterno;
@FXML
private TableColumn<Responsable, LocalDate> tblcFechaHastaPRLExterno;
public DetailsController() {
cargarPersonalExterno();
}
public ObservableList<Responsable> listaPersonalExterno() {
return listaPersonalExterno;
}
@FXML
public void initialize() {
doBindTablaPersonalExterno();
}
private void doBindTablaPersonalExterno() {
tblcNombreExterno.setCellValueFactory(new PropertyValueFactory<Responsable, String>("nombre"));
tblcNombreExterno.setCellFactory(col -> {
TableCell<Responsable, String> cell = new TableCell<Responsable, String>() {
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText("");
} else {
TextField tf = new TextField();
tf.setText(item);
setGraphic(tf);
}
}
};
return cell;
});
// 省略其他列的绑定和单元格工厂的设置
}
/**
* Carga el personal externo
*/
private void cargarPersonalExterno() {
List<Responsable> lista = new ArrayList<Responsable>();
Responsable r1 = new Responsable();
r1.setNombre("NEUS");
Responsable r2 = new Responsable();
r2.setNombre("PEPE");
lista.add(r1);
lista.add(r2);
listaPersonalExterno.addAll(lista);
}
@FXML
public void addExterno() {
Responsable r = new Responsable();
listaPersonalExterno.add(r);
}
}
这是您提供的代码的翻译版本。如果您需要进一步的帮助或有其他问题,请随时提问。
英文:
I have a Tableview in Javafx in which I'm trying to add a row dynamically when user presses a button. The problem is that when doing it the previous data in the table gets duplicated. I must say that if I print the size of the items in the table, it returns the correct size, without the duplciates and that I can't select the duplicated items nor scroll to see them all.
Here is my code:
detail.fxml
<TableView fx:id="tblPersonalExterno" prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
<columns>
<TableColumn prefWidth="781.0000244379044">
<graphic>
<Label text="Externo" />
</graphic>
<columns>
<TableColumn fx:id="tblcNombreExterno" prefWidth="270" text="Nombre"/>
<TableColumn fx:id="tblcEmpresaExterno" prefWidth="270" text="Empresa" />
<TableColumn fx:id="tblcInfPRLExterno" minWidth="0.0" prefWidth="59.0">
<graphic>
<Label text="Inf. PRL">
<tooltip>
<Tooltip text="Informado PRL" />
</tooltip>
</Label>
</graphic>
</TableColumn>
<TableColumn fx:id="tblcAprobadoPRLExterno" minWidth="0.0" prefWidth="73.00003051757812">
<graphic>
<Label text="Apr. Cl. PRL">
<tooltip>
<Tooltip text="Aprobado cliente PRL" />
</tooltip>
</Label>
</graphic>
</TableColumn>
<TableColumn fx:id="tblcFechaAprPRLExterno" prefWidth="100.0">
<graphic>
<Label text="Fecha apr.">
<tooltip>
<Tooltip text="Fecha de aprobación" />
</tooltip>
</Label>
</graphic>
</TableColumn>
<TableColumn prefWidth="60.0" text="Validez PRL">
<columns>
<TableColumn fx:id="tblcFechaDesdePRLExterno" prefWidth="100.0" text="Desde" />
<TableColumn fx:id="tblcFechaHastaPRLExterno" prefWidth="100.0" text="Hasta" />
</columns>
</TableColumn>
</columns>
</TableColumn>
</columns>
</TableView>
<ToolBar prefHeight="40.0" prefWidth="200.0">
<items>
<Button fx:id="btnAñadirExterno" mnemonicParsing="false" onAction="#addExterno">
<graphic>
<FontIcon iconLiteral="mdi-account-plus"
iconSize="16" />
</graphic>
<tooltip>
<Tooltip text="Añadir Personal Externo" />
</tooltip>
</Button>
<Button fx:id="btnEliminarExterno" mnemonicParsing="false">
<graphic>
<FontIcon iconLiteral="mdi-delete-forever"
iconSize="16" />
</graphic>
<tooltip>
<Tooltip text="Eliminar Personal Externo" />
</tooltip>
</Button>
</items>
</ToolBar>
DetailsController.java
public class DetailsController {
private ObservableList<Responsable> listaPersonalExterno = FXCollections.observableArrayList();
@FXML
private TableView<Responsable> tblPersonalExterno;
@FXML
private TableColumn<Responsable, String> tblcNombreExterno;
@FXML
private TableColumn<Responsable, String> tblcEmpresaExterno;
@FXML
private TableColumn<Responsable, Boolean> tblcInfPRLExterno;
@FXML
private TableColumn<Responsable, Boolean> tblcAprobadoPRLExterno;
@FXML
private TableColumn<Responsable, LocalDate> tblcFechaAprPRLExterno;
@FXML
private TableColumn<Responsable, LocalDate> tblcFechaDesdePRLExterno;
@FXML
private TableColumn<Responsable, LocalDate> tblcFechaHastaPRLExterno;
public DetailsController() {
cargarPersonalExterno();
}
public ObservableList<Responsable> listaPersonalExterno(){
return listaPersonalExterno;
}
@FXML
public void initialize() {
doBindTablaPersonalExterno();
}
private void doBindTablaPersonalExterno() {
tblcNombreExterno.setCellValueFactory(new PropertyValueFactory<Responsable, String>("nombre"));
tblcNombreExterno.setCellFactory(col -> {
TableCell<Responsable, String> cell = new TableCell<Responsable, String>(){
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if(empty) {
setText("");
}else {
TextField tf = new TextField();
tf.setText(item);
setGraphic(tf);
}
}
};
return cell;
});
tblcEmpresaExterno.setCellValueFactory(new PropertyValueFactory<Responsable, String>("empresa"));
tblcEmpresaExterno.setCellFactory(col -> {
TableCell<Responsable, String> cell = new TableCell<Responsable, String>(){
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if(empty) {
setText("");
}else {
TextField tf = new TextField();
tf.setText(item);
setGraphic(tf);
}
}
};
return cell;
});
tblcInfPRLExterno.setCellValueFactory(cellData -> new SimpleBooleanProperty(cellData.getValue().getPrl().isInformado()));
tblcInfPRLExterno.setCellFactory(col -> {
TableCell<Responsable, Boolean> cell = new TableCell<Responsable, Boolean>(){
@Override
public void updateItem(Boolean item, boolean empty) {
super.updateItem(item, empty);
if(empty) {
setText("");
}else {
CheckBox chk = new CheckBox();
setStyle("-fx-alignment: CENTER;");
if(item != null) {
chk.setSelected(item);
}
setGraphic(chk);
}
}
};
return cell;
});
tblcAprobadoPRLExterno.setCellValueFactory(cellData -> new SimpleBooleanProperty(cellData.getValue().getPrl().isAprobado()));
tblcAprobadoPRLExterno.setCellFactory(col -> {
TableCell<Responsable, Boolean> cell = new TableCell<Responsable, Boolean>(){
@Override
public void updateItem(Boolean item, boolean empty) {
super.updateItem(item, empty);
if(empty) {
setText("");
}else {
CheckBox chk = new CheckBox();
setStyle("-fx-alignment: CENTER;");
if(item != null) {
chk.setSelected(item);
}
setGraphic(chk);
}
}
};
return cell;
});
tblcFechaAprPRLExterno.setCellValueFactory(cellData -> new SimpleObjectProperty<LocalDate>(cellData.getValue().getPrl().getFechaAprobacion()));
tblcFechaAprPRLExterno.setCellFactory(col -> {
TableCell<Responsable, LocalDate> cell = new TableCell<Responsable, LocalDate>(){
@Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
if(empty) {
setText("");
}else {
DatePicker dp = new DatePicker();
setStyle("-fx-alignment: CENTER;");
dp.setValue(item);
setGraphic(dp);
}
}
};
return cell;
});
tblcFechaDesdePRLExterno.setCellValueFactory(cellData -> new SimpleObjectProperty<LocalDate>(cellData.getValue().getPrl().getValidez().getInicio()));
tblcFechaDesdePRLExterno.setCellFactory(col -> {
TableCell<Responsable, LocalDate> cell = new TableCell<Responsable, LocalDate>(){
@Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
if(empty) {
setText("");
}else {
DatePicker dp = new DatePicker();
setStyle("-fx-alignment: CENTER;");
dp.setValue(item);
setGraphic(dp);
}
}
};
return cell;
});
tblcFechaHastaPRLExterno.setCellValueFactory(cellData -> new SimpleObjectProperty<LocalDate>(cellData.getValue().getPrl().getValidez().getInicio()));
tblcFechaHastaPRLExterno.setCellFactory(col -> {
TableCell<Responsable, LocalDate> cell = new TableCell<Responsable, LocalDate>(){
@Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
if(empty) {
setText("");
}else {
DatePicker dp = new DatePicker();
setStyle("-fx-alignment: CENTER;");
dp.setValue(item);
setGraphic(dp);
}
}
};
return cell;
});
}
/**
* Carga el personal externo
*/
private void cargarPersonalExterno() {
List<Responsable> lista = new ArrayList<Responsable>();
Responsable r1 = new Responsable();
r1.setNombre("NEUS");
Responsable r2 = new Responsable();
r2.setNombre("PEPE");
lista.add(r1);
lista.add(r2);
listaPersonalExterno.addAll(lista);
}
@FXML
public void addExterno() {
Responsable r = new Responsable();
listaPersonalExterno.add(r);
}
}
Here is an image of the behaviour. The duplicated rows under the blank one seem to not exists because I can't select them, can't scroll and can't access to them by code.
答案1
得分: 5
你的代码问题在于当项目为空或为null时,你只将文本设置为null,但没有设置图形。因此,当行/单元格被重用时,图形部分仍然保留在单元格中。
在所有的单元格工厂中,当项目为空时,重置文本和图形。另外,在updateItem方法中创建新节点是一个不好的主意。应该在每个单元格实例中创建DatePicker,并在updateItem中将其设置为图形,类似于以下代码:
tblcFechaDesdePRLExterno.setCellFactory(col -> {
TableCell<Responsable, LocalDate> cell = new TableCell<Responsable, LocalDate>() {
private DatePicker dp = new DatePicker();
@Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null); // 这在你的代码中缺失了
} else {
setStyle("-fx-alignment: CENTER;");
dp.setValue(item);
setGraphic(dp);
}
}
};
return cell;
});
英文:
The problem with your code is when your item is empty or null, you are only setting the text to null but not the graphic. So the graphic part will still stay in the cell when the row/cell is reused.
Reset both the text and graphic when the item is empty in all your cell factories. And also it is a bad idea to create new nodes in the updateItem method. Create the DatePicker per cell instance and set it as graphic in the updateItem. Something like :
tblcFechaDesdePRLExterno.setCellFactory(col -> {
TableCell<Responsable, LocalDate> cell = new TableCell<Responsable, LocalDate>(){
private DatePicker dp = new DatePicker();
@Override
public void updateItem(LocalDate item, boolean empty) {
super.updateItem(item, empty);
if(empty) {
setText(null);
setGraphic(null); // THIS IS MISSING IN YOUR CODE
}else {
setStyle("-fx-alignment: CENTER;");
dp.setValue(item);
setGraphic(dp);
}
}
};
return cell;
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论