java - 从数据库加载顶点和边时,顶点绘制器遇到错误

标签 java render jung vertex transformer-model

我正在构建简单的家谱应用程序并使用 Jung 来绘制图表。到目前为止,我可以使用 zentus 的 sqlitejdbc 绘制图表并将其保存到嵌入式数据库中。不过,我还没有创建清除 Canvas 的函数,所以我必须重新启动应用程序来测试打开数据库。但是当我想重新加载它们时,应用程序就卡住了,我遇到了这个错误。

  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 中,贴图要么为 null,要么没有整数键值(“v”)或一条记录的值 pSex 属性为 null(可能未在数据库表上设置)。

调试器可以准确地告诉您实际问题是什么。

<小时/>

TCanvas 构造函数中,我看到这行代码:

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

这是您使用 map 创建画家的地方,但我没有看到该 map 的声明和初始化。因此,很有可能您将空 map 传递给画家,因此画家无法找到键的值(因为 map 是空的)。这肯定会导致 NPE。

<小时/>

这不是研究错误日志。在 eclipse 中:

  1. 切换到调试视角
  2. 找到“断点” View (通常是右上角的选项卡)
  3. 在该 View 上有一个带有“J”和感叹号的按钮,工具提示显示“添加 Java 异常断点”
  4. 单击该按钮并输入 NPE,然后选择 NullPointerException
  5. 现在您有了一个断点,该断点将在每个空指针异常时停止
  6. 调试您的应用程序(例如“运行”)
  7. 最终应用程序将停止,您将在“调试” View 中看到堆栈跟踪。在你的 vertexPainter 的一帧中,选择该行,它将带你到引发 NPE 的代码行。现在您必须查看变​​量值并使用检查函数。

关于java - 从数据库加载顶点和边时,顶点绘制器遇到错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11922748/

相关文章:

php - 像素绘制算法

java - 什么是 jung2(java 图形框架)的 maven 存储库 url?

java - react 堆模式如何与线程一起工作

ruby-on-rails - 在 rails 中使用 MIME 类型渲染文件

java - 在 GAE 端点中传递数组

iphone - addSublayer 和 renderInContext 在 iOS 中如何工作

java - 图的自动布局 (JGraphX)

java - 在 JUNG 图中创建冗余重复节点

java - lambda groupingBy 对象返回复杂的 JSON

java - 从 jpanel 中删除特定组件