Изображения в ячейках JTable на один пиксель?

Итак, теперь я могу загружать изображения в свои JTable-ячейки, но по какой-то причине графика сдвигается вправо на один пиксель, что позволяет мне видеть фон JTable. Есть идеи? Извините, если мое форматирование выключено; все еще не полностью используется для этой разметки.

public static void main(String[] args) {  

  final int rows = 16;  
  final int columns = 16;  
  final int dimTile = 32;

  JFrame frame = new JFrame("test");  
  JTable table = new JTable(rows, columns);  
  table.setIntercellSpacing(new Dimension(0, 0));  
  table.setShowGrid(false);
  table.setBackground(Color.cyan);  
  table.setTableHeader(null);  
  table.setRowHeight(dimTile);  
  table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);  
  table.setPreferredSize(new Dimension(rows * dimTile, columns * dimTile));  

  Tile tile = new Tile(0);  
  for(int i = 0; i < rows; i++) {  
     for(int j = 0; j < columns; j++) {  
        table.getColumnModel().getColumn(j).setCellRenderer(new MyRenderer());  
        table.setValueAy(tile, i, j);  
     }  
  }  

  JScrollPane scrollPane = new JScrollPane(table, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);  
scrollPane.setBorder(BorderFactory.createEmptyBorder());  

  frame.getContentPane().add(scrollPane);  
  frame.setSize(512, 512);  
  frame.setVisible(true);  
  int adjustedSizeX = frame.getInsets().left + frame.getInsets().right + 512;  
  int adjustedSizeY = frame.getInsets().top + frame.getInsets().bottom + 512;  
  frame.setSize(adjustedSizeX, adjustedSizeY);  
  frame.pack();  

  ...  
}  


public class MyRenderer extends DefaultTableCellRenderer {  
  @Override  
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {  
     super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);  

      Tile tile = (Tile) value;  
      setIcon(tile.getIcon());  
      return this;  
   }  
}  


public class Tile {  
  ImageIcon icon;  

  public Tile(int graphic) {  
     icon = new ImageIcon(PATH/TO/"...test.png");  
  }  

  public ImageIcon getIcon() {  
     return icon;  
  }  
}  

Ответ 1

Не совсем уверен, что вы подразумеваете под "одним пикселем" - но достигайте нулевого межсетевого интервала без каких-либо визуальных артефактов, вам нужно как обнулить поля, так и отключить линии сетки:

table.setIntercellSpacing(new Dimension(0, 0)); 
table.setShowGrid(false)

Edit

Хорошо, глядя ближе, есть несколько проблем с вашим кодом.

  • вы косвенно определяете размер столбца, а не прямо (и еще один приятный пример, почему никогда не делать компонент .setPreferredSize: -)
  • граница визуализации принимает некоторый размер

чтобы исправить первое, настроить каждую ширину столбца, макет таблицы будет автоматически конфигурировать его сам

    final int rows = 16;
    final int columns = 16;
    Tile tile = new Tile(0);
    int tileHeight = tile.getIcon().getIconHeight();
    int tileWidth = tile.getIcon().getIconWidth();

    JTable table = new JTable(rows, columns);
    // remove all margin
    table.setIntercellSpacing(new Dimension(0, 0));
    table.setShowGrid(false);
    table.setTableHeader(null);
    // set the rowHeight
    table.setRowHeight(tileHeight);
    // turn off auto-resize
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    // configure each column with renderer and prefWidth
    for (int j = 0; j < columns; j++) {
        TableColumn column = table.getColumnModel().getColumn(j);
        column.setCellRenderer(new MyRenderer());
        column.setPreferredWidth(tileWidth);
    }

для второго, нулевая граница в каждом вызове:

public static class MyRenderer extends DefaultTableCellRenderer {
    @Override
    public Component getTableCellRendererComponent(JTable table,
            Object value, boolean isSelected, boolean hasFocus, int row,
            int column) {
        super.getTableCellRendererComponent(table, value, isSelected,
                hasFocus, row, column);
        setBorder(null);
        Tile tile = (Tile) value;
        setIcon(tile.getIcon());
        return this;
    }
}