添加数据时,JavaFX TableView选择了单元格闪烁

时间:2017-03-31 10:59:43

标签: java javafx javafx-8

我有一个启用了单细胞选择的JavaFX TableView。当用户选择一个单元格时,当新数据添加到表格时,选择突出显示将闪烁

一个证明问题的小例子:

import java.util.Random;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;

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

    @Override
    public void start(
        Stage primaryStage) throws Exception
    {
        final ObservableList<DummyData> list = FXCollections.observableArrayList();

        final TableView<DummyData> tableView = new TableView<>(list);
        tableView.getColumns().add(createColumn(item -> item.getColumn1()));
        tableView.getColumns().add(createColumn(item -> item.getColumn2()));
        tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        tableView.getSelectionModel().setCellSelectionEnabled(true);

        final Thread thread = new Thread(() -> 
        {
            while (true)
            {
                Platform.runLater(() -> list.add(new DummyData()));

                try
                {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e)
                {
                    //do nothing
                }
            }
        });
        thread.setDaemon(true);
        thread.start();

        final BorderPane root = new BorderPane();
        root.setCenter(tableView);
        primaryStage.setScene(new Scene(root, 500, 500));
        primaryStage.show();
    }

    private TableColumn<DummyData, String> createColumn(
        final Callback<DummyData, String> dataGetter)
    {
        final TableColumn<DummyData, String> column = new TableColumn<>();
        column.setCellValueFactory(cellData -> new ReadOnlyStringWrapper(dataGetter.call(cellData.getValue())));
        return column;
    }

    private static class DummyData
    {
        private final String mColumn1;
        private final String mColumn2;

        public DummyData()
        {
            final Random ramdom = new Random();
            mColumn1 = Integer.toString(ramdom.nextInt(1000));
            mColumn2 = Integer.toString(ramdom.nextInt(1000));
        }

        public String getColumn1()
        {
            return mColumn1;
        }

        public String getColumn2()
        {
            return mColumn2;
        }
    }

}

如果你运行并选择一个单元格,你会看到闪烁。

到目前为止,我的挖掘表明它与表格视图中的单元格回收有关:我更改了Cell Factory,为每个单元格对象分配并注销了唯一的ID和单元格项目,并发现ID&lt; - &gt;项目关系不是恒定的;每个单元格对象都会在tableview周围移动,每次更新数据模型时都会显示不同的数据。这意味着每次更新都会修改selected属性,从而导致pseudoClassState发生更改。我怀疑这是一个微妙的时间问题,当细胞被取出桌面视图和细胞的选定属性被更改时

有没有其他人看过这个问题,有没有人有任何解决方法?

1 个答案:

答案 0 :(得分:0)

对你来说可能有点晚了,但我遇到了类似的问题并设法通过将TableView包装在额外的AnchorPane中来解决它。