2013-07-11 20 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 :-) –