【问题标题】:Reduce the size of a custom render component within JTable cell减小 JTable 单元中自定义渲染组件的大小
【发布时间】:2014-10-19 12:10:15
【问题描述】:

我有一个 JTable,其中最后一列显示了一个自定义单元格渲染器(一个 JButton)。是否可以减少其列中 JButton 的宽度,使其仅大到足以显示其文本?我宁愿不减少列本身的大小,除非那是唯一的解决方案。我尝试过但失败的方法是:

  • 设置空白边框
  • 设置首选尺寸
  • 添加边距

自定义渲染器的代码如下:

import java.awt.Component;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;

public class ButtonColumnRenderer extends JButton implements TableCellRenderer {

    public ButtonColumnRenderer(){
      //  this.setBorder(BorderFactory.createEmptyBorder(50, 50, 50, 50));
      //  this.setPreferredSize(new Dimension(10,10));
      //  this.setMargin(new Insets(20,20,20,20));
    }

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column){
        return this;
    }
}

自定义渲染组件可以使用如下:

    import javax.swing.*;
    import javax.swing.table.*;

    public static void main(String[] args){
        //setup data + column headers
        String[] columns = {"Text Column", "Button Column"};
        Object[][] data = new Object[3][2];
        for(int i = 0; i < 3; i++){
            Object[] rowOfData = {"text" + i, "button" + i};
            data[i] = rowOfData;
        }   

        //Setup table
        DefaultTableModel model = new DefaultTableModel(data, columns);
        JTable table = new JTable(model);
        TableColumn column =  table.getColumnModel().getColumn(table.getModel().getColumnCount() - 1);
        column.setCellRenderer(new ButtonColumnRenderer(table.getModel().getRowCount()));

        //Display table on frame
        JFrame frame = new JFrame();
        frame.add(table);
        frame.pack();
        frame.setVisible(true);
    }

更新:我已经设法使用与背景颜色相同的matteborder 来减小组件的大小,但是问题是边框没有“一刀切”(即组件仍然与它所在的表一起延伸)。任何为渲染组件设置恒定大小的帮助将不胜感激。

【问题讨论】:

  • 1) 另见AbstractButton.setMargin(Insets) 2) 为了尽快获得更好的帮助,请发布MCVE(最小、完整、可验证的示例)。
  • 您好 Andrew,不幸的是,设置边距对渲染组件的外观几乎没有影响(我已经更新了 SO 代码,以防我做错了什么)。抱歉,如果您认为代码有点冗长,我过去曾因提供的信息太少而被叫出来。
  • “对不起,如果您认为代码有点啰嗦” 不是,我从来没有写过类似的东西。它不是完整的、可验证的,也不是示例。阅读链接。
  • 啊,好吧,对不起,我对 SO 很陌生。所以你需要设置 JTable 的代码吗?
  • “所以你需要设置 JTable 的代码?” 这不是我需要的,重要的是。毕竟是你的问题。无论我对此有什么兴趣,都纯粹是学术上的。运行时问题的 MCVE 应该编译并运行(并显示问题)。所以它必须包括导入和main(String[])..

标签: java swing jtable jbutton tablecellrenderer


【解决方案1】:

IIUC,您的问题是按钮填满了列。由于您使用的调整大小模式为列提供更多空间,因此当调整表格大小时 - 您的按钮将获得更多空间来填充。

如果您使用容器(在本例中为JComponent),您可能会将问题视为“标准”布局问题,而不需要处理渲染器或表格:

public class ButtonColumnRenderer extends JComponent implements TableCellRenderer {

    private final JButton button;

    public ButtonColumnRenderer(){
        setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
        button = new JButton();
        add(Box.createHorizontalGlue());
        add(button);
        add(Box.createHorizontalGlue());
    }

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column){
        button.setText(String.valueOf(value));
        return this;
    }
}

我在这里的选择是使用BoxLayout。随意使用您最喜欢的物质。

【讨论】:

  • 对我有用的有点晚,不过可能对其他人有用!
【解决方案2】:

TableCellRenderer 的组件被重用,因此最定制的工作应该发生在getTableCellRenderComponent。 (对于其他读者:通常可以从DefaultTableCellRenderer, but that uses a JLabel. That has the advantage that a call tosuper.getTableCellRenderer 中派生出自己的 TableCellRenderer 设置用于选择和聚焦的视觉效果。)

public ButtonColumnRenderer(){
}

public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column){
  //  this.setBorder(BorderFactory.createEmptyBorder(50, 50, 50, 50));
  //  this.setPreferredSize(new Dimension(10,10));
  //  this.setMargin(new Insets(20,20,20,20));
    this.setBorder(BorderFactory.createMatteBorder(1, 50, 1, 50,
        isSelected ? Color.RED : Color.GRAY));
    this.setSize(new Dimension(120, 10));
    return this;
}

【讨论】:

  • 嗨乔普,感谢您的回复。在getTableCellRenderComponent 方法中为组件设置matteborder 确实会影响按钮的外观,但是由于“更新”中所述的原因,这并不令人满意。不幸的是,直接在getTableCellRenderComponent 方法中设置大小仍然没有什么效果,因为jbutton 只是扩展以填充单元格(我尝试了setSizesetPreferredSizesetMaximumSize)。我开始认为我可能只需要手动设置列宽。
猜你喜欢
  • 1970-01-01
  • 2020-09-27
  • 2019-02-27
  • 1970-01-01
  • 1970-01-01
  • 2011-11-08
  • 1970-01-01
  • 1970-01-01
  • 2013-12-16
相关资源
最近更新 更多