Question

Im building simple family tree application and using Jung to draw the chart. So far I am able to draw and save the chart into embedded database using sqlitejdbc from zentus. I've yet create the function to clear the canvas though, so I have to restart the application to test the opening the database. But when I want to load them back, the application just froze and I encountered this error.

  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)

This is the vertex painter transformer's code. It works perfectly fine if its not loading the database part.

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);

}
}

This is the initialization of graph and setting up the 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()

This is the part to load the database.

     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();
                }

            }

        }});

I really dont know whats happening here as Im pretty sure the opening and retrieving database part have no problem.

Was it helpful?

Solution

In vertexPainter#transform, either the map is null or it has no value for the integer key ("v") or the value pSex property for one record is null (maybe not set on the database table).

A debugger could tell you exactly what's the actual problem.


In the TCanvas constructor, I see this line of code:

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

That's where you create the painter with a map, but I don't see a declaration and initialization of that map. So there's a good chance, that you pass an empty map to the painter and thus the painter can't find a value for a key (because the map is empty). This would definitly lead to an NPE.


It's not about studying the error log. In eclipse:

  1. switch to the debug perpsective
  2. find the "Breakpoints" view (usually a tab in the upper right corner)
  3. on that view there's a button with a "J" and an exclamation mark, the tool tip says "Add Java Exception Breakpoint"
  4. Click on that button and type NPE, then select the NullPointerException
  5. Now you have a breakpoint that will halt on every null pointer exception
  6. Debug your application (like "Run")
  7. Eventually the application will halt and you'll see a stacktrace in the Debug view. One frame it your vertexPainter, select that row and it'll take you to the line of code that threw the NPE. Now you have to look at the variable values and play with the inspect function.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top