Java 为什么setTableHeader()方法抛出NullPointerException?

Java 为什么setTableHeader()方法抛出NullPointerException?,java,swing,nullpointerexception,jtable,jtableheader,Java,Swing,Nullpointerexception,Jtable,Jtableheader,我尝试将工具提示添加到我的JTable标题中。在本例中,我使用了TTHeader类,它扩展了JTableHeader Java类。一切看起来都很好,但当我尝试向JTable添加新的TTHeader头时,我得到了源未知的NullPointerException。我不知道为什么。TTHeader类似乎还可以。问题出在别的地方 下面是我的方法的代码。 对于JTable填充: private JPanel contentPane; private JScrollPane scrollPane; p

我尝试将工具提示添加到我的JTable标题中。在本例中,我使用了TTHeader类,它扩展了JTableHeader Java类。一切看起来都很好,但当我尝试向JTable添加新的TTHeader头时,我得到了源未知的NullPointerException。我不知道为什么。TTHeader类似乎还可以。问题出在别的地方

下面是我的方法的代码。 对于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);
                }
           }
      });
 }
第19行:

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

当您获得一个NPE并识别该行时,首先要检查的是所有出现的解引用运算符(
)。此类运算符左侧(!)的值将为
null
。(如果一行上有多个
s,那么其中一个就是。因此,如果您的行是
foo.getBar().doSomething()
,则
foo
null
foo.getBar()
返回
null
。但是
doSomething()
返回什么并不重要。)

在本例中,可能是返回
null
getTable()
方法

自Java5以来,出现了两个新的、更狡猾的方法 NPE的原因:

  • for(Foo-Foo:fooCollection)
    中的隐式解引用,如果
    fooCollection
    为空,则会得到一个NPE
  • 数字的自动取消装箱:
    整数i=null;int j=i+1//此处为NPE

  • 关于NPE的调试,您只需要知道这些。一般来说,还有更一般的建议,您应该记录变量值或使用调试器一步一步地执行代码。

    首先添加
    e.printStackTrace()
    进入你的
    catch
    块,获取
    异常
    详细信息,然后添加到你的帖子中,并向我们指出这一行。我几乎确信这不是你获得NPE的地方。你使用的是自定义LAF。当您使用默认(金属)LAF时会发生什么?当我从JComboBox中选择所需的数据库时,问题就会出现。应用程序在做出选择后抛出NPE。一开始,当我启动应用程序时,JTable被正确启动,工具提示也能正常工作。事实就是这样。我将JTable的初始化移到方法populateTable()中,每当用户选择所需的DB时,JTable从一开始就被初始化。但我不明白一件事——为什么我一开始就得到NPE?我对已经初始化的表使用了getTable(),所以它不应该出现…我们应该看更多的代码来给您一个精确的答案,但请记住Swing应用程序通常是多线程的,所以如果您不小心,一个线程的非空值很容易被另一个线程的空值所取代。这是最糟糕的例子,我对从JDBC填充的JTable有一个问题,不是吗
    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)
    
    int modelCol = getTable().convertColumnIndexToModel(col);