JTable 单元格中的图像相差一个像素?

发布于 2024-11-29 15:17:28 字数 2063 浏览 1 评论 0原文

因此,我现在可以将图像加载到 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;  
  }  
}  

So, I'm able to load images into my JTable's cells now, but for some reason the graphics are all shifted to the right by one pixel, allowing me to see the JTable's background. Any ideas? Sorry if my formatting's off; still not entirely used to this markup.

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;  
  }  
}  

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

那片花海 2024-12-06 15:17:28

不完全确定“关闭一个像素”是什么意思 - 但要在没有任何视觉伪影的情况下实现零单元格间距,您必须将边距归零并关闭网格线:

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

编辑

好吧,仔细观察,有您的代码有几个问题,

  • 您间接而不是直接调整列大小(还有另一个很好的例子,为什么永远不要执行组件。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;
    }
}

Not entirely sure what you mean by "one pixel off" - but achieve zero intercell spacing without any visual artefacts you have to both zero the margins and turn off the grid lines:

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

Edit

Okay, looking closer, there are several issues with your code

  • you do the column sizing indirectly instead of directly (and yet another nice example why to never-ever do a component.setPreferredSize :-)
  • the renderer's border takes some size

to fix the first, configure each column's width, table layout will automagically configure its itself

    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);
    }

for the second, null the border in each call:

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;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文