[英]Look-and-feel issue when centering JTable column header
我正在使用以下代码:
public final class TableCellRendererCenter extends DefaultTableCellRenderer {
public static final TableCellRenderer INSTANCE
= new TableCellRendererCenter();
protected TableCellRendererCenter() {
// Calling super
super();
this.setHorizontalAlignment(SwingConstants.CENTER);
}
}
在 JTable 列上:
TableColumnModel retrMod = ChartItemsTable.getColumnModel();
TableColumn retrCol = retrMod.getColumn(2);
retrCol.setHeaderRenderer(TableCellRendererCenter.INSTANCE);
retrCol.setCellRenderer(TableCellRendererCenter.INSTANCE);
并且外观不再与其他列标题匹配:
为什么? 我该如何解决这个问题?
编辑
似乎 NetBeans 正在使用来自package sun.swing.table;
的DefaultTableCellHeaderRenderer
;
我到处都读到我不应该使用太阳包。 Grrrr ......这没有帮助!
编辑 2
0verbose 的建议产生以下结果:
解决方案
根据 eugener 的建议,我将代码更新如下:
public final class TableCellRendererCenter extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
// returns component used for default header rendering
// makes it independent on current L&F
Component retr = table.getTableHeader().getDefaultRenderer().
getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
if ( JLabel.class.isAssignableFrom(retr.getClass()) ) {
JLabel jl = (JLabel) retr;
jl.setHorizontalAlignment(SwingConstants.CENTER);
}
return retr;
}
@Override
public void validate() {}
@Override
public void revalidate() {}
@Override
public void firePropertyChange(
String propertyName, boolean oldValue, boolean newValue) {}
@Override
public void firePropertyChange(
String propertyName, Object oldValue, Object newValue) {}
}
我明白了:
外观保留,header 列居中,!! (其他列标题也居中,但我可以通过对int row, int column
参数进行进一步测试来控制这一点)。
问题是您使用的单元格渲染器与 LAF 使用的单元格渲染器不同。 IMO 实现正确 LAF 的唯一方法是使用 LAF 本身已经提供的渲染器,例如:
public class TableHeaderRenderer extends JComponent implements TableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
// returns component used for default header rendering
// makes it independent on current L&F
return table.getTableHeader().getDefaultRenderer().
getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
// following methods are overriden for performance reasons
@Override
public void validate() {}
@Override
public void revalidate() {}
@Override
public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}
@Override
public void firePropertyChange(String propertyName, Object oldValue, Object newValue) {}
}
显然,一旦你有合适的渲染器,你可以将它转换为 JLabel(当然,在检查它之后),然后将你的文本居中或做其他事情。
也许您可以尝试以这种方式重构您的类:
public class TableCellRendererCenter extends JLabel implements TableCellRenderer{
public TableCellRendererCenter(JTable associatedTable){
this.table = associatedTable;
JTableHeader header = this.table.getTableHeader();
this.setHorizontalAlignment(SwingConstants.CENTER);
this.setForeground(header.getForeground());
this.setBackground(header.getBackground());
this.setFont(header.getFont());
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
return this;
}}
编辑:我现在检查了。 DefaultTableCellRenderer已经扩展了 JComponent。 所以可能只需要这些行:
this.setForeground(header.getForeground());
this.setBackground(header.getBackground());
this.setFont(header.getFont());
(我不确定。我做了类似的事情,但不是针对列 header 并且没有扩展 DefaultTableCellRenderer)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.