JavaFX TableView 滚动

2024-01-11

我的 TableView 包含一些数字数据。当我说通过按钮编辑值时,它将单元格的背景更改为绿色。当没有足够的行使表可滚动时,这种方法很有效。一旦表格变得(或从一开始)可滚动,它就会开始表现得很奇怪。它会更改已编辑项目的背景,但它会更改在向下滚动之前不可见的项目的背景。但是,当我调试时,更改背景的代码仅被调用一次。我认为当可滚动破坏并重新创建单元格时,它必须对表格视图做一些事情,或者也许我误解了某些东西并且我做错了。

Example: I've edited second row. I've edited second row

And when I scrolled down just a little bit, this one had different background as well. (they both have it same time) This one got edited as well

代码: 型号类别:

public class Bid {

  private DoubleProperty value; 
  private BooleanProperty valueChanged;

  public Bid(double val) {
    value = new SimpleDoubleProperty();
    valueChanged = new SimpleBooleanProperty();
    setValue(val);
    value.addListener((observable, old, newVal) -> {
      System.out
          .println(observable.toString() + " changed value from " + old.doubleValue() + " to " + newVal.doubleValue());
      valueChanged.setValue(true);
    });
  }

  public double getValue() {
    return value.get();
  }

  public void setValue(double value) {
    this.value.set(value);
  }

  public DoubleProperty valueProperty() {
    return value;
  }

  public boolean isValueChanged() {
    return valueChanged.get();
  }

  public BooleanProperty valueChangedProperty() {
    return valueChanged;
  }

  public void setValueChanged(boolean valueChanged) {
    this.valueChanged.set(valueChanged);
  }

  @Override
  public String toString() {
    return "Bid{" +
        "value=" + value.getValue() +
        '}';
  }
}

我的单元格(当我第一次遇到这个问题时,我认为这是样式删除部分,但删除它没有帮助):

public class BidCell extends TextFieldTableCell<Bid, Double> {


  private BooleanProperty newExternalValue;

  public BidCell() {
    super(new StringConverter<Double>() { // converter used for conversion from/to string


      @Override
      public String toString(Double object) {
        return object.toString();
      }

      @Override
      public Double fromString(String string) {
        return Double.valueOf(string);
      }
    });

    newExternalValue = new SimpleBooleanProperty();

    newExternalValue.addListener((observable, oldValue, newValue) ->
    {
      if (newValue) {
        String old = this.getStyle();
        this.setStyle("-fx-background-color: #99ff99");
        System.out.println("Color changed");
        Thread thread = new Thread(new StyleRemover(this, old, newExternalValue));
        thread.setDaemon(true);
        thread.start();
      }
    });
  }


  @Override
  public void updateItem(Double item, boolean empty) {
    super.updateItem(item, empty);
    if (getTableRow() != null) {
      if (getTableRow().getItem() != null) {
        if (item != null && !empty) {

          Bid b = getTableRow().getItem() instanceof Bid ? ((Bid) getTableRow().getItem()) : null;
          if (b != null) {
            if (b.isValueChanged()) {
              System.out.println("Setting newExternalValue to true for cell" + this);
              newExternalValue.setValue(true);
              b.setValueChanged(false);
            }
          }
        }
      }
    }
  }

  class StyleRemover implements Runnable {

    private BidCell cell;
    private String oldStyle;
    BooleanProperty newExternalValue;

    public StyleRemover(BidCell cell, String oldStyle, BooleanProperty newExternalValue) {
      this.cell = cell;
      this.oldStyle = oldStyle;
      this.newExternalValue = newExternalValue;
    }

    @Override
    public void run() {
      try {
        Thread.sleep(3000);
        cell.setStyle(oldStyle);
        newExternalValue.setValue(false);
      }
      catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }

Grid:

public class Grid {

  private TableView<Bid> view;
  private TableColumn<Bid, Double> bidStringTableColumn;
  ObservableList<Bid> bids;

  public TableView<Bid> getView() {
    return view;
  }

