2012-08-12 63 views
0

在構建簡單家族樹應用程序並使用Jung繪製圖表時,會遇到錯誤。到目前爲止,我能夠使用zentus中的sqlitejdbc繪製圖表並將其保存到嵌入式數據庫中。我還沒有創建函數來清除畫布,所以我必須重新啓動應用程序來測試打開數據庫。但是當我想加載它們時,應用程序就會凍結,我遇到了這個錯誤。當從數據庫加載頂點和邊時,頂點畫家遇到錯誤

path:C:\Users\PaLi\Desktop\psm things\chart4.db 
    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException 
at FamTree.vertexPainter.transform(vertexPainter.java:20) 
at FamTree.vertexPainter.transform(vertexPainter.java:1) 
at edu.uci.ics.jung.visualization.renderers.BasicVertexRenderer.paintShapeForVertex(BasicVertexRenderer.java:98) 
at edu.uci.ics.jung.visualization.renderers.BasicVertexRenderer.paintIconForVertex(BasicVertexRenderer.java:74) 
at edu.uci.ics.jung.visualization.renderers.BasicVertexRenderer.paintVertex(BasicVertexRenderer.java:37) 
at edu.uci.ics.jung.visualization.renderers.BasicRenderer.renderVertex(BasicRenderer.java:70) 
at edu.uci.ics.jung.visualization.renderers.BasicRenderer.render(BasicRenderer.java:55) 
at edu.uci.ics.jung.visualization.BasicVisualizationServer.renderGraph(BasicVisualizationServer.java:367) 
at edu.uci.ics.jung.visualization.BasicVisualizationServer.paintComponent(BasicVisualizationServer.java:321) 
at javax.swing.JComponent.paint(JComponent.java:1054) 
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5221) 
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1482) 
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1413) 
at javax.swing.RepaintManager.paint(RepaintManager.java:1206) 
at javax.swing.JComponent._paintImmediately(JComponent.java:5169) 
at javax.swing.JComponent.paintImmediately(JComponent.java:4980) 
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:770) 
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:728) 
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:677) 
at javax.swing.RepaintManager.access$700(RepaintManager.java:59) 
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1621) 
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251) 
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:705) 
at java.awt.EventQueue.access$000(EventQueue.java:101) 
at java.awt.EventQueue$3.run(EventQueue.java:666) 
at java.awt.EventQueue$3.run(EventQueue.java:664) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
at java.awt.EventQueue.dispatchEvent(EventQueue.java:675) 
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211) 
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105) 
at java.awt.EventDispatchThread.run(EventDispatchThread.java:90) 

這是頂點畫家變壓器的代碼。如果沒有加載數據庫部分,它工作得很好。

package FamTree; 

import org.apache.commons.collections15.Transformer; 

import java.awt.*; 
import java.util.Map; 

class vertexPainter implements Transformer<Integer, Paint> 
{ 
private Map<Integer,Person> tempV; 

public vertexPainter(Map<Integer,Person> passV) 
{ 
    tempV = passV; 
} 
public Paint transform(Integer v) 
{ 

    if (tempV.get(v).getpSex().equalsIgnoreCase("male")) 
     return (Color.blue); 
    else 
    return (Color.red); 

} 
} 

這是圖的初始化和設置vv。

 public TCanvas(){ 

    graph = new SparseMultigraph<Integer,Number>(); 

    layout2 = new StaticLayout<Integer,Number>(graph,new Dimension(2000,2000)); 

    vv = new VisualizationViewer<Integer,Number>(layout2); 
    vv.setBackground(Color.white); 
    vv.setVertexToolTipTransformer(new ToStringLabeller<Integer>()); 
    vv.getRenderContext().setVertexFillPaintTransformer(new vertexPainter(vertex)); 
vv.getRenderer().getVertexLabelRenderer().setPosition(Renderer.VertexLabel.Position.S); 
    vv.getRenderContext().setVertexLabelTransformer(new vertexLabel(vertex)); 
    vv.getRenderContext().setEdgeDrawPaintTransformer(new edgePainter()); 

    Transformer<Number,String> stringer = new Transformer<Number,String>(){ 
     public String transform(Number e) { 
      return "Edge:"+e+ "-"+graph.getEndpoints(e).toString(); 
     } 
    }; 

    vv.getRenderContext().setEdgeLabelTransformer(stringer); 

    EdgeLabelRenderer edgeLabelRenderer= vv.getRenderContext().getEdgeLabelRenderer(); 
    edgeLabelRenderer.setRotateEdgeLabels(false); 



    gm = new DefaultModalGraphMouse<Integer, Number>(); 
    vv.setGraphMouse(gm); 
    gm.add(new PopupGraphMousePlugin()); 

    GraphZoomScrollPane scrollPane2 = new GraphZoomScrollPane(vv); 

    JPanel vvPanel = new JPanel(); 
    vvPanel.setLayout(new BorderLayout()); 
    vvPanel.add(scrollPane2); 

    addBottomControls(vvPanel); 

    Container content = getContentPane(); 
    content.add(vvPanel); 
    }//TCanvas() 

