【问题标题】:How to change a cell in a jTable programmatically?如何以编程方式更改 jTable 中的单元格?
【发布时间】:2020-09-26 14:09:36
【问题描述】:

我目前正在编写一个应用程序,我在其中向用户展示 JTable 中的网站链接等内容。我已经正确设置了我的 JTable,以便在单击相关单元格时打开相应的网站。但是,我很难正确格式化单元格,以便用户知道他们实际上有可能单击单元格以立即打开网站。

因此,我想要实现的是让链接的颜色至少为蓝色,甚至最好还带有下划线。我搜索了关于 SO 的不同文章,但无法完全理解那里解释的东西如何协同工作 - 尽管我不完全确定这些东西是否会是我真正想要的。

我填表的方式如下:

String[][] rowData = new String[entries.size() + 1][entries.get(0).length + 1];


rowData[0] = columnNames;

int i = 1;

Iterator<String[]> iterator = entries.iterator();
while (iterator.hasNext()) {
    rowData[i] = iterator.next();
    i++;
}

tblEntries = new JTable(rowData, columnNames);

entries 在这种情况下是一个 ArrayList,它由数据库处理程序传递,并且 - 顾名思义 - 包含表的所有条目。在将 ArrayList 读入相应的 Array 后,我初始化表,如最后一行所示。现在所有链接实际上都存储在所有行 > 0 和第 4 列中。

我的第一个方法是这样做:

for (int j = 0; j < entries.size(); j++) {
    for (int j2 = 0; j2 < entries.get(0).length; j2++) {
        tblEntries.editCellAt(row, column, e);
    }
}

e 应该是一个事件,用于检查是否满足链接条件并相应地执行格式化。但是我现在真的不知道需要什么样的事件才能将它传递给函数。

我在different SO article 中看到的另一种方法是使用 prepareRenderer 方法来指定正确呈现内容的条件。但是显然,这似乎仅适用于自己的 JTable 实现,我想避免使用 tblEntries.prepareRenderer() 并应用新的 TableCellRendererDefaultTableCellRenderer 并没有给我需要根据上面提到的SO文章。

那么,解决这个问题的最好和最方便的方法是什么?提前感谢您的任何建议和帮助。


解决方案:

对于遇到类似问题的任何人,我会将我的解决方案放在这里。正如@camickr 所建议的那样,最好的解决方案是自定义DefaultTreeCellRenderer,但是在这种特定情况下的问题是它还会以链接格式呈现特定的表头(显然不包含任何链接)。因此,我进一步搜索并找到了this website,在那里我找到了一个工作代码,用于自定义应在何处应用渲染器。

最后我想出了这个代码:

String[][] rowData = new String[entries.size() + 1][entries.get(0).length + 1];


rowData[0] = columnNames;

int i = 1;

Iterator<String[]> iterator = entries.iterator();
while (iterator.hasNext()) {
    rowData[i] = iterator.next();
    i++;
}

tblEntries = new JTable(rowData, columnNames) {
    @Override
    public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
        Component c = super.prepareRenderer(renderer, row, column);

        if (row > 0 && column == 4) {
            c = super.prepareRenderer(new LinkRenderer(), row, column);
        }

        return c;
    }
};

有关 LinkRenderer 的参考,请参阅下面接受的答案。

【问题讨论】:

    标签: java swing formatting jtable tablecellrenderer


    【解决方案1】:

    我想要实现的是使链接的颜色至少为蓝色,最好还带有下划线。

    这由渲染器控制。 JTable 的默认渲染器是 JLabel。

    您可以轻松创建自定义渲染器以蓝色显示文本:

    DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
    renderer.setForeground( Color.BLUE );
    table.getColumnModel().getColumn(3).setCellRenderer( renderer );
    

    不幸的是,在文本下划线会更加困难。可以通过设置 Font 的属性来实现组件中的文本下划线,这对于 JLabel 来说很容易做到:

    JLabel label = new JLabel("Underlined label");
    Font font = label.getFont();
    Map<TextAttribute, Object> map = new HashMap<TextAttribute, Object>();
    map.put(TextAttribute.FONT, font);
    map.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
    font = Font.getFont(map);
    label.setFont(font);
    

    但是,您不能只为渲染器设置字体,因为在渲染每个单元格时,默认渲染器会将字体重置为表格使用的字体。

    所以如果你想实现一个自定义Font的自定义渲染器,你需要扩展DefaultTableCellRenderer并覆盖getTableCellRendererComponent(….)方法。代码可能类似于:

    class LinkRenderer extends DefaultTableCellRenderer
    {
        private Font underlineFont;
    
        public LinkRenderer()
        {
            super();
            setForeground( Color.BLUE );
    
            underlineFont = .getFont();
            Map<TextAttribute, Object> map = new HashMap<TextAttribute, Object>();
            map.put(TextAttribute.FONT, underlineFont);
            map.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
            underLinefont = Font.getFont(map);
        }
    
        @Override
        public Component getTableCellRendererComponent(
            JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
        {
            super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    
            setFont( underlineFont );
    
            return this;
        }
    }
    

    阅读 Renderers and Editors 上的 Swing 教程部分了解更多信息。

    所以另一种方法是不使用自定义渲染器,而是可以将 HTML 添加到表格模型中。 JLabel 可以显示简单的 HTML。

    所以你添加到模型中的文本会是这样的:

    String text = "<html><u><font color=blue>the link goes here</font></ul></html>";
    

    【讨论】:

    • 感谢您提供非常详细的解释。我很确定这应该可以帮助我解决我的问题,但不幸的是,我只能在几天内确认这一点,因为在接下来的几天里我将没有时间在项目上编写代码。但我会尽快告诉你结果如何!
    • 好的,我现在已经开始测试了。您的建议工作得很好,除了不能排除第一行的自定义渲染器(它显示表标题并且不包含任何链接)。但是我能够将自定义渲染器的解决方案实现为不同的概念,我将在原始帖子中将其链接为最终解决方案。非常感谢您的帮助!
    • @Samaranth *不可能排除第一行的自定义渲染器(显示表头 * - 表头不应该是数据的一部分。表头是JTable。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多