2015-06-17 72 views
0

如何獲取一行文本的HTML源代碼(按行代表在渲染的文本中兩個換行符之間的任何文本,如可見)在一個正在呈現HTML頁面的JTextPane?如何獲取在JTextPane渲染HTML頁面中選擇的文本的HTML

我的目標是在編輯文本渲染的行時,爲一行同時編輯HTML。

代碼:

package test; 

import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import java.io.IOException; 
import java.net.URL; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.JScrollPane; 
import javax.swing.text.BadLocationException; 

public class TextPaneTester extends javax.swing.JFrame { 

    public TextPaneTester() { 
     initComponents(); 
     myInitComponents(); 
    } 

    @SuppressWarnings("unchecked") 
    // <editor-fold defaultstate="collapsed" desc="Generated Code">       
    private void initComponents() { 
     contentScrollPane = new javax.swing.JScrollPane(); 
     content = new javax.swing.JTextPane(); 

     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
     contentScrollPane.setViewportView(content); 

     javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
     getContentPane().setLayout(layout); 
     layout.setHorizontalGroup(
       layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
     .addComponent(contentScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE) 
    ); 
    layout.setVerticalGroup(   l layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
     .addGroup(layout.createSequentialGroup() 
      .addContainerGap() 
      .addComponent(contentScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 278, Short.MAX_VALUE) 
      .addContainerGap()) 
     ); 

     pack(); 
     }// </editor-fold>       

    private void myInitComponents(){ 
     //content.setEditorKit(new StyledEditorKit()); 
     contentScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 
     contentScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 
    } 

    private void fetchURL(String url){ 
     try{ 
      // URL(URL baseURL[, String relativeURL]) 
      URL helpURL = new URL(url); 
      this.content.addPropertyChangeListener("page", 
        new PropertyChangeListener() { 
         @Override 
         public void propertyChange(PropertyChangeEvent event) { 
          System.out.println("After lsitening to page load event, getText() on JTextPane gives " 
           + content.getText()); 

          try { 
           System.out.println("After lsitening to page load event, getDocument().getText() on JTextPane gives " 
             + content.getDocument().getText(0, content.getDocument().getLength())); 
          } catch (BadLocationException ex) { 
           Logger.getLogger(TextPaneTester.class.getName()).log(Level.SEVERE, null, ex); 
          } 
         } 
      }); 
      this.content.setPage(helpURL); 
      } 
     catch (IOException e) { 
      System.err.println("Attempted to read a bad URL: " + url); 
     } 
    } 

    public static void main(String args[]) { 
     /* Create and display the form */ 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       String url = "https://en.wikipedia.org/wiki/Stack_Overflow"; 
       TextPaneTester reader = new TextPaneTester(); 
       reader.fetchURL(url); 
       reader.setVisible(true); 
      } 
     }); 
    } 
    // variable declaration     
    private javax.swing.JTextPane content; 
    private javax.swing.JScrollPane contentScrollPane;     
} 

輸出:

run: 
After lsitening to page load event, getDocument().getText() on JTextPane gives          





Stack Overflow 
From Wikipedia, the free encyclopedia 

Jump to: navigation , search 
For other uses, see Stack overflow (disambiguation). 
Stack Overflow 


Screenshot of Stack Overflow as of February 2015 
Web address 
stackoverflow .com 
Commercial? 
Yes 
Type of site 
Knowledge markets 
Registration 
Optional; Uses OpenID 
Available in 
English 
Content license 
CC-BY-SA 3.0 (for user contributions) 
Written in 
ASP.NET MVC [1] 
Owner 
Stack Exchange, Inc. 
Created by 
Joel Spolsky and Jeff Atwood 
Launched 
15 September 2008[2] 
Alexa rank 
52 (March 2015[update])[3] 
Current status 
Online 
Stack Overflow is a privately held website, the flagship site of the Stack Exchange Network,[4][5][6] created in 2008 by Jeff Atwood and Joel Spolsky,[7][8] as a more open alternative to earlier Q&A sites such as Experts-Exchange. The name for the website was chosen by voting in April 2008 by readers of Coding Horror, Atwood's popular programming blog.[9] 
It features questions and answers on a wide range of topics in computer programming.[10][11][12] 
The website serves as a platform for users to ask and answer questions, and, through membership and active participation, to vote questions and answers up or down and edit questions and answers in a fashion similar to a wiki or Digg.[13] Users of Stack Overflow can earn reputation points and "badges"; for example, a person is awarded 10 reputation points for receiving an "up" vote on an answer given to a question, and can receive badges for their valued contributions,[14] which represents a kind of gamification of the traditional Q&A site or forum. All user-generated content is licensed under a Creative Commons Attribute-ShareAlike license.[15] 
Closing questions is a main differentiation from Yahoo! Answers and a way to prevent low quality questions.[16] The mechanism was overhauled in 2013; questions edited after being put "on hold" now appear in a review queue.[17] Jeff Atwood stated in 2010 that duplicate questions are not seen as a problem but rather they constitute an advantage if such additional questions drive extra traffic to the site by multiplying relevant keyword hits in search engines.[18] 
As of April 2014[update], Stack Overflow has over 4,000,000 registered users and more than 11,000,000 questions.[19][20] Based on the type of tags assigned to questions, the top eight most discussed topics on the site are: Java, JavaScript, C#, PHP, Android, jQuery, Python and HTML.[21] 

