ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

如何在JavaFX TableView中解决这种视觉故障?

2019-07-06 09:03:15  阅读:236  来源: 互联网

标签:java javafx tableview javafx-8


左列:用于选择或取消选择行的复选框,默认情况下已选中.右列:表示直到(包括行)的所选行数的字符串.因此,取消选中一行中的复选框会更改下方行中的值.

错误:向下滚动到表格的底部.取消选中带有邀请码74的行中的复选框.再次选择它.最后三个邀请码应再次阅读73,74和75.但很多时候,它们显示73,73,74或73,74,74.

该错误并不总是发生!如果没有出现,使用表格的滚动条向上和向下滚动一点并重复上述过程可以使其发生.

似乎这个bug只是可视化的 – 我把ObservableList的内容转储到控制台,它显示了正确的值.除了这个视觉故障,我的应用程序正常工作.单击窗口中的任何其他控件(例如,表格的滚动条)将表格中的邀请代码翻转为正确的值.切换到桌面上的另一个工作区并返回使其显示正确的值.

Small image,显示左侧ObservableList的控制台转储,右侧的错误表.

问题,逻辑上:
我怎么能压扁这个bug!?

编辑:根据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);
    }
}

解决方法:

可能不是最技术性的答案,但通过使用personTable.requestFocus();在doInvCode()方法的末尾,表格在视觉上刷新,似乎解决了问题.

标签:java,javafx,tableview,javafx-8
来源: https://codeday.me/bug/20190706/1395796.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有