  public Grid() {
    view = new TableView<>(); // create tableview

    bids = FXCollections.observableArrayList(); // fill data for it
    bids.addListener((ListChangeListener<Bid>) c -> {
      c.next();
      if (c.wasAdded()) {
        System.out.println("added new value " + c.getAddedSubList().get(0).toString());
      }
    });
    for (double i = 0; i < 10; i += 0.45) {
      Bid e = new Bid(i);

      bids.add(e);
    }
    view.setItems(bids);
    view.setEditable(true);

    bidStringTableColumn = new TableColumn<>("Bid"); // create column with header text "Bid"
    bidStringTableColumn.setCellValueFactory(param -> param.getValue().valueProperty()
        .asObject()); // value factory for column, determines which property will fill column
    bidStringTableColumn.setCellFactory(e -> new BidCell());

    view.getColumns().add(bidStringTableColumn); // add column to table
  }


  public ObservableList<Bid> getBids() {
    return bids;
  }

编辑:这不仅仅是样式问题,我发现如果我开始编辑该单元格并向下滚动,该单元格也处于编辑模式。一种可能的解决方案可能只是以某种方式禁用单元格破坏和重新创建滚动,但是我还没有找到一种方法来做到这一点,我认为这是不可能的。 (我知道它是为了性能而存在,但性能对我们来说并不重要,并且不会有数百万行,最多大约 100 行)


我花了一些时间,但我解决了。 最重要的是这句话

“tableview 和 listview 单元格被重用来渲染不同的行 源列表的数据。”

这基本上意味着您无法将样式设置为单元格,因为当您滚动时它会用于不同的数据。那是我的错误。

最简单的解决方案是将样式存储在模型( Bid )类中,然后在单元格中从那里获取它。 在单元格中我做了方法

