2012-12-27 94 views
-3

我是新的java,我有一個JTable,可以從txt文件中讀取記錄,並顯示他們完美。 我想給我的JFrame添加一本新書,當用戶在表上選擇一行並點擊「刪除」按鈕時,該行應該刪除,刪除的行記錄也必須從txt文件中刪除。 我的代碼是這樣的,但它有錯誤,沒有看到JTable! :刪除JTable行讀取文件記錄

public class CopyOfAllUserTable extends AbstractTableModel { 
Vector data; 
Vector column; 
public static void main(String[] args){ 
    new CopyOfAllUserTable(); 
} 
public CopyOfAllUserTable() { 

     String line; 
     data = new Vector(); 
     column = new Vector(); 
     try { 
     FileInputStream fis = new FileInputStream("D:\\AllUserRecords.txt"); 
     BufferedReader br = new BufferedReader(new InputStreamReader(fis)); 
     StringTokenizer st1 = new StringTokenizer(br.readLine(), " "); 
       while (st1.hasMoreTokens()) 
       column.addElement(st1.nextToken()); 
       while ((line = br.readLine()) != null) { 
         StringTokenizer st2 = new StringTokenizer(line, " "); 
         while (st2.hasMoreTokens()) 
           data.addElement(st2.nextToken()); 
       } 
       br.close(); 
     } catch (Exception e) { 
       e.printStackTrace(); 
     } 

    final JFrame frame1=new JFrame(); 
    JTable table=new JTable(data,column); 
    JButton button1=new JButton("Delete"); 


    button1.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      DefaultTableModel model=new DefaultTableModel(data, column); 
      JTable table=new JTable(model); 

     } 
    }); 


    JPanel panel=new JPanel(); 
    panel.add(table); 
    panel.add(button1); 
    frame1.add(panel); 
    frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame1.setBounds(200, 80, 600, 500); 
    frame1.setVisible(true); 
    frame1.setEnabled(true); 


} 

public int getRowCount() { 
     return data.size()/getColumnCount(); 
} 

public int getColumnCount() { 
     return column.size(); 
} 

public Object getValueAt(int rowIndex, int columnIndex) { 
     return (String) data.elementAt((rowIndex * getColumnCount()) 
         + columnIndex); 
} 

} 

我的問題是在刪除行,從文件中讀取記錄到JTable中是完全成功的。

+1

*「但它有錯誤」*什麼錯誤?複製/粘貼堆棧跟蹤。 –

回答

3

首先,您不是將JTable添加到幀的內容。

對於像容器:frame.getContentPane()JPanel,您應該使用#add(...)方法添加子組件。

例如:

final JPanel panel=new JPanel(new BorderLayout()); 
button1.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
     DefaultTableModel model=new DefaultTableModel(data, column); 
     JTable table=new JTable(model); 
     panel.add(new JScrollPane(table)); 
     panel.revalidate(); 
    } 
}); 

注意JPanel默認佈局是FlowLayout。第二件事 - 如果你想在你的JTable中有標題和滾動,你需要用JScrollPane來包裝它。 接下來 - 您應該在添加/刪除/ etc後重新驗證面板。

第二個問題是從JTable中刪除行。我通常寫的方法來處理它:

protected void removeRows(final int[] rows) { 
    int modelRows[] = new int[rows.length]; 
    for(int i = 0; i < rows.length; ++i) { 
     modelRows[i] = table.convertRowIndexToModel(rows[i]); 
    } 
    Arrays.sort(modelRows); 
    for(int i = modelRows.length - 1; i >= 0; --i) { 
     int row = modelRows[i]; 
     model.removeRow(row); 
    } 
    model.fireTableDataChanged(); 
} 

convertRowIndexToModel方法轉換索引通過JTable#getSelectedRows()JTable#getSelectedRow()(它們是可見的索引)返回到模型索引。如果設置RowSorterJTable,或者你把它留給標準執行:

table.setAutoCreateRowSorter(true); 
+0

您是否在removeRows方法中使用默認表模型?或者手動編寫此方法? – Sajad

+0

非常感謝,有一個問題,如果我們的桌子很小,是否需要使用jscroolpane? – Sajad

2

您直接追加表與使用JScrollPane出來的面板。如果你不喜歡這樣, 所以不是該你的表頭是不可見的,

JPanel panel=new JPanel(); 
    panel.add(table); 

做到這一點,

JPanel panel=new JPanel(); 
panel.add(new JScrollPane(table)); 

爲什麼使用JScrollPane?閱讀this

當用戶選擇一行並點擊刪除,然後獲取選定的行並將其從表列表中刪除。由於您正在使用AbstractTableModel,因此您必須編寫自定義的removeRow(..)方法來執行此操作。

例子:

private boolean removeSelectedRow(int row) { 
    // Remove the row from the list that the table is using. 
    dataList.remove(row); 
    // You need to call fireXXX method to refresh the table model. 
    fireTableDataChanged(); 
    return true; 
    // If fail return false; 
} 

如果刪除的是行動,那麼首先得到選定行,然後調用removeSelectedRow(INT)像下面,

private void deleteRow() { 
    int selectedRow = table.getSelectedRow(); 
    boolean deleteStatus = removeSelectedRow(selectedRow); 

    // Only if the deletion is success then delete from the file. 
    if(deleteStatus) { 
    // Delete it from the file too. 
    } 
} 
0

首先,你必須確保選擇了某些東西:選擇了某些東西而不是啓用刪除按鈕。請查找JTable的Java源代碼@

http://developer.classpath.org/doc/javax/swing/JTable-source.html

和下面的代碼:

1331: /**
1332: * Receives notification when the row selection changes and fires
1333: * appropriate property change events.
1334: *
1335: * @param event the list selection event
1336: */
1337: public void valueChanged(ListSelectionEvent event)
1338: {
1339: firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
1340: Boolean.FALSE, Boolean.TRUE);
1341: int r = getSelectedRow();
1342: int c = getSelectedColumn();
1343: if (r != lastSelectedRow || c != lastSelectedColumn)
1344: {
1345: Accessible o = getAccessibleAt(lastSelectedRow,lastSelectedColumn);
1347: Accessible n = getAccessibleAt(r, c);
1348: firePropertyChange(AccessibleContext.ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY, o, n);
1350: lastSelectedRow = r;
1351: lastSelectedColumn = c;
1352: }
1353: }

您需要爲最後的註冊事件時通知所選行已被更改。添加您自己的偵聽器,根據是否選擇了一行來啓用刪除按鈕,這與您在事件本身中看到的情況相同。

請使用從DefaultTableModel開始,因爲它可以在90%的情況下工作。

任何更改將應用​​於tabledatamodel,它將自動傳播到JTable視圖:通常,您永遠不會更改視圖,因爲所有選擇和滾動信息都會丟失,這是您不想要的。

當刪除按鈕被觸發時,方法很簡單:有一行被選中,否則無法點擊它:從defaultTableModel中刪除選定的行號,最後但並非最不重要的,我會寫整個數據模型模型的內容添加到指定文件,因爲表模型包含實際顯示在視圖中的實際行。

所以請考慮模型模型和模型:視圖只實例化一次,包裝滾動等等,並且你保持原樣。模型通常也不會更改:您可以通過添加和/或刪除行來更改模型的內容。另一個提示是:總是使用渲染器:根據我的愚見,這些渲染器並不理解如何使用JTables。

是的,您可以省略第一部分來聽取選擇更改:確定並彈出警告以指示問題。並且在稍後階段添加偵聽選擇更改以啓用和禁用JButton刪除行的功能。

希望這會有所幫助。

+0

我不明白ValueChanged()方法... – Sajad