Contents 
1 History 
1.1 Content criteria 
1.2 User suspension 
2 Statistics 
3 Criticism 
4 Technology 
4.1 Stack Apps 
5 See also 
6 References 
7 External links 

History[edit] 
The website was created by Jeff Atwood and Joel Spolsky in 2008.[7] On 31 July 2008, Jeff Atwood sent out invitations encouraging his subscribers to take part in the private beta of the new website, limiting its use to those willing to test out the new software. On 15 September 2008 it was announced the public beta version was in session and that the general public was now able to use it to seek assistance on programming related issues. The design of the Stack Overflow logo was decided by a voting process.[22] 
On 3 May 2010 it was announced that Stack Overflow had raised $6 million in venture capital from a group of investors led by Union Square Ventures.[23][24] 
Content criteria[edit] 
Stack Overflow admits questions about programming that are tightly focused on a specific problem. Questions that are of a broader nature or invite answers that are inherently a matter of opinion are usually closed by a process carried out by the site's participants. The sister site programmers.stackexchange.com is intended to be a venue for some such broader questions, such as questions about agile software development in general. 
User suspension[edit] 
In April 2009, Stack Exchange implemented a policy of "timed suspension",[25] in order to curtail users who either show "No effort to learn (the community rules) and improve over time" or engage in "disruptive behavior" and become a nuisance. The suspension is accompanied by temporarily setting the user's reputation score at '1' and a notation on the user's profile page indicating the suspension and remaining duration. 
Statistics[edit] 
A 2013 study has found that 77% of users only ask one question, 65% only answer one question, and only 8% of users answer more than 5 questions.[26] As of 2011, 92% of the questions were answered, in a median time of 11 minutes.[27] Since 2013, the Stack Exchange network software automatically deletes questions that meet certain criteria, including having no answers in a certain amount of time.[28] 
As of August 2012, 443,000 of the 1.3M registered users had answered at least one question, and of those, approximately 6,000 (0.46% of the total user count) had earned a reputation score greater than 5000.[29] Reputation can be gained fastest by answering questions related to tags with lower expertise density, doing so promptly (in particular being the first one to answer a question), being active during off-peak hours, and contributing to diverse areas.[29] 
In June 2015, 125,313 posts were deleted within the past 30 days, of which about 8% were deleted by moderators.[30] 
Criticism[edit] 

This section needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed. (July 2014) 
Stack Overflow has been criticized for encouraging poor learning habits, using a rewards system with perverse incentives favoring quick answers versus quality ones,[31] and having a community dominated and shaped by authoritarian moderators[weasel words].[32] The barrier of entry for new users is high.[33] Popular questions with both informative and humorous value have been deleted from the site,[34][35] including the very list of these questions.[36] 
Technology[edit] 
Stack Overflow is written in C#[1] using the ASP.NET MVC (Model-View-Controller) framework, and Microsoft SQL Server for the database[37] and the Dapper object-relational mapper used for data access.[38] Unregistered users have access to most of the site's functionality, while users who sign in (for example, by using the OpenID service) can gain access to more functionality, such as establishing a profile and being able to earn reputation to allow functionality like re-tagging questions or voting to close a question. 
Stack Apps[edit] 
The Stack Overflow team has recently[when?] begun the creation of an API for accessing the data contained on the other sites. Discussion on Stack Apps centers around the API, although users are encouraged to list apps and libraries developed for the API. 
See also[edit] 

Internet portal 

Information technology portal 
Askbot (free engine) 
OSQA (Open Source Question and Answer) 
Rosetta Code (Multi-lingual algorithms) 
List of Internet forums 
... 

PS:我需要允許用戶兩個新行之間選擇喜歡的返回(從的JTextPane視圖)文本textPane.getDocument()。gettext的()。在某種程度上,我期待將此選定文本與相應的HTML塊相映射,以便我可以用翻譯文本(由用戶在另一個JTextPane中給出)的HTML替換其內部HTML。

+0

請提供一些需要工作的工作代碼 –

+0

我不知道要搜索什麼,更不用說如何執行此操作(使用Java)。我的代碼目前只能執行渲染頁面和getDocument()。getText()獲取HTML或文本的任務。 – devautor

+0

那麼,張貼代碼爲@SaqibRezwan說。否則,我們不能提供代碼,恐怕這個問題可能過於寬泛。 – Frakcool

回答

4

添加一個DocumentListener以瞭解底層HTMLDocument的變化。在下面的示例中,相鄰的JTextArea顯示使用getText()的結果鍵入的更改,其中「根據此編輯器的內容類型返回此TextComponent中包含的文本。」您可以遍歷解析的HTMLDocument的元素,如here所示。

程序如何知道正在編輯哪個HTML標記?