 public void checkStyle() {
    if (getTableRow().getItem() != null) {
      Bid bid = (Bid) getTableRow().getItem();
      this.setDisabled(bid.isDisabled());
      String style = bid.getStyle();
      if (!this.getStyle().equals(style) && getItem() == bid.getValue()) 
          this.setStyle(style);
    }

我打电话进来updateItem and updateIndex并在

  newExternalValue.addListener((observable, oldValue, newValue) ->
    {
      checkStyle();
    });
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JavaFX TableView 滚动 的相关文章

随机推荐

  • 如何更改BitBucket中的主分支?

    我在 bitbucket 上有一个有两个分支的仓库 第一个分支是具有虚假内容的 master 分支 然后我有另一个名为 trunk 的具有正确内容的分支 我想将主分支更改为主干 实际上是master 我发现在 bitbucket web 上
  • Hilt ClassCastException:ViewComponentManager$FragmentContextWrapper 无法转换为 AppCompatActivity

    我有这段代码 当单击适配器中的 viewHolder 项目时 我会显示对话框片段 SpecialRequestNotFoundBottomSheetDialog requestItem specialRequestEntity id let
  • cURL 和重定向 - 返回多个标头?

    我正在编写一个专门的 PHP 代理 并被 cURL 的一个功能所困扰 如果设置了以下值 curl setopt ch CURLOPT FOLLOWLOCATION true curl setopt ch CURLOPT HEADER tru
  • x-editable - 调整输入字段的宽度

    如何调整弹出窗口的输入宽度 似乎没有任何选项 http vitalets github io x editable docs html text http vitalets github io x editable docs html te
  • 使用 CDI @Inject 注入 Spring bean

    我试图将 Spring 上下文中定义的 bean 注入到 CDI 托管组件中 但没有成功 bean 不会被注入 而是在每次执行注入时创建一个新实例 我的环境是带有 JBoss Weld 的 Tomcat 7 Spring Applicati
  • 导入错误:DLL 加载失败:%1 不是有效的 Win32 应用程序。但DLL在那里

    我的情况非常类似于错误 ImportError DLL 加载失败 1 不是有效的 Win32 应用程序 https stackoverflow com questions 14629818 importerror dll load fail
  • 为什么 gt() 和 lt() 只是 jQuery 选择器,而 eq() 也是一个方法?

    在 jQuery 中 为什么只eq 既是选择器 又是方法 而是gt and lt 只是选择器 对象不支持该属性或方法 jQuery 语法的这种不一致 差距是否有我不明白的特殊原因 eq click function alert li eq
  • 如何在 XMLSlurper 语句中使用变量引用

    我正在使用带有 XMLSlurper 的 groovy 来验证soap ui pro 中的 Web 服务响应 我有以下有效代码 expectedResponse 是存储预期错误代码的 var 例如 E0023 if expectedResp
  • Xcode 数据模型编辑器未出现

    我正在使用 Xcode 4 2 并且正在尝试使用 Core Data 单击 xcdatamodeld 文件后 我看到一个奇怪的视图 而不是数据模型编辑器视图 我已经重新安装了 Xcode 4 2 甚至从头开始创建了一个启用 Core Dat
  • 如何删除 MASM 中未使用的 .CONST 数据?

    我在 MASM 中使用宏生成大约 2000 个函数 为每个函数定义一个字符串 但在任何给定程序中我只使用大约 30 个函数 无法提前预测我将使用哪些 我根据需要使用它们 有什么方法可以告诉链接器 删除 我最终没有使用的字符串吗 他们将二进制
  • 如何使用图像类型按钮删除 HTML 表单中提交时的 x 和 y?

    我在我的应用程序中创建了一个表单 如下所示
  • 免费矢量图标[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有用于基本桌面程序工具栏按钮 如后退 前进 打印 保存等 的免费矢量图标 例如 适合在使用 WPF
  • 在 JSON 键或值中使用双引号

    我想使用双引号 在我的 JSON 中 但它不起作用 这是我的 JSON I 1 Vehicle Con trol M D2 VM 3300 00 VSD 324 04 G 1 Ve hicle Control M N 1 http json
  • Java 日期解析“上午”和“下午”

    使用 SimpleDateFormat 如何解析字符串 2013 05 23T09 18 07 下午 380 0000 我所有的 SimpleDateFormat 字符串都在 p m part 提前致谢 编辑 我们无法控制传入的格式 我试过
  • 如何要求 Neo4j 考虑周期

    Neo4j 似乎故意省略了循环 因此查询如下 MATCH n1 R gt n2 lt R n1 RETURN n1 n2 除非存在两个类型关系 否则始终不返回任何内容R之间n1 and n2 这绝对是可能的 而且是一个糟糕的黑客 但我有一个
  • Oracle:从字符串中删除前 4 个字符

    所以我想从oracle中的字符串中删除前4个字符 这些角色每次都可能不同 就我而言 我需要去掉 IBAN 的前 4 个字符并将它们放在字符串的末尾 我得到了将它们放在字符串末尾的部分 但我无法删除前 4 个字符 我在互联网上找到的每个解决方
  • 我怎样才能安全地执行Python的子集?

    我需要在数据库中存储基本功能的源代码 并允许通过管理界面对其进行修改 这段代码将接受几个数字和字符串作为参数 并返回一个数字或None 我知道 eval 是邪恶的 所以我需要实现一种安全的方法来从基于 python 的网络应用程序中执行 p
  • Django 管理员,无法分组依据:异常值:“dict”对象没有属性“_meta”

    我有一个映射到 postgresql 视图的模型 class AppModel models Model nbr models BigIntegerField blank True null True region models Forei
  • 是否可以从 heroku 检索您的源代码?

    将源代码上传到 Heroku 后 如果需要 例如本地磁盘出现故障 是否可以从那里下载它 由于 Heroku 与 git 的集成 我认为这至少在理论上是可能的 只要去https dashboard heroku com apps YOUR A
  • JavaFX TableView 滚动

    我的 TableView 包含一些数字数据 当我说通过按钮编辑值时 它将单元格的背景更改为绿色 当没有足够的行使表可滚动时 这种方法很有效 一旦表格变得 或从一开始 可滚动 它就会开始表现得很奇怪 它会更改已编辑项目的背景 但它会更改在向下