Jtable动力固定柱问题

时间:2015-10-04 19:27:22

标签: java swing jtable

我创建了一个可以动态锁定和解锁列的类。 在我的程序中,我创建了两个具有相同tablemodel的表。 一个在滚动窗格的Jviewport中,另一个在RowHeaderView中。 问题是当您解锁所有锁定的列时 你想再次开始锁定,不起作用。没有错误,但它就像事件没有回答。

产生问题的步骤:

  1. 试用代码,
  2. 将所有列放在固定表中,
  3. 然后右键双击解锁,
  4. 然后再次开始锁定并解锁
  5. 执行此过程,您可以看到鼠标事件不再回答

    public class Prova extends JFrame{
    
    private JTable mainTable,fixedTable;
    private JScrollPane scrollPane;
    private JTableHeader mainTableHeader;
    private TableColumnModel originalColumnModel,mainColumnModel,fixedColumnModel;
    private TableColumn[] columns;
    private int ncols,counter;
    
    public Prova(){
    
        counter = 0;
        TableModel mainTableModel = new DefaultTableModel(5, 10);
        scrollPane = new JScrollPane();
        mainTable = new JTable(mainTableModel);
        mainColumnModel = mainTable.getColumnModel();
    
        fixedTable = new JTable();
        fixedTable.setAutoCreateColumnsFromModel(false);
        fixedTable.setModel(mainTable.getModel() );
    
        ncols = mainTableModel.getColumnCount();
        columns = new TableColumn[ncols];
        for (int i=0;i<ncols;i++){
            columns[i] = mainColumnModel.getColumn(i);
        }
    
        mainColumnModel = mainTable.getColumnModel();
        fixedColumnModel = fixedTable.getColumnModel();
        mainTableHeader = mainTable.getTableHeader();
    
        mainTableHeader.addMouseListener( new MouseAdapter(){
        @Override
            public void mouseClicked(MouseEvent me){
                if (SwingUtilities.isRightMouseButton(me)){
                    if (ncols - counter>1){
                        counter ++;
                        int col = mainTable.columnAtPoint(me.getPoint());
                        TableColumn column = mainColumnModel.getColumn(col);
                        mainColumnModel.removeColumn(column);
                        fixedTable.getColumnModel().addColumn(column);
                        scrollPane.setRowHeaderView(fixedTable);
                        scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, fixedTable.getTableHeader());
                    }
                }
            }
        });
    
        fixedTable.getTableHeader().addMouseListener(new MouseAdapter() {
        @Override
            public void mouseClicked(MouseEvent me){
                if (SwingUtilities.isRightMouseButton(me) && me.getClickCount()== 2 ){
    
                    while (mainColumnModel.getColumnCount() > 0){
                        mainColumnModel.removeColumn(mainColumnModel.getColumn(0));
                    }
    
                    while (fixedColumnModel.getColumnCount() > 0){
                        fixedColumnModel.removeColumn(fixedColumnModel.getColumn(0));
                    }
    
                    for(int i=0;i<ncols;i++){
                        mainColumnModel.addColumn(columns[i]);
                    }
    
                    scrollPane.setRowHeaderView(null); 
                }
    
            }
        });
    
        scrollPane.setViewportView(mainTable);
        add(scrollPane, BorderLayout.CENTER);
        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
    @Override
            public void run() {
        new Prova().setVisible(true);
            }
    });
    }
    }
    

1 个答案:

答案 0 :(得分:2)

发布SSCCE时的几点建议:

for (int i=0;i<ncols;i++){

不要害怕在代码中使用空格,以便在分离for语句的3个语句时使其更具可读性。

for (int i = 0; i < ncols; i++){

保持代码简单并与问题直接相关:

TableModel mainTableModel = new EmployeeTableModel(listEmployees);

您的问题是关于“移动列”,而不是关于表中的数据,因此不需要特殊的TableModel和Employee类。只需使用DefaultTableModel:

TableModel mainTableModel = new DefaultTableModel(5, 10);

您当前的代码将无法编译,因为您没有包含Employee类。通过使用JDK类,代码更小,更易于阅读。

  

问题是当您解锁所有锁定的列并且您想再次开始锁定时,无法正常工作

您的循环代码错误。我没有费心去弄清楚出了什么问题。相反,我使代码更简单:

//for(int i=0;i<(ncols-counter);i++){
while (mainColumnModel.getColumnCount() > 0)
{
    mainColumnModel.removeColumn(mainColumnModel.getColumn(0));
}

//for(int i=0;i<counter;i++){
while (fixedColumnModel.getColumnCount() > 0)
{
    fixedColumnModel.removeColumn(fixedColumnModel.getColumn(0));
}

另一个问题是您的固定表没有标题,因此您不知道列是什么。这可以通过使用:

来解决
scrollPane.setRowHeaderView(fixedTable);
scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, fixedTable.getTableHeader());

既然你有一个标题,你需要将MouseListener添加到标题中,而不是滚动窗格:

//scrollPane.addMouseListener(new MouseAdapter() {
fixedTable.getTableHeader().addMouseListener(new MouseAdapter() {

编辑:

你遇到了与我上面修复的问题类似的问题。当您可以使用组件本身时,不要继续使用变量来跟踪值。

if (ncols - counter>1){

你永远不会重置计数器的值,所以if条件第二次不会为真。

如上所述,只使用列模型中的值:

//if (ncols - counter>1){
if (mainColumnModel.getColumnCount() > 1) {

这只是解决问题的基本方法。在代码块中放置一个显示语句,以查看是否在遇到问题时执行。