【发布时间】:2016-04-17 08:14:59
【问题描述】:
左列:用于选择或取消选择行的复选框,默认选中。右列:一个字符串,表示直到并包括该行的选定行的数量。因此,取消选中一行中的复选框会更改下面行中的值。
错误:向下滚动到表格底部。取消选中邀请代码为 74 的行中的复选框。再次选中它。最后三个邀请码应再次显示为 73、74 和 75。但很多时候,它们会显示 73、73、74 或 73、74、74。
错误并不总是发生!如果没有出现,用表格的滚动条上下滚动一下,重复上面的过程,就可以让它出现。
似乎这个错误只是视觉上的——我让它将 ObservableList 的内容转储到控制台并显示正确的值。除了这个视觉故障之外,我的应用程序可以正常工作。单击窗口中的任何其他控件(例如表格的滚动条)会将表格中的邀请码翻转为正确的值。切换到我桌面上的另一个工作区并返回使其也显示正确的值。
Small image,左侧显示 ObservableList 的控制台转储,右侧显示错误表。
问题,非常合乎逻辑: 我该如何解决这个错误!?
编辑:按照 Kleopatra 的建议抛出更多代码。谢谢!
MCV:
FXMLDocumentController.java
package invcodebug;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.util.Callback;
public class FXMLDocumentController implements Initializable {
@FXML private TableView<Person> personTable;
@FXML private TableColumn<Person, Boolean> invitedCol;
@FXML private TableColumn<Person, String> inviteCodeCol;
private final ObservableList<Person> persons
= FXCollections.observableArrayList();
@Override
public void initialize(URL location, ResourceBundle resources) {
initPersonTable();
populatePersons();
}
private void initPersonTable() {
invitedCol.setCellValueFactory(new PropertyValueFactory<>("invited"));
inviteCodeCol.setCellValueFactory(new PropertyValueFactory<>("inviteCode"));
invitedCol.setCellFactory(CheckBoxTableCell.forTableColumn(new Callback<Integer, ObservableValue<Boolean>>() {
@Override
public ObservableValue<Boolean> call(Integer param) {
doInvCode();
// SHOWS: underlying ObservableList has correct values
System.out.println("--------------------------");
for (Person p : persons) {
System.out.println(p.isInvited() + " " + p.getInviteCode()
);
}
return persons.get(param).invitedProperty();
}
}));
personTable.setItems(persons);
}
private void doInvCode() {
int invCounter = 1;
for (Person p : persons) {
if (p.isInvited()) {
p.setInviteCode(((Integer) invCounter).toString());
invCounter++;
} else p.setInviteCode("");
}
}
private void populatePersons() {
for (int i = 0; i < 75; i++) {
persons.add(new Person(true, ""));
}
}
}
Person.java
package invcodebug;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
public class Person {
private final SimpleBooleanProperty invited;
private final SimpleStringProperty inviteCode;
public Person(boolean invited, String inviteCode) {
this.invited = new SimpleBooleanProperty(invited);
this.inviteCode = new SimpleStringProperty(inviteCode);
}
public boolean isInvited() {
return invited.get();
}
public SimpleBooleanProperty invitedProperty() {
return invited;
}
public String getInviteCode(){
return inviteCode.get();
}
public void setInviteCode(String invCode) {
this.inviteCode.set(invCode);
}
public SimpleStringProperty inviteCodeProperty() {
return inviteCode;
}
}
FXMLDocument.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane id="AnchorPane" prefHeight="464.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="invcodebug.FXMLDocumentController">
<children>
<TableView fx:id="personTable" editable="true" layoutX="26.0" layoutY="28.0" prefHeight="347.0" prefWidth="572.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="20.0">
<columns>
<TableColumn fx:id="invitedCol" prefWidth="27.0" sortable="false" />
<TableColumn fx:id="inviteCodeCol" editable="false" prefWidth="110.0" resizable="false" sortable="false" text="Invite Code" />
</columns>
</TableView>
</children>
</AnchorPane>
InvCodeBug.java
package invcodebug;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class InvCodeBug extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
【问题讨论】:
-
对我来说看起来像一个错误(一旦单元格被重新使用,即在一些滚动之后,就会在任何行发生) - 您可以考虑报告它。无关:下一次,请提供尽可能短的示例来说明问题(所有带有微调器、文本字段或编辑名称列的东西都可能被丢弃)
-
@kleopatra 向 Oracle 报告了错误,已编辑问题。感谢您的建议!
标签: java javafx tableview javafx-8