2011-08-25 122 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); 
       } 
      } 
     }); 
    } 
    }); 
}