2013-08-29 67 views
0

我開發了一款使用neo4j創建本體的軟件。建立本體之後,我開始將200萬行數據集映射到它,這需要大約20分鐘才能完成。因此,我希望添加一個顯示流程執行的JFrame。下面的代碼在開始時創建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(); 
     }   
     } 
    } 
+0

這個問題缺少兩個重要的事情,1)SSCCE,2)AWT/Swing的JComponents被指定爲可重複使用的,然後是否有任何重新安裝新的無論在運行時 – mKorbel

+0

你不需要setVisible(true)框架內的每一個組件。只是JFrame本身。 – Kayaman

+0

@mKorbel 1)我很抱歉,我知道它有點長,但我不知道問題出在哪裏,什麼是重要的,什麼不重要(我是初學者)。這就是爲什麼我粘貼了整個代碼。 2)我不明白答案 – QGA

回答

2

您說得對,您的問題與負責繪製組件的線程被您的操作阻止的問題有關。但是,解釋多線程編程的各個方面都不在一個答案的範圍內。

作爲一種變通方法你可以延遲計算。

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

這樣,你的計算仍然在相同的線程中運行,並阻止UI,但在稍後當初始幀內容被繪製時。

如果你想要做真正的後臺計算你必須學習關於多線程的一個或多個教程來了解所有併發症那就試試吧,然後回來,如果你有更具體的問題。

+0

我已經在你的函數中封裝了數據庫計算,它運行良好。非常感謝你 – QGA

+0

'SwingWorker'會很合適,因爲在'doYourHavyComputation'正在運行時不會停止整個UI ... – MadProgrammer

+0

SwingWorker仍然需要了解多線程問題,例如,如果事件處理程序訪問與後臺計算相同的數據。 – Holger

0

我已閱讀,這個問題可能是由於缺少一個線程是 圍繞代碼

將是一個合適的假設。 Swing是一個單線程環境,這意味着所有的UI交互和更新都需要在Event Dispatching Thread的上下文中進行。同樣在阻止此線程的操作或操作中,將阻止EDT處理(除其他之外)塗料請求。

雖然有一些可能的解決方案,最適合您的需求可能是SwingWorker

這可以讓你在後臺線程運行冗長的操作,但有許多通過它可以重新同步的方法來進行這些操作的回EDT。

退房Concurrency in 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方法。

見...

對於一些例子。

這將確保整個你處理你的計算,用戶界面保持響應,將更改

+0

'類TwoThread擴展Thread { \t \t \t 線T1 =新主題(){ 公共無效的run(){ \t \t \t \t \t \t } }; //我的第二個線程 '線程T2 =新的Thread(){'' 公共無效的run(){' \t \t \t '}'' };' \t \t \t '@覆蓋公共無效的run (){' \t \t \t't1.start();' \t \t \t't2.start();' \t \t \t'}' \t \t \t \t \t \t \t '\t}' \t \t \t \t \t \t '\t TT1 TwoThread =新TwoThread();' \t \t'TT1。start();' – QGA

+0

感謝您的幫助。我在之前的評論中附加了(我仍在學習如何使用博客:))我如何解決我的問題,同時調用兩個線程。我在第一個run()方法中輸入了jframe,在第二個中輸入了我的計算。對不起,我不允許給你+1我沒有足夠的聲望......你應得的:) – QGA

+0

別忘了。 Swing要求您僅在Event Dispatching Thread的上下文中更新UI。使用'Thread'需要你自己執行這個同步 – MadProgrammer

相關問題