刷新JTable会删除标题

时间:2014-02-11 19:00:05

标签: java swing netbeans jtable

我有一个JTable,我通过a填充每个循环。当我单击“刷新”按钮时,我希望刷新表,然后在每个循环中运行并重新填充JTable,这非常有用,除非我刷新表格时它会使我的标题变灰。这是一切的代码。此外,我在使用HeaderRenderer时会抛出一个转换异常,因为我可以将它强制转换为DefaultTableCellModel,但我拥有该类的原因是让我的标题无论如何都可以使用。所以这里是我遇到问题的类的代码。

HeaderRenderer类:

    package privatelessontrackernetbeans;

    import java.awt.Component;
    import javax.swing.JLabel;
    import javax.swing.JTable;
    import javax.swing.table.DefaultTableCellRenderer;
    import javax.swing.table.TableCellRenderer;

    /**
     *
     * @author trashgod
     * @author Brent Coleman
     */
    public class HeaderRenderer implements TableCellRenderer {
        DefaultTableCellRenderer renderer;

        public HeaderRenderer(JTable table) {
            try {
                renderer = (DefaultTableCellRenderer) table.getTableHeader()
                        .getDefaultRenderer();
                renderer.setHorizontalAlignment(JLabel.CENTER);
            } catch (ClassCastException e) {
                System.out.println("Cannot be cast to DefaultTableCellRender. " +
                        "I still dont know why.");
            } catch (NullPointerException e) {
                System.out.println("Null Pointer because of the other exception.");
            }
        }

        /**
         *
         * @param col
         * @return 
         */
        @Override
        public Component getTableCellRendererComponent (
            JTable table, Object value, boolean isSelected, boolean hasFocus,
                    int row, int col) {

            try {
                return renderer.getTableCellRendererComponent(
                    table, value, isSelected, hasFocus, row, col);
            } catch (NullPointerException e) {
                return null;
            }
        }
    }

带有JTable的类(只是有问题的方法)

    private void postInitComponents() {
        //Table for students that need more lessons
        DefaultTableModel dtm = (DefaultTableModel) jTable1.getModel();
        dtm.getDataVector().removeAllElements();
        //Center the cells
        DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
        centerRenderer.setHorizontalAlignment(JLabel.CENTER);
        jTable1.setDefaultRenderer(Object.class, centerRenderer);
        //Center the Titles
        JTableHeader header = jTable1.getTableHeader();
        header.setDefaultRenderer(new HeaderRenderer(jTable1));
        studentsNeedToPay = checkStudentsLessons();
        for (Instructor key : studentsNeedToPay.keySet()) {
            ArrayList<Student> values = studentsNeedToPay.get(key);
            boolean listed = false;
            for (Student s : values) {
                //Instructor already listed
                if (listed) {
                    Object[] data = {null, s.getName(),
                            s.getLessonsRemaining()};
                    dtm.addRow(data);
                } else {//Instructor not listed
                    Object[] data = {key.getName(), s.getName(), 
                            s.getLessonsRemaining()};
                    dtm.addRow(data);
                    listed = true;
                }
            }
        }
    }

1 个答案:

答案 0 :(得分:4)

我认为您的标题问题是由您获得的类强制转换异常引起的。问题是表标题的渲染器无法在代码中作为DefaultTableCellRenderer生成,因为您在此处将新的HeaderRenderer对象设置为默认渲染器:

 JTableHeader header = jTable1.getTableHeader();
 header.setDefaultRenderer(new HeaderRenderer(jTable1));

由于此类不会从DefaultTableCellRenderer延伸,因此您将在此行获得类强制转换异常:

public HeaderRenderer(JTable table) {
    try {
        renderer = (DefaultTableCellRenderer) table.getTableHeader().getDefaultRenderer();
        ...        
    } catch (ClassCastException e) { ... }
}

在任何情况下,如果你的目标只是让heder的文本居中,你甚至不需要提供新的表格单元格渲染器。这应该足够了:

private void postInitComponents() {
    ...
    DefaultTableCellRenderer renderer = (DefaultTableCellRenderer) jTable1.getTableHeader().getDefaultRenderer();
    renderer.setHorizontalAlignment(SwingConstants.CENTER);
    ...
}

题外话

关于这个:

DefaultTableModel dtm = (DefaultTableModel) jTable1.getModel();
dtm.getDataVector().removeAllElements();

这样您就可以直接访问底层数据结构(实现为Vector),这是错误的。您可以通过将行的计数设置为0来实现相同的目标:

DefaultTableModel dtm = (DefaultTableModel) jTable1.getModel();
dtm.setRowCount(0);