出于某种原因,当我的TreeTableView填充了许多元素时,文件上设置的图标将随机变为完全透明。
向下滚动时,它们会刷新。
我已经检查了这个帖子:JavaFX TreeTableView rows gone when scrolling
我假设自从我开始
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
我在格式化后的2-3天前更新了这个版本,所以我看不到上面的版本已经过时2年了(因为我链接的另一个帖子是[从2013年开始])。< / p>
许多节点都埋没在未扩展的其他节点中,因此我很困惑为什么单击其中一个节点来展开它们会导致GUI缓慢地突然显示。当我单击其中一个节点时,会出现大约15个新元素。我没有一台旧电脑(2.8 Ghz 4核8演出公羊),除非这样的事情要征税吗?
这也发生在已经加载的节点上,因此向上和向下滚动会导致它们消失。
这是一个小例子,有时它可能变得荒谬(我在全屏幕上最多有一半的图像变成空白)。
这是一个错误吗?或者我做错了什么? TreeTableView是否设计用于处理这么多条目(约50k,但它们彼此嵌套,因此在任何给定时间只显示2000-3000个)?
我在处理100-500个条目时从未发生过这种情况,但是将使用此应用程序的人可能会处理可能会变得更大的数据(5000-10000个嵌套元素可能不同时显示所有内容。)
我能想到的唯一解决方法就是单独查看每个节点,从表中删除表中的每个其他节点,只显示当前节点,但这需要进行大量的重写,如果我想避免可能的。
编辑:作为一个注释,我为每个使用多个ImageView,所以它不像有人试图在图中使用一个Node的问题。
=============================================== ======================
更新了MCVE:
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
FXMLLoader fxmlloader = new FXMLLoader(Main.class.getResource("Test.fxml"));
AnchorPane root = fxmlloader.load();
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
控制器:
package application;
import javafx.fxml.FXML;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
public class Controller {
@FXML
public AnchorPane rootPane;
@FXML
public TreeTableView<String> ttv;
@FXML
public TreeTableColumn<String, String> ttc;
@FXML
public void initialize() {
Image img = new Image("http://i.imgur.com/TEgfhOw.png");
TreeItem<String> root = new TreeItem<>("Root item");
TreeItem<String> ti;
for (int a = 0; a < 50000; a++) {
ti = new TreeItem<>(Integer.toString(a));
ti.setGraphic(new ImageView(img));
root.getChildren().add(ti);
}
ttv.setRoot(root);
}
}
FXML文件:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="rootPane" prefHeight="400.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Controller">
<children>
<TreeTableView fx:id="ttv" prefHeight="300.0" prefWidth="300.0">
<columns>
<TreeTableColumn fx:id="ttc" prefWidth="195.0" text="C1" />
</columns>
</TreeTableView>
</children>
</AnchorPane>
当我最终拉下卷轴时(通常在向上和向下拖动它的3-4秒内)会发生这种情况:
此外,文件随机显示在向下拖动时立即向左翻录。 说明:
运行文件
展开根节点
向上和向下拖动滚动条,从上到下让它快速发生(至少对我而言)
答案 0 :(得分:3)
建议的替代方法
对于您的用例,我建议您不要在每个TreeItem上设置图形。而是在树单元格的单元格值工厂中设置图形。
在每个TreeItem上设置图形时,可以创建50K图形节点。在单元工厂中设置图形时,只为每个可见单元格创建一个图形节点(例如,样本的11个图形节点)。
示例代码
以下代码未显示您在问题中描述的行为,并且对我有效:
$moduleName = Mage::app()->getRequest()->getModuleName();
$controllerName = Mage::app()->getRequest()->getControllerName();
$actionName = Mage::app()->getRequest()->getActionName();
即使此答案中的代码可能适合您,我仍然建议您在JavaFX issue tracker中记录报告,要求开发人员查看您在问题中发布的原始代码的效果(如果有一些内部可以在平台代码中完成,以改善或记录其可扩展性与大量的树项图形集。)
答案 1 :(得分:0)
@jewelsea的建议只能使用一个图标,但是当需要多个图标时会引起问题。
Image pink = new Image (getClass ().getResourceAsStream ("Letter-A-pink-icon.png"));
Image blue = new Image (getClass ().getResourceAsStream ("Letter-A-blue-icon.png"));
TreeItem<String> root = new TreeItem<> ("0");
for (int i = 1; i <= 5000; i++)
{
TreeItem<String> ti = new TreeItem<> (Integer.toString (i));
root.getChildren ().add (ti);
}
ttc.setCellValueFactory (
param -> new ReadOnlyObjectWrapper<> (param.getValue ().getValue ()));
ttc.setCellFactory (
new Callback<TreeTableColumn<String, String>, TreeTableCell<String, String>> ()
{
@Override
public TreeTableCell<String, String>
call (TreeTableColumn<String, String> param)
{
return new TreeTableCell<String, String> ()
{
ImageView imageView;
@Override
protected void updateItem (String item, boolean empty)
{
super.updateItem (item, empty);
if (!empty && item != null)
{
if (imageView == null)
imageView = new ImageView ();
int val = Integer.parseInt (item);
imageView.setImage (val % 2 == 0 ? pink : blue);
setText (item);
setGraphic (imageView);
}
else
{
setText (null);
setGraphic (null);
}
}
};
}
});
ttv.setRoot (root);
}
Java正在重用TreeTableCells,这意味着ImageView每次都需要更新。