0

我想向用户展示一个 10000 * 400 瓦片的热图。我程序中的当前状态是我有一个类是JComponent. 在这个JComponent,我有Image瓷砖的实例。如果我有一个 300 * 300 的矩阵,程序使用 800 到 1000 MB 的内存。这太多了。

我还能做什么或让某人控制可以显示如此大的热图?

今天我进行了测试JHeatChart,它创建了一个BufferedImage. 10000 * 400 矩阵的大小低于 400 MB,但该类需要超过 15 分钟才能创建它。这太长了。

有没有人有一些想法或知道可以处理数据的控件?

4

5 回答 5

2

您可以尝试缩放地图。因此,如果您放大得很远,请使用更大的图块,而不是将每个图块打印到屏幕上。还可以尝试将单个图块合并到一个对象,而不是为每个图块保留引用。

于 2011-08-10T12:37:28.127 回答
2

由于这将是一张地图,因此您无需为每个图块创建一个组件。其中许多可以重复使用。您要做的是在应用程序初始化期间,创建所有可能组件的映射,然后在每个图块上传递对该组件的引用。

这是一个例子。

public class HeatMap{

private static List<JComponent> tiles = new ArrayList<JComponent>();    
private List<JComponent> heatmap = new ArrayList<JComponent>();
private Random rand = new Random();

static{
    tiles.add(new JLabel("Cold"));
    tiles.add(new JLabel("Hot"));
    tiles.add(new JLabel("Warm"));
}

public HeatMap(){
    for(int i=0; i<10000; i++){
        for(int j=0; j<400; j++){
                heatmap.add(tiles.get(rand.nextInt(3)));            
        }
    }
}
}

在上述情况下,我们只需要创建 3 个图块,其余的都是对它们的引用。这种方法应该有助于减少您的内存使用量。

于 2011-08-10T13:18:07.600 回答
1

瓦片真的必须表示为图像还是彩色框就足够了?

如果一个彩色框就足够了,您可以只在您的paint(...)方法中绘制可见的图块。无需加载这些图像。

如果它必须是图像,我假设并非每个图块都是唯一的,因此您可以尝试一次加载所有需要的图像,而不是为每个图块加载图像,并让图块引用相应的图像。因此,如果您有 100 个不同的图像,而不是 4000000 个副本,您将有 100 个和 4000000 个非常小的参考。

于 2011-08-10T12:58:04.870 回答
1

显然,10000 * 400 的图块太多了,无法一次查看。相反,使用fly-weight 模式仅渲染在JScrollPane. JTable是一个例子。

于 2011-08-10T17:44:36.067 回答
1

无论如何呈现它,用户将永远无法同时感知 400 万个数据点。因此,您永远不应该拥有四百万个图形小部件。要么缩小显示,要么(放大时)一次只显示所有图块的一个子集。无论哪种方式,您都必须将名义上的 4,000,000 个映射到更少的图形小部件并重用您已有的那些。

正如其他答案所指定的那样,您还应该考虑使用最简单的小部件类型来完成这项工作。

于 2011-08-10T13:20:16.583 回答