2

我正在使用以下代码:

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 正在使用DefaultTableCellHeaderRenderer来自package sun.swing.table;

我到处读到我不应该使用太阳包。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) {}

}

我明白了:

在此处输入图像描述

外观保留,列标题居中!!!(其他列标题也居中,但我可以通过对int row, int column参数进行进一步测试来控制它)。

4

2 回答 2

5

问题是您使用的单元格渲染器与 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(当然,在检查它之后),然后将你的文本居中或做其他事情。

于 2011-06-30T00:21:31.270 回答
2

也许您可以尝试以这种方式重构您的类:

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());

(我不确定。我做了类似的事情,但不是针对列标题,也没有扩展 DefaultTableCellRenderer)

于 2011-06-29T23:39:18.827 回答