即使我阅读并测试了@kleopatra 的答案
How do I correctly use customer renderers to paint specific cells in a JTable?
关于
super.getTableCellRendererComponent(...)
必须是返回前的最后一行代码,我无法根据这些建议编写正确的渲染器,对我来说只能这样工作JLabel
是为 Borders、HorizontalAlignment 和 Foreground 添加的,尤其是 Background 使用 Component 而不是JLabel
给我带来了一些无意义,(这里不重要)
来自 SSCCE
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
public class SelectedTableHeader {
private JFrame frame = new JFrame("Table Demo");
private JTableHeader header;
private Object selectedColumn = null;
private String[] columnNames = {"String", "Integer", "Float", "Double", "Locale & Double", "Boolean"};
private Object[][] data = {
{"aaa", new Integer(12), new Float(12.15), new Double(100.05), new Double(12.05), true},
{"bbb", new Integer(5), new Float(7.154), new Double(6.1555), new Double(417.55), false},
{"CCC", new Integer(92), new Float(0.1135), new Double(3.1455), new Double(11.05), true},
{"ddd", new Integer(12), new Float(31.15), new Double(10.05), new Double(23.05), true},
{"eee", new Integer(5), new Float(5.154), new Double(16.1555), new Double(17.55), false},
{"fff", new Integer(92), new Float(4.1135), new Double(31.1455), new Double(3.05), true}};
private TableModel model = new DefaultTableModel(data, columnNames) {
private static final long serialVersionUID = 1L;
@Override
public Class<?> getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
};
private JTable table = new JTable(model);
public SelectedTableHeader() {
header = table.getTableHeader();
header.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
JTableHeader h = (JTableHeader) e.getSource();
int i = h.columnAtPoint(e.getPoint());
Object o = h.getColumnModel().getColumn(i).getHeaderValue();
if (i < 0) {
selectedColumn = null;
return;
}
selectedColumn = o;
h.requestFocusInWindow();
}
});
final TableCellRenderer hr = table.getTableHeader().getDefaultRenderer();
header.setDefaultRenderer(new TableCellRenderer() {
private JLabel lbl;
@Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (selectedColumn == value) {
lbl = (JLabel) hr.getTableCellRendererComponent(table, value, true, true, row, column);
lbl.setBorder(BorderFactory.createCompoundBorder(lbl.getBorder(), BorderFactory.createLineBorder(Color.red, 1)));
lbl.setHorizontalAlignment(SwingConstants.LEFT);
} else {
lbl = (JLabel) hr.getTableCellRendererComponent(table, value, false, false, row, column);
lbl.setBorder(BorderFactory.createCompoundBorder(lbl.getBorder(), BorderFactory.createEmptyBorder(0, 5, 0, 0)));
lbl.setHorizontalAlignment(SwingConstants.CENTER);
}
if (column == 0) {
lbl.setForeground(Color.red);
} else {
lbl.setForeground(header.getForeground());
}
/*return (value == selectedColumn) ? hr.getTableCellRendererComponent(
table, value, true, true, row, column) : hr.getTableCellRendererComponent(
table, value, false, false, row, column);*/
return lbl;
}
});
table.setRowHeight(20);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scroll = new JScrollPane(table);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(scroll);
frame.pack();
frame.setLocation(150, 150);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
SelectedTableHeader selectedTableHeader = new SelectedTableHeader();
}
});
}
}
最佳答案
根据我的经验,当您覆盖任何 JTable
Renderer
时,最好获取 DefaultTableCellHeaderRenderer
。因此,不是直接从 Renderer
中弄乱 JLabel
,而是使用 super()
获取 Renderer
。因此,您的代码应如下所示:
header.setDefaultRenderer(new DefaultTableCellHeaderRenderer() {
@Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
DefaultTableCellHeaderRenderer rendererComponent = (DefaultTableCellHeaderRenderer)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (selectedColumn == value) {
rendererComponent.setBorder(BorderFactory.createCompoundBorder(rendererComponent.getBorder(), BorderFactory.createLineBorder(Color.red, 1)));
rendererComponent.setHorizontalAlignment(SwingConstants.LEFT);
} else {
rendererComponent.setBorder(BorderFactory.createCompoundBorder(rendererComponent.getBorder(), BorderFactory.createEmptyBorder(0, 5, 0, 0)));
rendererComponent.setHorizontalAlignment(SwingConstants.CENTER);
}
if (column == 0) {
rendererComponent.setForeground(Color.red);
} else {
rendererComponent.setForeground(header.getForeground());
}
return rendererComponent;
}
});
尝试直接回答您的问题:
问题 1:
问:如何正确使用客户渲染器绘制 JTable 中的特定单元格?
A:您当前的代码是在 JTableHeader
上设置一个 Renderer
。要在您的表格单元格上添加渲染器,代码与上面类似,只是您通过 Column 模型设置它:
table.getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
// Set your code to render your component.
return renderer;
}
});
请注意:JTables
是基于列的,这意味着特定列中的所有数据必须是同一类型(您的 SSCCE 遵循此约定)。我最喜欢做的事情是为每种类型提供自定义 Renderer
。例如,每当我有一个 Date
列时,我都会使用这个渲染器:
import java.awt.Component;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import org.joda.time.LocalDate;
/**
*
* @author Ryan
*/
public class DateCellRenderer extends DefaultTableCellRenderer {
String pattern;
public DateCellRenderer(String pattern){
this.pattern = pattern;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (value != null && value instanceof LocalDate) {
renderer.setText(((LocalDate)value).toString(pattern));
} else
throw new IllegalArgumentException("Only supported Object type is LocalDate.");
return renderer;
}
}
我用类似的东西调用这段代码:
table.getColumn("Date Entered").setCellRenderer(new DateCellRenderer("MMM dd, yyyy"));
问题 2:
问:特定一个表头颜色java swing
A:嗯..你的 SSCCE 似乎已经弄清楚了。
问题 3:
问:关于 super.getTableCellRendererComponent(...) 必须是返回前的最后一行代码,我无法根据这些建议编写正确的渲染器,对我来说只能这样工作
答:我不确定你的意思是“必须是返回前的最后一行代码”。事实并非如此,我上面给出的代码片段证明了这一点
问题 4:
问:为 Borders、HorizontalAlignment 和 Foreground 添加了 JLabel,尤其是 Background 使用 Component 而不是 JLabel 给我带来了一些无意义,(这里不重要)
答:好的... DefaultTableCellHeaderRenderer
足以满足所有这些,边框、对齐、前景和背景。
关于java - 如何使用 TableHeader 渲染器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9851253/