0

我开发了一个使用 neo4j 创建本体的软件。构建本体后,我开始将 200 万行的数据集映射到它,这大约需要 20 分钟才能完成。因此,我希望添加一个显示流程执行的 JFrame。下面的代码在开始时创建 JFrame,然后开始映射数据集。但是,我可以在执行期间看到 JFrame,但它的组件在映射完成后出现在 JFrame 内。我读过这个问题可能是由于缺少围绕代码的线程。谁能帮我解决这个问题??

void createGraphDataset(String [][] choices , final ArrayList<String[]> DatabaseFile, GraphDatabaseService BORO_DB){

        JFrame converterFrame = new JFrame();
        converterFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        converterFrame.setBounds(100, 100, 650, 288);

                    JPanel contentPane = new JPanel();
        contentPane.setLayout(null);
        contentPane.setVisible(true);
        converterFrame.getContentPane().add(contentPane);

        JPanel panelNeo1 = new JPanel();
        panelNeo1.setBounds(6, 6, 638, 254);
        panelNeo1.setVisible(true);
        contentPane.add(panelNeo1);
        panelNeo1.setLayout(null);

        JLabel labelNeo1 = new JLabel("CSV BORO Converter");
        labelNeo1.setBounds(16, 19, 260, 37);
        panelNeo1.add(labelNeo1);
        labelNeo1.setVisible(true);

        JPanel panelNeo2 = new JPanel();
        panelNeo2.setBounds(16, 60, 605, 167);
        panelNeo1.add(panelNeo2);
        panelNeo2.setLayout(null);
        panelNeo2.setVisible(true);

        /*
        JProgressBar progressBar = new JProgressBar();
        progressBar.setBounds(27, 89, 547, 20);
        panelNeo2.add(progressBar);
        panelNeo2.setVisible(true);
        */

        JLabel labelNeo2 = new JLabel(" Processing: Number of row");
        labelNeo2.setOpaque(true);
        labelNeo2.setBounds(28, 36, 184, 20);
        panelNeo2.add(labelNeo2);
        labelNeo2.setVisible(true);

        JLabel labelNeo3 = new JLabel("");
        labelNeo3.setBounds(212, 36, 76, 20);
        panelNeo2.add(labelNeo3);
        labelNeo3.setVisible(true);

        JLabel labelNeo4 = new JLabel();
        labelNeo4.setText(String.valueOf(DatabaseFile.size()));
        labelNeo4.setBounds(311, 36, 70, 20);
        panelNeo2.add(labelNeo4);
        labelNeo4.setVisible(true);

        JLabel labelNeo6 = new JLabel("of");
        labelNeo6.setBounds(288, 36, 23, 20);
        panelNeo2.add(labelNeo6);
        labelNeo6.setVisible(true);

        converterFrame.setVisible(true);



        TopNode= new Node [DatabaseFile.get(0).length];


        //Create TopNodes
        Transaction tx0 = BORO_DB.beginTx();
            try{

                for(int u =0; u<DatabaseFile.get(0).length;u++){

                        TopNode[u]=BORO_DB.createNode();
                        TopNode[u].setProperty("name", choices[u][0]);

                }

                tx0.success();

            }
            finally{

                tx0.finish();

            }

        //Create the database 
        for(int i =0; i<DatabaseFile.size();i++){

        Transaction tx2 = BORO_DB.beginTx();

            try
            {

                // Nodes for each row
                Node []graphNode= new Node [DatabaseFile.get(i).length];

                // Relationships for each row ingoing
                Relationship [] graphRelOn = new Relationship [DatabaseFile.get(i).length-1];

                // Relationships for each row outgoing
                Relationship [] graphRelOut = new Relationship [DatabaseFile.get(i).length-1];

                //Relationship to TopNode ingoing
                Relationship TopNodeRelIn[]=new Relationship [DatabaseFile.get(i).length];


                            //Creates Nodes for row and relationship to TopNode

                            for(int j=0; j<DatabaseFile.get(i).length;j++){

                                    //Stores Database values
                                    String []ValuesRow =DatabaseFile.get(i);

                                    //Creates nodes for 1 row
                                    graphNode[j] = BORO_DB.createNode();
                                    graphNode[j].setProperty("name", ValuesRow[j]);

                                    //From row to TopNode Relationship (enter)
                                    TopNodeRelIn[j]=graphNode[j].createRelationshipTo(TopNode[j], RelTypes.typeInstances);
                                    TopNodeRelIn[j].setProperty("relationship-type", "typeInstances");  
                            }

                            //Creates Relationships

                            for(int k=0; k<(DatabaseFile.get(i).length)-1;k++){


                                    //Between same elements of the same row (left to right)
                                    graphRelOn[k]=graphNode[k].createRelationshipTo(graphNode[k+1], RelTypes.relatesTo);
                                    graphRelOn[k].setProperty("relationship-type", "relatesTo");

                                    //Between same elements of the same row (right to left)
                                    graphRelOut[k]=graphNode[(DatabaseFile.get(i).length)-1].createRelationshipTo(graphNode[(DatabaseFile.get(i).length)-(2+k)], RelTypes.relatesTo);
                                    graphRelOut[k].setProperty("relationship-type", "relatesTo");


                            }

                    tx2.success();
                }
        finally
        {
        tx2.finish();
        }        
        }   
    }
4

2 回答 2

2

您是对的,您的问题与负责绘制组件的线程被您的操作阻塞的问题有关。但是,解释多线程编程的所有方面超出了单一答案的范围。

作为一种解决方法,您可以延迟计算。

// setup the GUI
frame.setVisible(true);
EventQueue.invokeLater(new Runnable() {
    public void run()
    {
      doYourHavyComputation();
    }
  });

这样,您的计算仍会在同一线程中运行并阻塞 UI,但稍后会在绘制初始帧内容时进行。

如果你想做真正的后台计算,你必须学习一个或多个关于多线程的教程来理解所有的复杂性,然后尝试它,如果你有更具体的问题再回来。

于 2013-08-29T10:30:09.957 回答
0

我已经读到问题可能是由于缺少围绕代码的线程

将是一个合适的假设。Swing 是一个单线程环境,这意味着对 UI 的所有交互和更新都需要在 Event Dispatching Thread 的上下文中进行。同样,阻塞该线程的动作或操作将阻止 EDT 处理(除其他外)绘制请求。

虽然有许多可能的解决方案,但最适合您需求的可能是SwingWorker.

这允许您在后台线程中运行冗长的操作,但有许多方法可以让您将这些操作的输出重新同步回 EDT。

查看Swing 中的并发以获取更多详细信息。

你如何使用它取决于你的需求......

例如,您可以简单地“发布”您正在处理的当前行......

public class Generator<Node , Integer> {

    protected void process(List<Integer> rows) {
        // Back in the EDT
        int lastRow = rows.get(rows.size() - 1); // Only interested in the last one...
        // Update the UI...
    }

    protected Node  doInBackground() throws Exception {
        Node topNode = new Node [DatabaseFile.get(0).length];
        /*...*/
        publish(rowNumber);
        /*...*/
        return topNode;
    }

    public void done() {
        // Back in the EDT
        try {
            Node topNode = get(); // Get the result of the calculation...
        } catch (Exception exp) {
            exp.printStackTrace();
        }
    }

}

或者您可以利用SwingWorker的属性更改支持并在内置setProgress方法中使用它。

看...

举一些例子。

这些将确保您在处理您的计算时,UI 仍然响应您的更改

于 2013-08-30T01:01:17.927 回答