Java Swing-更改表模型重置渲染器。为什么?

Java Swing-更改表模型重置渲染器。为什么?,java,swing,jtable,Java,Swing,Jtable,我的SSCCE: import java.awt.Dimension; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.Unsuppor

我的SSCCE:

import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

public class Renderer_Model_LookAndFeel extends JFrame {
    public Renderer_Model_LookAndFeel() {
        begin();
    }

    private void begin() {
        try {
            UIManager.setLookAndFeel(new NimbusLookAndFeel());
        } catch (UnsupportedLookAndFeelException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


        Object[][] data = new Object[4][4];
        Object[] title = new Object[] {"Name", "Gender", "Age", "Prof."};

        JTable table = new JTable(new DefaultTableModel(data, title));

        for (int i=0; i<4; i++) {
            for (int j=0; j<4; j++) {
                data[i][j] = "Tom"; 
            }
        }


        //SET RENDERER
        DefaultTableCellRenderer r = new DefaultTableCellRenderer();
        r.setHorizontalAlignment(SwingConstants.RIGHT);
        table.getColumnModel().getColumn(2).setCellRenderer(r);

        table.setModel(new DefaultTableModel(data, title));

        table.setPreferredScrollableViewportSize(new Dimension(500, 300));

        JScrollPane sp = new JScrollPane(table);
        sp.setBounds(0, 0, 600, 400);
        getContentPane().add(sp);
        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                Renderer_Model_LookAndFeel frame = new Renderer_Model_LookAndFeel();

            }

        });
    }
}
以及:

如果首先设置模型,然后更改列渲染器,则第三列将右对齐。但是,如果我先设置渲染器,然后更改模型,则渲染器将重置为
null
,然后遵守默认对齐方式

为什么?

在我的项目中,我们首先在方法A中建立UI部分,然后读取XML文件以填充方法B中的数据,以便用UI表示分离数据。因此,我按以下顺序进行:

  • 构造所有UI组件,包括表,用空数据向量填充它
  • 读取XML以获取数据
  • 重置表格数据

  • 所以问题就出现了。我切换顺序没有问题(尽管它将数据部分与UI混合),但我只想知道原因

    为什么要将新的DefaultTableModel设置两次?我猜是因为您覆盖了渲染器使用的给定模型,然后它变为null。在表格初始化时设置模型,以后再也不设置模型这实际上是
    setModel
    所做的创建默认表格模型并始终使用它,并使用
    model.addRow()将数据添加到模型中。新表格模型的设置会导致列模型的重新创建。您可以使用方法
    JTable.setAutoCreateColumnsFromModel(boolean)
    将其关闭,但在这种情况下,您需要自己安装列模型。
    JTabel#setModel
    调用
    tableChanged
    ,这反过来调用
    createDefaultColumnsFromModel
    ,这在一定程度上是,在创建所有新的
    TableColumn
    s-解决方案时,单元格呈现程序的变化是什么?不要针对列设置呈现程序,而是通过调用
    JTable#setDefaultRenderer
    ,传入
    TableModel#getColumnClass
    返回的列的
    类来针对列类型设置呈现程序。就我个人而言,我会避免
    setAutoCreateColumnsFromModel
    ,因为它会带来相当大的开销,如果它不同步,可能会导致很多问题,但这就是我
    table.setModel(new DefaultTableModel(data, title));
    
    DefaultTableCellRenderer r = new DefaultTableCellRenderer();
    r.setHorizontalAlignment(SwingConstants.RIGHT);
    table.getColumnModel().getColumn(2).setCellRenderer(r);