一種HTMLDocument模型 HTML,「其結果是,由HTML文檔中描述的結構是不完全默認複製」。編輯器更改元素,而不是標籤。 getText()方法使用HTMLWriter通過遍歷其內部文檔樹的元素來重建建模的HTML。您可以使用適當的構造函數重建文檔的一部分。例如,該方法返回對應於當前選擇HTML:

private String writeSelection() { 
    StringWriter buf = new StringWriter(); 
    HTMLWriter writer = new HTMLWriter(buf, 
     (HTMLDocument)jtp.getDocument(), jtp.getSelectionStart(), jtp.getSelectionEnd()); 
    try { 
     writer.write(); 
    } catch (IOException | BadLocationException ex) { 
     ex.printStackTrace(); 
    } 
    return buf.toString(); 
} 

我希望能夠點擊文本部分,並得到它的HTML。

添加一個CaretListener要了解選擇更改。下面的示例調用writeSelection(),如上所示,每次更改。

jtp.addCaretListener(new CaretListener() { 

    @Override 
    public void caretUpdate(CaretEvent e) { 
     EventQueue.invokeLater(() -> { 
      jta.replaceRange(writeSelection(), 0, jta.getDocument().getLength()); 
     }); 
    } 
}); 

又見結構觀察者引here

image

import java.awt.GridLayout; 
import java.io.IOException; 
import java.net.URL; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.JTextPane; 
import javax.swing.event.DocumentEvent; 
import javax.swing.event.DocumentListener; 

//* @see https://stackoverflow.com/a/30905872/230513 */ 
public class TextPaneTester extends javax.swing.JFrame { 

    private final JTextPane jtp = new JTextPane(); 
    private final JTextArea jta = new JTextArea(20, 48); 

    public TextPaneTester() { 
     initComponents(); 
    } 

    private void initComponents() { 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setLayout(new GridLayout(0, 1)); 
     add(new JScrollPane(jtp)); 
     add(new JScrollPane(jta)); 
     pack(); 
    } 

    private void fetchURL(String url) { 
     try { 
      URL helpURL = new URL(url); 
      this.jtp.setPage(helpURL); 
      this.jtp.getDocument().addDocumentListener(new DocumentListener() { 

       @Override 
       public void insertUpdate(DocumentEvent e) { 
        print(e); 
       } 

       @Override 
       public void removeUpdate(DocumentEvent e) { 
        print(e); 
       } 

       @Override 
       public void changedUpdate(DocumentEvent e) { 
        print(e); 
       } 

       private void print(DocumentEvent e) { 
        jta.replaceRange(jtp.getText(), 0, jta.getDocument().getLength()); 
       } 
      }); 
     } catch (IOException e) { 
      System.err.println("Attempted to read a bad URL: " + url); 
     } 
    } 

    public static void main(String args[]) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       String url = "http://www.example.com"; 
       TextPaneTester reader = new TextPaneTester(); 
       reader.fetchURL(url); 
       reader.setVisible(true); 
      } 
     }); 
    } 
} 
+0

這真的很有用,先生,它真的讓我更接近。謝謝。但實際上我需要更多的控制選擇任何文本的父標籤選擇,因爲我需要像這樣的用戶界面[link](https://upload.wikimedia.org/wikipedia/commons/6/69/Content-Translation -Warning.png)即兩個JTextPanes,它們允許我將源HTML中的樣式和範圍屬性映射到從可編輯的TextPane接收的HTML。我希望我有一些道理。 – devautor

+0

順便說一下,該程序如何知道正在編輯哪個HTML標籤?這可能是我的一些困惑的答案。 – devautor

+0

您可以使用'GridLayout(1,0)'作爲[side-by-side pane](https://upload.wikimedia.org/wikipedia/commons/6/69/Content-Translation-Warning.png);更上面。 – trashgod

0

要更換一個段落的內容,你可以簡單地使用:

HTMLDocument doc = (HTMLDocument)getDocument(); 
    doc.setInnerHTML(doc.getParagraphElement(getSelectionStart()),newContent) 

newContent是你的textarea的HTML內容。

這是你的情況,你逐段翻譯。您可以通過使用獲得更小的實體:

doc.getCharacterElement(getSelectionStart()).getParentElement(); 

編輯:順便問一下,你也可以使用:

try { 
     new HTMLEditorKit().write(writer, htmlDoc, startOffset, length); 
     String html = writer.toString(); 
    } catch (IOException | BadLocationException ex) { 
     Logger.getLogger(Editeur.class.getName()).log(Level.SEVERE, null, ex); 
    } 

獲得文檔的startOffsetstartOffset+length之間的HTML內容。您可以很容易地從中推斷出如何獲取段落,選擇內容或整個文檔的html內容。

+0

我可以做些什麼:「繼續尋找父元素,直到遇到塊元素」?這應該是一個很好的通用方法嗎?而且,謝謝你的幫助! – devautor

+0

與getParagraphElement相比有什麼意義? – Sharcoux

+0

檢查我的編輯,看看如何在需要時獲取文檔的一部分的html。 – Sharcoux