如何以编程方式更改 jTable 中的单元格?
How to change a cell in a jTable programmatically?
我目前正在编写一个应用程序,其中我向用户展示 link 到 JTable 中的网站。我已经正确设置了我的 JTable,以便在单击相关单元格时打开相应的网站。但是,我很难正确格式化单元格,以便用户知道他们实际上可以单击单元格以立即打开网站。
因此我想要实现的是 link 的颜色至少是蓝色的,甚至更好的是还带有下划线。我搜索了关于 SO 的不同文章,但不太明白那里解释的东西是如何协同工作的——尽管我不完全确定这些东西是否就是我真正想要的。
我 table 的填写方式如下:
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,顾名思义,它包含 table 的所有条目。将 ArrayList 读入相应的数组后,我初始化 table,如最后一行所示。现在所有 links 实际上都存储在所有行 > 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
应该是一个事件,用于检查 link 的条件是否满足并相应地执行格式化。但是我现在真的不知道需要什么样的事件才能将它传递给函数。
我在 different SO article 中看到的另一种方法是使用 prepareRenderer 方法来指定正确呈现内容的条件。然而,显然这似乎只适用于我想避免的 JTable 的自己实现,因为 tblEntries.prepareRenderer()
并且应用新的 TableCellRenderer
或 DefaultTableCellRenderer
并没有给我这样的功能我需要根据上面提到的SO文章进行覆盖。
那么,解决这个问题最好最方便的方法是什么?在此先感谢您的任何建议和帮助。
解决方案:
对于遇到类似问题的任何人,我都会将我的解决方案放在这里。正如 @camickr the best solution is a custom DefaultTreeCellRenderer
the problem in this specific scenario however is that it will also render the specific table-header (which obviously doesn't contain any links) in the link format. Hence I searched a bit further and found 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 的参考,请参阅下面接受的答案。
what I want to achieve is to have the colour of the link being blue at least and even better also underlined.
这是由渲染器控制的。 JTable 的默认呈现器是 JLabel。
您可以轻松创建自定义呈现器以蓝色显示文本:
DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
renderer.setForeground( Color.BLUE );
table.getColumnModel().getColumn(3).setCellRenderer( renderer );
不幸的是,给文本加下划线会比较困难。组件中的下划线文本可以通过设置字体的 属性 来实现,这对于 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);
但是,您不能只为渲染器设置字体,因为当渲染每个单元格时,默认渲染器会将字体重置为 table 使用的字体。
所以如果你想用自定义字体实现自定义渲染器,你需要扩展 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 添加到 table 模型。 JLabel 可以显示简单的 HTML.
因此您添加到模型中的文本类似于:
String text = "<html><u><font color=blue>the link goes here</font></ul></html>";
我目前正在编写一个应用程序,其中我向用户展示 link 到 JTable 中的网站。我已经正确设置了我的 JTable,以便在单击相关单元格时打开相应的网站。但是,我很难正确格式化单元格,以便用户知道他们实际上可以单击单元格以立即打开网站。
因此我想要实现的是 link 的颜色至少是蓝色的,甚至更好的是还带有下划线。我搜索了关于 SO 的不同文章,但不太明白那里解释的东西是如何协同工作的——尽管我不完全确定这些东西是否就是我真正想要的。
我 table 的填写方式如下:
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,顾名思义,它包含 table 的所有条目。将 ArrayList 读入相应的数组后,我初始化 table,如最后一行所示。现在所有 links 实际上都存储在所有行 > 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
应该是一个事件,用于检查 link 的条件是否满足并相应地执行格式化。但是我现在真的不知道需要什么样的事件才能将它传递给函数。
我在 different SO article 中看到的另一种方法是使用 prepareRenderer 方法来指定正确呈现内容的条件。然而,显然这似乎只适用于我想避免的 JTable 的自己实现,因为 tblEntries.prepareRenderer()
并且应用新的 TableCellRenderer
或 DefaultTableCellRenderer
并没有给我这样的功能我需要根据上面提到的SO文章进行覆盖。
那么,解决这个问题最好最方便的方法是什么?在此先感谢您的任何建议和帮助。
解决方案:
对于遇到类似问题的任何人,我都会将我的解决方案放在这里。正如 @camickr the best solution is a custom DefaultTreeCellRenderer
the problem in this specific scenario however is that it will also render the specific table-header (which obviously doesn't contain any links) in the link format. Hence I searched a bit further and found 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 的参考,请参阅下面接受的答案。
what I want to achieve is to have the colour of the link being blue at least and even better also underlined.
这是由渲染器控制的。 JTable 的默认呈现器是 JLabel。
您可以轻松创建自定义呈现器以蓝色显示文本:
DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
renderer.setForeground( Color.BLUE );
table.getColumnModel().getColumn(3).setCellRenderer( renderer );
不幸的是,给文本加下划线会比较困难。组件中的下划线文本可以通过设置字体的 属性 来实现,这对于 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);
但是,您不能只为渲染器设置字体,因为当渲染每个单元格时,默认渲染器会将字体重置为 table 使用的字体。
所以如果你想用自定义字体实现自定义渲染器,你需要扩展 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 添加到 table 模型。 JLabel 可以显示简单的 HTML.
因此您添加到模型中的文本类似于:
String text = "<html><u><font color=blue>the link goes here</font></ul></html>";