2017-10-12 162 views
0

我生成一个热图,使用Jtable并用数字填充,然后用颜色 enter image description here。我想显示圆圈或其他图形图像,而不是颜色,它们的大小相对应,如enter image description here。 我在R中找到了一个库来做它,geom_tile,但是找不到在Javs中做到这一点的任何方法。你们有什么想法或例子来说明如何去做?如何在java中绘制热图,显示圆圈而不是颜色

+0

https://stackoverflow.com/questions/4941372/how-to-insert-image-into-jtable-cell – assylias

回答

1

要绘制自定义表格单元格,您需要提供自己的TableCellRenderer实现。

您的自定义TableCellRenderer只能实现一个方法:getTableCellRendererComponent,它必须返回ComponentJComponent

然后,您的TableCellRenderer可以返回一个自定义的JComponent,它根据预先设置的单元格值绘制圆。

在下面有一个样本代码演示设置自定义HeatmapCellRenderer,其使用DotRenderer作为组分以使单个细胞:

public class TableHeatmap { 

    public static void main(String[] args) { 
     JFrame frame = new JFrame(); 
     // create a demo table 10 x 10 cells 
     JTable table = new JTable(10, 10); 
     frame.setContentPane(table); 

     // fill in some random data 
     for (int row = 0; row < 10; row++) { 
      for (int col = 0; col < 10; col++) { 
       table.setValueAt((int) (Math.random() * 10), row, col); 
      } 
     } 

     // set our custom TableCellRenderer 
     table.setDefaultRenderer(Object.class, new HeatmapCellRenderer()); 
     table.setRowHeight(30); 

     // show the window 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    private static class HeatmapCellRenderer implements TableCellRenderer { 

     private final DotRenderer renderer = new DotRenderer(); 

     @Override 
     public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
      if (value instanceof Integer) { 
       this.renderer.setValue((Integer) value); 
       return this.renderer; 
      } 
      return null; 
     } 
    } 

    private static class DotRenderer extends JComponent { 
     private int value; 

     public void setValue(int value) { 
      this.value = value; 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      g.setColor(Color.BLUE); 
      g.fillRect(0, 0, this.getWidth(), this.getHeight()); 
      g.setColor(Color.RED); 
      int centerX = this.getWidth()/2; 
      int centerY = this.getHeight()/2; 
      g.fillOval(centerX - this.value, centerY - this.value, this.value * 2, this.value * 2); 
     } 

    } 

} 

上述代码应生成类似于以下截图的表:

example screenshot

通过使用不仅仅是更复杂的对象的Integer为你的细胞,你可以实现更复杂的仁德RERS。例如,如果您有一个简单的数据类class MyData { int value1; int value2; }并将这些值插入表中,则可以实现一个渲染器,该渲染器根据单元格值设置依赖于value1的背景色和基于value2的点大小。将value3添加到该类将进一步允许根据这些值对点进行着色,并非常接近您的示例图像。