2013-09-24 114 views
0

我嘗試將工具提示添加到我的JTable標頭。在這種情況下,我使用擴展JTableHeader Java類的TTHeader類。一切似乎都很好,但是當我嘗試向我的JTable添加新的TTHeader頭時,我得到的是帶有未知源的NullPointerException。我不知道爲什麼。 TTHeader類似乎沒問題。問題在別的地方。爲什麼setTableHeader()方法拋出NullPointerException?

這是我的方法代碼。 對於JTable中填入:

private JPanel contentPane; 
private JScrollPane scrollPane; 
private JTable table; 
private String tooltipsSDB[] = {"SessionID", "UserID", "PatientID", "PluginID", "Date", "Time"}; 

Connection conn = null; 
ResultSet rs = null; 
PreparedStatement ps = null; 

Table() { 
     // Connection Component 
     conn = ConnectionJDBC.ConnectDB(); 

     setTitle("My sample table"); 
     setSize(new Dimension(400, 400)); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setLocationRelativeTo(null); 
     setVisible(true); 

     contentPane = new JPanel(); 
     contentPane.setLayout(new BorderLayout(0, 0)); 
     setContentPane(contentPane); 

     scrollPane = new JScrollPane(); 
     contentPane.add(scrollPane, BorderLayout.CENTER); 

     table = new JTable() { 
      public boolean isCellEditable(int row, int column) { 
       return false; 
      }; 
     }; 
     table.setAutoCreateRowSorter(true); 
     // Populate JTable with data from SQL DB 
     populateTable(); 
     scrollPane.setViewportView(table); 
} 

public void populateTable() { 
     String sql = "SELECT * FROM " + ExampleDatabase + " ORDER BY " + ExampleData + " DESC"; 
     try { 
      // Make Connection With DB 
      ps = conn.prepareStatement(sql); 
      rs = ps.executeQuery(); 
      ResultSetMetaData rsmetadata = rs.getMetaData(); 

      // Populate JTable 
      int columns = rsmetadata.getColumnCount(); 
      DefaultTableModel dtm = new DefaultTableModel(); 
      Vector columns_name = new Vector(); 
      Vector data_rows = new Vector(); 
      for (int i = 1; i <= columns; i++) { 
       columns_name.addElement(rsmetadata.getColumnName(i)); 
      } 
      dtm.setColumnIdentifiers(columns_name); 
      while (rs.next()) { 
       data_rows = new Vector(); 
       for (int j = 1; j <= columns; j++) { 
        data_rows.addElement(rs.getString(j)); 
       } 
       dtm.addRow(data_rows); 
      } 
      table.setModel(dtm); 

      // Create Header For JTable 
      TTHeader tth = new TTHeader(table.getColumnModel()); 
      tth.setToolTipStrings(tooltipsSDB); 
      table.setTableHeader(tth); // On This Line I Get NullPointerException With Uknown Source 

      table.repaint(); 
     } catch (SQLException e) { 
      JOptionPane.showMessageDialog(null, "Populate table error! \n" + e); 

     } 
} 

public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        new Table(); 
       } catch (Exception e) { 
        JOptionPane.showMessageDialog(null, e); 
       } 
      } 
     }); 
} 

而且TTHeader類:

String[] toolTips; 

public TTHeader(TableColumnModel model) { 
    super(model); 
} 

public String getToolTipText(MouseEvent e) { 
    int col = columnAtPoint(e.getPoint()); 
    int modelCol = getTable().convertColumnIndexToModel(col); 
    String retStr; 
    try { 
     retStr = toolTips[modelCol]; 
    } catch (NullPointerException ex) { 
     retStr = ""; 
    } catch (ArrayIndexOutOfBoundsException ex) { 
     retStr = ""; 
    } 
    if (retStr.length() < 1) { 
     retStr = super.getToolTipText(e); 
    } 
    return retStr; 
} 

public void setToolTipStrings(String[] toolTips) { 
    this.toolTips = toolTips; 
} 

當我選擇從JComboBox中第二個數據庫NPE出現。在JComboBox監聽器中,我調用populateTable()方法。這裏是一個更具體的堆棧跟蹤:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException 
at mypackage.TTHeader.getToolTipText(TTHeader.java:19) 
at javax.swing.ToolTipManager$insideTimerAction.actionPerformed(Unknown Source) 
at javax.swing.Timer.fireActionPerformed(Unknown Source) 
at javax.swing.Timer$DoPostEvent.run(Unknown Source) 
at java.awt.event.InvocationEvent.dispatch(Unknown Source) 
at java.awt.EventQueue.dispatchEventImpl(Unknown Source) 
at java.awt.EventQueue.access$200(Unknown Source) 
at java.awt.EventQueue$3.run(Unknown Source) 
at java.awt.EventQueue$3.run(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
at java.awt.EventQueue.dispatchEvent(Unknown Source) 
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) 
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) 
at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
at java.awt.EventDispatchThread.run(Unknown Source) 

系NR 19:

int modelCol = getTable().convertColumnIndexToModel(col); 
+0

首先將'e.printStackTrace()'添加到'catch'塊中以獲取'exception'的細節,然後添加到您的文章並指向該行。 – Smit

+0

我幾乎相信,這不是你得到NPE的地方。 –

+0

plz post stacktrace – exexzian

回答

1

當你得到一個NPE,並確定了行了,你檢查的第一件事是對其操作的所有出現(.) 。此操作員左側(!)的值爲null。 (如果你有一個在線多. s,則其中的一個。所以,如果您的線路是foo.getBar().doSomething(),要麼foonullfoo.getBar()回報null。但是doSomething()回報也無所謂。)

在這種情況下,將可能是getTable()方法返回null

由於Java 5出現了兩個新的,而更可能偷偷摸摸的原因 NPE的:

  1. for (Foo foo : fooCollection)隱解引用,在這裏你會得到一個NPE如果fooCollection爲null。
  2. 號的自動拆箱:Integer i = null; int j = i + 1; //NPE here

這就是所有你需要知道的關於一般的NPE的調試,有當然的更一般的建議,您應該登錄變量值或使用調試器一步一步地執行您的代碼。

+1

就是這樣。我將JTable的初始化移動到了方法populateTable(),並且每當用戶選擇所需的DB時,JTable就從初始化開始初始化。但我不明白一件事 - 爲什麼我在開始時會得到NPE?我使用getTable()作爲已經初始化的表,所以它不應該出現... – bluevoxel

+0

我們應該看到更多的代碼給你一個確切的答案,但要記住,Swing應用程序通常是多線程的,所以什麼是非如果你不小心,對於一個線程無效可以很容易地爲null。 – biziclop

+0

這是什麼存在的最糟糕的例子,我有一個從JDBC填充JTable的問題,不是嗎? – mKorbel

相關問題