2017-06-14 118 views
1

我正在開發基於Java的網頁抓取工具。我創建了一個JFrame(Java:Swing)。我的抓取工具正在成功運行。它正在訪問創建的鏈接。但我想在JTextArea中動態地添加爬行鏈接,但它不會。我不能這樣做。當我嘗試這個時,我的程序是freezen。但我可以設置訪問的網址到控制檯。使用Java Swing進行網頁抓取

我的GUI這樣的:

image

我的代碼行是這樣的:

Document html = null; 

    try { 
     html = Jsoup.connect(url).get(); 
     Elements links = html.select("a"); 

     for(Element link: links) { 
      String tmp = link.attr("abs:href"); 
      jTextArea2.append(tmp + "\n"); 

      if(!this.visitedUrl.contains(tmp)) { 
       this.foundedUrl.add(tmp); 
       System.out.println(tmp); 
      } 
     } 

     while(this.foundedUrl.size() > 0) { 
      String tmp = this.foundedUrl.get(this.foundedUrl.size() - 1); 
      this.foundedUrl.remove(this.foundedUrl.size() - 1); 
      if(!this.visitedUrl.contains(tmp)) { 
       this.linkTracker(tmp); 
      } 
     } 

我怎麼能在JTextArea中集訪問的URL動態?

+0

您是否從UI事件線程調用此代碼?大多數Swing控件支持僅從UI事件線程調用。 –

+0

歡迎來到堆棧溢出,請參加[導覽],並通過[幫助],這會引導你[問],這會稍後告訴你發佈一個有效的[mcve]來證明你的問題。因爲你的程序是不完整的,因此不可編譯,我們不希望你的整個應用程序,但一個簡單但完整的例子(而不是代碼片段),可以證明你的問題。例如,您可以對URL進行硬編碼,並有一個啓動該過程的'JTextArea'和'JButton'。我們知道你的圖形用戶界面凍結了,但你的問題太廣泛了,因爲它缺乏足夠的信息(即MCVE)需要回復... – Frakcool

+0

...因爲你可能沒有在EDT中初始化你的應用程序,或者你正在運行在美國東部時間,也許你想看看[Swing Worker](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html),這可以讓你處理長期任務單獨的線程和不阻止EDT(凍結您的GUI)。另請閱讀[併發中的Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) – Frakcool

回答

0

試試這個:

new Thread((Runnable)() -> 
{ 
    Document html = null; 

    try { 
    html = Jsoup.connect(url).get(); 
    Elements links = html.select("a"); 

    for(Element link: links) { 
     String tmp = link.attr("abs:href"); 
     EventQueue.invokeLater(() -> { 
      jTextArea2.append(tmp + "\n"); 
     }); 

     if(!this.visitedUrl.contains(tmp)) { 
      this.foundedUrl.add(tmp); 
      System.out.println(tmp); 
     } 
    } 

    while(this.foundedUrl.size() > 0) { 
     String tmp = this.foundedUrl.get(this.foundedUrl.size() - 1); 
     this.foundedUrl.remove(this.foundedUrl.size() - 1); 
     if(!this.visitedUrl.contains(tmp)) { 
      this.linkTracker(tmp); 
     } 
    } 
    }catch(Exception e){} 
}).start(); 

你GUI被凍結的原因是因爲你是阻塞GUI線程。因此,通過創建一個新的線程並從那裏運行,在不同的線程上啓動您的操作。 然後獲取更新調用EventQue 它會告訴GUI線程將文本添加到JTextArea