2013-07-11 19 views
1

我已經在這個網站上閱讀過很多關於這個問題的問題,我找不到爲什麼它仍然無法正常工作。複選框無法被選中 - 它們是可編輯的! Java Swing

問題:

我由JTable被一個JScrollPane內顯示。該JTable構造如下:

table = new JTable(new DataTableModel()); 

正如你所看到的,我使用了一個名爲DataTableModel定製AbstractDataModel。現在,當我顯示此時,出現複選框,但無法將其選中。它們是可編輯的,如下所示。以下是DataTableModel類中的相關代碼:(請注意,我的複選框列是第一列,位於索引0處,並且我的數據在此列中的數據爲「null」)。對於一些

public class DataTableModel extends AbstractTableModel 
{ 
    private String[][] data; 
    private String[] header = 
    { "", "KB Name", "fpGUID" }; 

    public DataTableModel() throws SQLException 
    { 
     // ========= CONNECTS TO DB AND PULLS RESULTS ========== 

     // GETS RESULTS SET CALLED "rs" 

     // populate data array 
     int counter = 0; 
     while (rs.next()) 
     { 
      //data[counter][0] = "sfsdfsdfs "; 
      data[counter][1] = (String) rs.getObject(2); 
      data[counter][2] = (String) rs.getObject(4); 

      counter++; 
     } 
     // ===================================================== 

    } 

@Override 
public String getValueAt(int rowIndex, int columnIndex) 
{ 
    return data[rowIndex][columnIndex]; 
} 

public boolean isCellEditable(int row, int col) 
{ 
    return col == 0; 
} 

public Class getColumnClass(int column) 
{ 
    if (column == 0) 
    { 
     return Boolean.class; 
    } else 
    { 
     return String.class; 
    } 
} 

所以,看來我的getColumnClass()方法很好,所以有什麼問題?它可能是我的「數據」,我存儲表中的數據的東西。下面是數據數組:

+3

這看起來不正確的:'字符串getValueAt(...)'。這應該返回一個Object,而不是一個String,特別是如果columnIndex是0,它應該返回一個'Boolean'來與你的'getColumnClass'一致並且需要顯示一個可編輯的JCheckBox。 –

+0

哦,它應該返回一個Object?我試圖將數據數組的第0列設置爲false,但我得到一個錯誤,因爲我的數據數組是String類型的。我應該使數據類型,如果數據數組爲對象(我想我已經嘗試過,但得到一個錯誤..)。 –

+0

您需要查看[TableModel]的API(http://docs.oracle.com/javase/7/docs/api/javax/swing/table/TableModel.html)。 getValueAt(...)'方法的簽名是什麼?該API會告訴你。至於你的錯誤,好吧,你需要修正它們,但我100%肯定列0 *的數據必須是布爾型的。 –

回答

3

有許多的東西,跳出...

  • (如已經開始指出的)getValueAt似乎宣告錯誤。它應該返回Object。想一想吧。你的期望是,第一列將是boolean,所以你怎麼能從這種方法返回String ...這導致...
  • 你的data數組是一個String的數組......這裏,再次,期望是第一個值應該是boolean。現在,你可以真正保持這一點,但你需要將值從getValueAt方法爲setValueAt方法......這將導致轉化爲boolean,然後再返回...
  • 你沒有實現setValueAt,所以沒有辦法可以保存對單元格值的更改
  • 您還沒有實施getRowCount,這是必需的,getColumnCount,這是必需的,你應該實現getColumnName,因爲你實際上有一些。

enter image description here

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.sql.SQLException; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.table.AbstractTableModel; 

public class TestTableModel02 { 

    public static void main(String[] args) { 
     new TestTableModel02(); 
    } 

    public TestTableModel02() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new JScrollPane(new JTable(new DataTableModel()))); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class DataTableModel extends AbstractTableModel { 

     private Object[][] data; 
     private String[] header = {"", "KB Name", "fpGUID"}; 

     public DataTableModel() {//throws SQLException { 
      // ========= CONNECTS TO DB AND PULLS RESULTS ========== 

      // GETS RESULTS SET CALLED "rs" 

      // populate data array 
//   int counter = 0; 
//   while (rs.next()) { 
//    //data[counter][0] = "sfsdfsdfs "; 
//    data[counter][1] = (String) rs.getObject(2); 
//    data[counter][2] = (String) rs.getObject(4); 
// 
//    counter++; 
//   } 
      // ===================================================== 

      data = new Object[4][3]; 
      data[0] = new Object[]{false, "Help", "1234"}; 
      data[1] = new Object[]{false, "On fire", "5648"}; 
      data[2] = new Object[]{false, "Drowning", "9012"}; 
      data[3] = new Object[]{false, "Micky Mouse", "3456"}; 
     } 

     @Override 
     public Object getValueAt(int rowIndex, int columnIndex) { 
      return data[rowIndex][columnIndex]; 
     } 

     @Override 
     public boolean isCellEditable(int row, int col) { 
      return col == 0; 
     } 

     @Override 
     public Class getColumnClass(int column) { 
      if (column == 0) { 
       return Boolean.class; 
      } else { 
       return String.class; 
      } 
     } 

     @Override 
     public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 
      if (columnIndex == 0) { 
       if (aValue instanceof Boolean) { 
        data[rowIndex][columnIndex] = (Boolean)aValue; 
        fireTableCellUpdated(rowIndex, columnIndex); 
       } 
      } 
     } 

     @Override 
     public int getRowCount() { 
      return data.length; 
     } 

     @Override 
     public int getColumnCount() { 
      return header.length; 
     } 

     @Override 
     public String getColumnName(int column) { 
      return header[column]; 
     } 
    } 
} 

現在,有辦法,你可以得到整個「第一列必須是布爾」的問題,但坦率地說身邊,這是更少的代碼,做這樣。

我也強烈建議你看看SwingWorker並使用它加載所有的數據,否則你可能會發現當數據開始加載時,你的UI會停頓下來,這通常是寧願不愉快。

看看...

詳情

+0

'DataTableModel'類的'setValueAt()'方法內部不是程序員假設調用'fireTableCellUpdated(row,col);'? –

+0

@nIcEcOw單元格,行,你會得到相同的效果:P – MadProgrammer

+0

LOL :-),實際上,剛開始閱讀關於'JTable'現在一天,從未嘗試過。但是,在單擊一個「JCheckBox」作爲渲染器的同時,我們不是隻更改一個「單元格」,而是整個「Row」,儘管對於此示例爲+1 :-) –