【问题标题】:setCellRenderer() not workingsetCellRenderer() 不工作
【发布时间】:2013-11-05 14:55:51
【问题描述】:

我正在尝试为特定列设置渲染器,但不知何故,此渲染器并未用于渲染该列。有什么解释吗?

tabledata = new LendDataTable();
table.setModel(tabledata);
TableColumn xx = table.getColumnModel().getColumn(3);
xx.setCellRenderer(new BookBackRenderer());//here it doesn't (there are 7 rows in total)
table.setDefaultRenderer(Integer.class, new BookBackRenderer());// here it works
add(table, BorderLayout.CENTER);



public  class BookBackRenderer extends DefaultTableCellRenderer {

/**
 * 
 */
private static final long serialVersionUID = 1L;

public BookBackRenderer() {
    // TODO Auto-generated constructor stub

}

@Override
public Component getTableCellRendererComponent(JTable table, Object value,
        boolean isSelected, boolean hasFocus, int row, int column) {


    System.out.println(column);
    return super.getTableCellRendererComponent(table, value.toString() + "xy", isSelected, hasFocus, row, column);
}

}

问题似乎与 TableModel 相关。一旦我使用 DefaultTableModel,它就可以完美运行。我的表格模型的代码:

/**
 * 
 */
package client.gui;

import java.awt.Component;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.EventObject;
import java.util.LinkedList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.event.CellEditorListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
import javax.swing.text.DateFormatter;

import org.json.JSONArray;

import lbvs.Leiheintrag;

/**
 * @author John
 *
 */
public class LendDataTable extends AbstractTableModel  implements
TableModel{
    private List<Leiheintrag> lendlist;

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    /**
     * 
     */
    public LendDataTable() {
        // TODO Auto-generated constructor stub
        lendlist = new LinkedList<Leiheintrag> ();
    }
    public void setData (List<Leiheintrag> list)
    {
        lendlist = list;
        this.fireTableStructureChanged();
        this.fireTableDataChanged();



    }

    /* (non-Javadoc)
     * @see javax.swing.table.TableModel#getRowCount()
     */
    @Override
    public int getRowCount() {
        // TODO Auto-generated method stub
        return lendlist.size();
    }

    /* (non-Javadoc)
     * @see javax.swing.table.TableModel#getColumnCount()
     */
    @Override
    public int getColumnCount() {
        // TODO Auto-generated method stub
        return 7;
    }

    /* (non-Javadoc)
     * @see javax.swing.table.TableModel#getValueAt(int, int)
     */
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        // TODO Auto-generated method stub
        Leiheintrag eintr = lendlist.get(rowIndex);
        switch (columnIndex){
        case 0:
            return eintr.getBuch();
        case 1:
            return eintr.getLeihdatum();
        case 2:
            return eintr.getAbgabe_bis();
        case 3:
            return ((Long)eintr.getRueck_datum());
        case 4:
            return eintr.getBezahlt_am();
        case 5:
            return eintr.getKosten();
        case 6 :
            return eintr.getLast_edit_user();
         default:
            return null;


        }
    }
    public Class<?> getColumnClass(int columnIndex){
        switch (columnIndex){
        case 0:
            return Integer.class;
        case 1:
            return Long.class;
        case 2:
            return Long.class;
        case 3:
            return Long.class;
        case 4:
            return Long.class;
        case 5:
            return Float.class;
        case 6 :
            return Integer.class;
         default:
            return null;


        }
    }
}

感谢您的帮助

【问题讨论】:

  • 我很担心这需要调试;为了调试,我们需要完整的代码。将您的问题归结为一个可运行的小示例,如果这不能告诉您问题本身,它会给我们其他人一些工作。
  • 在您的LendDataTable 类中,您是否重写了getColumnClass 方法?这会默认返回Object.class,因此为Integer 设置渲染器将无济于事。
  • 是的,我做到了.. 但问题是渲染器应该用于特定的列,而不应该由值的类定义(因为在不同的列中是相同的).. .

标签: java swing jtable tablecellrenderer abstracttablemodel


【解决方案1】:

问题似乎与 TableModel 相关。一旦我使用 DefaultTableModel,它就可以完美运行

下面的方法似乎有问题。

public void setData (List<Leiheintrag> list)
{
    lendlist = list;
    this.fireTableStructureChanged();
    this.fireTableDataChanged();
}

当您调用fireTableStructureChange() 时,JTable 将重新创建 TableColumnModel(以及所有 TableColumns),这意味着您的渲染器将不再与 TableColumn 3 关联。

我认为你可以只使用fireTableDataChanged(),或者如果这不起作用,那么使用fireTableRowsInserted()

如果您愿意,可以查看DefaultTableModel 的源代码,了解setDataVector() 方法调用了什么,因为这两个模型的概念是相同的。

【讨论】:

    【解决方案2】:

    @camickr 所说的显然是true。但我认为有一件重要的事情要提。

    fireTableStructureChanged 的 JAVA DOC 明确指出:

    使用JTable.setModel(model) 调用或在接收到由fireTableStructureChanged 函数调用触发的event 时,如果设置了autoCreateColumnsFromModeltrueJTable 将丢弃任何表列它拥有并按照它们在模型中出现的顺序重新分配默认列。我认为将autoCreateColumnsFromModel 标志设置为false 而不是删除fireTableStructureChanged() 调用就足够了。要设置或取消设置此标志,请使用:

    JTable.setAutoCreateColumnsFromModel(boolean)
    

    【讨论】:

    • 是的,设置 autoCreateColumnFromModel(false) 会起作用(了解这个方法很重要),但真正的问题是因为 setData() 方法没有正确实现。解决问题比掩盖症状更好。
    • @camickr,我同意你的看法。 :)
    猜你喜欢
    • 2018-12-28
    • 2014-06-29
    • 2017-12-19
    • 1970-01-01
    • 2013-01-09
    • 2021-01-10
    • 1970-01-01
    • 2019-01-19
    • 1970-01-01
    相关资源
    最近更新 更多