這是加載數據庫的部分。

 menu.add(new AbstractAction("Open") { 
     public void actionPerformed(ActionEvent e) { 

      JFileChooser open = new JFileChooser(); 
      final File file ; 

      int vat = open.showOpenDialog(rootPane); 

      if(vat==JFileChooser.APPROVE_OPTION){ 

       file = open.getSelectedFile(); 

       String fPath = file.getAbsolutePath(); 

       System.out.println("path:"+fPath); 
       try{ 

        Class.forName("org.sqlite.JDBC"); 
        Connection conn = DriverManager.getConnection("jdbc:sqlite:"+fPath); 

        Statement stat = conn.createStatement(); 

        ResultSet rs = stat.executeQuery("select * from Person;"); 
        while (rs.next()) { 


         Integer pid = rs.getInt("pID"); 
         String pname = rs.getString("pName"); 
         String psex = rs.getString("pSex"); 
         Integer fatherid = (Integer)rs.getInt("fatherID"); 
         Integer motherid = (Integer)rs.getInt("motherID"); 
         Integer spouseid = (Integer)rs.getInt("spouseID"); 

         Person personInfo = new Person(); 

         personInfo.setpID(pid); 
         personInfo.setpName(pname); 
         personInfo.setpSex(psex); 
         personInfo.setFatherID(fatherid); 
         personInfo.setMotherID(motherid); 
         personInfo.setSpouseID(spouseid); 

         vertex.put(pid,personInfo); 
         graph.addVertex(pid); 
         vv.repaint(); 

         ResultSet rs2 = stat.executeQuery("select * from Location;"); 
         while (rs2.next()) { 

          if(rs2.getInt("pID")==pid){ 

           Point2D.Double loc = new Point2D.Double(); 

           Double x = rs2.getDouble("pointX"); 
           Double y = rs2.getDouble("pointY"); 
           loc.setLocation(x, y); 

           layout2.setLocation(pid, vv.getRenderContext().getMultiLayerTransformer().inverseTransform(loc)); 
           vv.repaint(); 
          } 
         } 
         rs2.close(); 


        } 
        rs.close(); 

        ResultSet rs3 = stat.executeQuery("select * from Relation;"); 

        while (rs3.next()) { 

         Point2D.Double loc2 = new Point2D.Double(); 

         Number edgeid = (Number)rs3.getInt("edgeID"); 
         Integer v1 = rs3.getInt("vertex1"); 
         Integer v2 = rs3.getInt("vertex2"); 
         String type = rs3.getString("RelationType"); 

         Relation relation = new Relation(edgeid, v1, v2, type); 
         edge.put(edgeid, relation); 
         if(type.equalsIgnoreCase("DIRECTED")){ 
          graph.addEdge(edgeid, v1, v2, EdgeType.DIRECTED); 
         } 
         if(type.equalsIgnoreCase("UNDIRECTED")){ 
          graph.addEdge(edgeid, v1, v2, EdgeType.UNDIRECTED); 
         } 
         vv.repaint(); 


        } 
        rs3.close(); 

        conn.close(); 
        vv.repaint(); 

       } 
       catch (Exception ex) { 
        // TODO: handle exception 
        ex.printStackTrace(); 
       } 

      } 

     }}); 

我真的不知道這裏發生了什麼,因爲我很確定打開和檢索數據庫部分沒有問題。

回答

1

vertexPainter#transform,無論是地圖null或者它對於整數鍵(「v」)或值pSex屬性一個記錄中沒有值爲null(可能未設置數據庫表)。

一個調試器可以告訴你究竟是什麼實際問題。


TCanvas構造函數中,我看到這行代碼:

vv.getRenderContext().setVertexFillPaintTransformer(new vertexPainter(vertex)); 

這就是你創建一個帶有地圖的畫家,但我沒有看到地圖的聲明和初始化。所以很有可能你將一張空白的地圖傳遞給畫家,因此畫家找不到一個鍵值(因爲地圖是空的)。這將明確地導致NPE。


這不是關於研究錯誤日誌。在蝕:

  1. 切換到調試perpsective
  2. 找到關於該視圖中的「斷點」視圖(在右上角通常爲標籤)
  3. 有一個與一個「J」和驚歎號的按鈕標記,工具提示說「添加Java異常斷點」
  4. 點擊該按鈕並輸入NPE,然後選擇NullPointerException異常
  5. 現在你有一個斷點,將停止對每一個空指針異常
  6. 調試applicati (如「運行」)
  7. 最終,應用程序將暫停,您將在「調試」視圖中看到堆棧跟蹤。一個框架它vertexPainter,選擇該行,它會帶你到投擲NPE的代碼行。現在您必須查看變​​量值並使用檢查功能。
+0

我找不到問題。當我啓動應用程序並從空白處繪製圖形時,它工作正常。所以根據我的理解,從數據庫中繪製頂點和邊的負載的機制應該是相同的。 – 2012-08-12 14:11:12

+1

調試。希望你使用ide:設置一個斷點來停止NullPointerExceptions並檢查變量。我指出的其中一個是'null'。 – 2012-08-12 14:14:17

+0

我使用eclipse indigo ide。我不明白你想要我做什麼。我該如何停止NullPointerExceptions?對不起,我真的不知道如何使用錯誤日誌進行調試。 – 2012-08-12 14:20:50