2011-08-25 68 views
4

如何在表模式更新(fireTableDataChanes)后保留表行选择?我知道我应该在选择之前保存选择,并在(从there)之后恢复。但是当我尝试在TableModelListener中恢复选择时,它不起作用。那么我应该在哪里恢复选择?TableModel更新后的JTable行选择

更新: 现在我尝试以这种方式恢复选择: table.setModel(model);

model.addTableModelListener(new TableModelListener() { 

     @Override 
     public void tableChanged(TableModelEvent e) { 
     table.addRowSelectionInterval(1, 1); 
     } 
    }); 

但它不起作用。

+0

向我们展示一些代码。你目前如何保存/恢复选择状态? –

+0

我的错。代码添加到问题中。 – Lampapos

+1

如果您不必触发dataChanged,那么首先请检查您的模型,如果您确实发生了内容更新和删除/添加的大量混合变化。如果不是,则触发一个或多个适当的更受限制的事件类型 - 表格将保持选择同步。或者相反:如果表格不能显示,任何自定义代码都不能显示;-) – kleopatra

回答

0

的决定很简单:我们应该使用Swing的EventQueue:

final int selectedRow = 0; 
// Save selected row table 
tableList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { 
    @Override 
    public void valueChanged(ListSelectionEvent e) { 
     selectedRow = e.getFirstIndex(); 
    } 
}); 

// Restore selected raw table 
model.addTableModelListener(new TableModelListener() {  
    @Override 
    public void tableChanged(TableModelEvent e) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       if (selectedRow >= 0) { 
          tableList.addRowSelectionInterval(index, index); 
       } 
      } 
     }); 
    } 
}); 
0

从第一个答案的例子显示了基本的解决方案,但将无法工作开箱。无法更改最终的“selectedRow”。所以应该使用可变整数(例如AtomicInteger)。 tamleModelListener调度到任务摆动,以便稍后调用 - 在大多数情况下,在表更改已经移除选择之后。所以在大多数情况下,selectedRow将是-1。

我已经改变了上面的例子有点(并添加单细胞的选择,但它也适用于全行):

final AtomicInteger selectedRow=new AtomicInteger(-1); 
    final AtomicInteger selectedCol=new AtomicInteger(-1); 
    tblZeiten.getSelectionModel().addListSelectionListener(new ListSelectionListener() { 
     @Override 
     public void valueChanged(ListSelectionEvent e) 
     { 
      selectedRow.set(tblZeiten.getSelectedRow()); 
      selectedCol.set(tblZeiten.getSelectedColumn()); 
     } 
    }); 
    tblZeiten.getModel().addTableModelListener(new TableModelListener() {  
     @Override 
     public void tableChanged(TableModelEvent e) 
     { 
      TableCellEditor editor=tblZeiten.getCellEditor(); 
      if (editor!=null) editor.cancelCellEditing(); 

      final int row=selectedRow.get(); 
      final int col=selectedCol.get(); 
      if (row<0||col<0) return; 

      SwingUtilities.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        // http://book.javanb.com/the-java-developers-almanac-1-4/egs/javax.swing.table/Sel.html 
        tblZeiten.changeSelection(row,col, false, false); 
       } 
      }); 
     } 
    }); 
2

这是第一个回答的更新版本。您可以使用字段来存储行,因为它可以由内部类访问。我对这个解决方案有些困难,因为我使用了一个周期性线程来更新表。

private int selectedRow = -1; 

public void mymethod() { 
//put code to create the table here... 
    JTable tableList = new JTable(); 


// Save selected row table 
    tableList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { 
     @Override 
     public void valueChanged(ListSelectionEvent e) { 
      selectedRow = e.getFirstIndex(); 
     } 
    }); 

// Restore selected raw table 
model.addTableModelListener(new TableModelListener() {  
    @Override 
    public void tableChanged(TableModelEvent e) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       if (selectedRow >= 0) { 
          tableList.addRowSelectionInterval(index, index); 
       } 
      } 
     }); 
    } 
    }); 
}