2012-08-12 4 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(); 
       } 

      } 

     }}); 

저는 정말로 여기에 무슨 일이 일어나고 있는지 확실히 알기 때문에 데이터베이스를 열거 나 검색하는 데 문제가 없습니다. vertexPainter#transform에서

답변

1

, 두지도는 null 또는이 (아마도 데이터베이스 테이블에 설정되지 않음) null의 정수 키 ("v") 또는 하나 개의 레코드에 대한 값 pSex 속성에 대한 값이 없습니다.

디버거가 실제 문제를 정확히 알려줍니다.


TCanvas 생성자에서, 나는이 코드 줄 참조 : 당신이지도 화가를 만드는 곳입니다

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

을,하지만 난 그지도의 선언과 초기화를 볼 수 없습니다. 따라서 빈 그림을 화가에게 전달하면 화가는 키 값을 찾을 수 없습니다 (지도가 비어 있기 때문에). 이것은 분명 NPE로 이어질 것입니다.


오류 로그를 연구하는 것이 아닙니다. 이클립스 : 디버그에

  1. 스위치가
  2. 가보기에 "중단"보기 (오른쪽 상단 모서리에 보통 탭)
  3. 을 찾을 perpsective

    는 "J"와 느낌표가있는 버튼이있다 마크는 도구 설명이
  4. 그 버튼 입력 NPE에
  5. 을 클릭 한 다음
  6. 지금 당신은 모든 널 포인터 예외
  7. 디버깅 입학 원서에 중단하는 중단 점을 가지고있는 경우 NullPointerException을 선택 "자바 예외 중단 점 추가"를 말한다 on ("Run"과 같이)
  8. 결국 응용 프로그램이 중단되고 디버그보기에 스택 추적이 표시됩니다. 하나의 프레임에 vertexPainter를 추가하고 해당 행을 선택하면 NPE를 던진 코드 행으로 이동합니다. 이제 변수 값을보고 inspect 함수로 재생해야합니다.
+0

문제가 없습니다. 그것은 응용 프로그램을 시작하고 아무것도에서 그래프를 그리면 잘 작동합니다. 그래서 내 이해에서 데이터베이스에서 꼭지점과 가장자리로드를 그리는 메커니즘은 동일해야합니다. –

+1

디버그. 희망 당신은 IDE를 사용 : NullPointerExceptions 중단하고 변수를 검사 중단 점을 설정합니다. 내가 지적한 것들 중 하나는'무효 '이다. –

+0

일식 인디애나 IDE를 사용하고 있습니다. 그리고 나는 당신이 무엇을하고 싶어하는지 이해하지 못합니다. NullPointerExceptions를 중지하려면 어떻게해야합니까? 죄송합니다 정말로 오류 로그를 사용하여 디버깅하는 방법을 모르겠다. –