2015-06-21 107 views
0

我正在使用swing JTable,並且在重新繪製表格時遇到問題。我畫一個JTable與THR下面的代碼用Swing JTable重繪表問題

Object[] column = new Object[]{"Entity", "Attribute"}; 
Object[][] rowData = new Object[][]{{"E1", "A1"},{"E2", "A2"}}; 
TableCellRenderer cellRenderer = new TableCellRenderer(); 

JTable table = new JTable(new DefaultTableModel(rowData, column)); 

table.setCellSelectionEnabled(true); 

table.getColumnModel().getColumn(0).setCellRenderer(cellRenderer); 

下面是我的表格繪製代碼..

public class TableCellRenderer implements javax.swing.table.TableCellRenderer { 

//private JPanel panel; 
JTextField field; 
private JTable table; 

@Override 
public Component getTableCellRendererComponent(final JTable table, final Object value, 
     boolean isSelected, boolean hasFocus, final int row, final int column) { 

    this.table = table; 
    //JTextField field = null; 
    System.out.println("Rendere : Row : " + row + "Column : " + column); 
    final JPanel panel = new JPanel(); 
    panel.setLayout(new BorderLayout()); 

    JButton button = new JButton("?"); 
    button.setPreferredSize(new Dimension(20, panel.getHeight())); 
    button.addActionListener(new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent arg0) { 
      new SelectionDialog(panel, table, value, row, column); 

     } 
    }); 
    if(table.getValueAt(row, column) != null){ 
     field = new JTextField(table.getValueAt(row, column).toString()); 
    }else{ 
     field = new JTextField(table.getValueAt(row, column).toString()); 
    } 
    field.setPreferredSize(new Dimension(30, panel.getHeight())); 
    panel.add(field, BorderLayout.WEST); 
    panel.add(button, BorderLayout.EAST); 

    return panel; 

} 

這就是我如何更新在表中的單元格內容..

SelectionDialog.this.table.getModel().setValueAt("E7", 0, 0); 

我正在通過SelectionDialog更新表格模型數據,例如更改第0行,第0列到E7等數據。在更改表模型中的數據後,我嘗試了以下選項,但沒有一個選項刷新表格數據,但JTable模型中的數據已正確更新。如果我在飛行中添加一個新行,然後調用下面的方法,然後每一件事工作正常,但如果我在現有行的模型修改的數據則沒有下文中提到的解決方案的工作

//((DefaultTableModel)SelectionDialog.this.table.getModel()).addRow(new Object[]{"E3", "A3"}); 
      //((DefaultTableModel)SelectionDialog.this.table.getModel()).fireTableCellUpdated(SelectionDialog.this.row, SelectionDialog.this.column); 
      //((DefaultTableModel)SelectionDialog.this.table.getModel()).fireTableChanged(new TableModelEvent(SelectionDialog.this.table.getModel())); 
      //((DefaultTableModel)SelectionDialog.this.table.getModel()).fireTableStructureChanged(); 
      //SelectionDialog.this.table.repaint(); 
     // SelectionDialog.this.table.revalidate(); 

請提供任何關於這個問題的見解,我可能會忽略一些非常突出的事情。

編輯1:只需添加一個我想放置的筆記,但不知道我錯過了多少。表格一般不會更新,但是如果我從進行更改的單元格中調出,或者我改變了表格的大小,那麼它會立即將該特定單元格的內容更改爲新的選定值。

問題就迎刃而解了:

我把我的發現對誰正面臨着類似的問題的人。

我在表格中的每個單元格內呈現了一個按鈕和一個文本框。當點擊按鈕時(不提供編輯器代碼,因爲它看起來與我無關)將出現一個對話框,其中輸入來自用戶的值並更新特定的列和行。 我提到的行不工作在我的職位(編輯1之前)工作正常,但渲染器不執行,除非我手動從選定的單元格(其按鈕被點擊)集中或手動更改jtable的大小有意義的按鈕是內部編輯器和按鈕單擊顯示,細胞被編輯和場外渲染,將不執行,除非編輯完成,需要進行集中或回車鍵等 我應用了下面的代碼爲

table.editCellAt(-1, -1); 

它從已編輯的單元格中進行調整(使用按鈕進行編輯),因此渲染器將按預期執行和工作。

回答

2

當您使用的是DefaultTableModel並且想要更新某個值時,您需要使用DefaultTableModel#setValueAt方法。

調用此方法(當然在事件調度線程上)將更新您的模型並激發必要的事件。這些事件將導致您的JTable自行更新。

一些關於你的渲染補充說明:

  • 在渲染的每個調用創建新的組件是不是要走的路。對於大型桌子來說,這變得非常慢。在渲染器的構造函數中創建所有組件,並且只更新它們的狀態
  • 在渲染器中向表中添加JButton不起作用,除非您還有編輯器。該按鈕不可點擊,並且您附加的動作偵聽器將永遠不會被調用。有關更多信息,請參閱renderers and editors section in the JTable tutorial
  • 應該不需要在渲染器中調用getValueAt。該值作爲參數之一傳入
+0

感謝您通過。我做了一個我之前忘了添加的編輯。我用你提到的方式更新模型數據,我也有一個編輯器,但沒有放在這裏,因爲我可能似乎不相干。我面臨的問題是,除非我手動/顯式地通過鼠標焦點從編輯列中刪除或我更改表格大小,否則不會調用渲染器? – Kashif