Appending hyperlinks to JEditorPane - java

I've got a program outputs some URLs to a JEditorPane. I want the URLs to be hyperlinks. The program will basically output the URLS to the JEditorPane as if it were a log.
I've got it somewhat working, but it's not hyperlinking the URLs.
Here's the code I have:
JEditorPane editorPane = new JEditorPane();
editorPane.setEditorKit(JEditorPane.createEditorKitForContentType("text/html"));
editorPane.setEditable(false);
editorPane.addHyperlinkListener(new HyperlinkListener() {
//listener code here
});
//some other code here
StyledDocument document = (StyledDocument) editorPane.getDocument();
String url = "http://some url";
String newUrl = "\n"+url+"\n";
document.insertString(document.getLength(), "\n" + newUrl + "\n", null);
Instead of http://example.com/ it's outputting:
http://example.com/
If I don't use a StyledDocument and just do editorPane.setText(newUrl) it does correctly hyperlink the URLs, but it has the obvious problem that setText will replace whatever was already there.

When you use editorPane.setText(), the method will use the editor kit to insert the string. That means it will analyze it, style it and then use document.insertString() with the appropriate styles to create the expected effect.
If you call document.insertString() directly, you're circumventing the editor kit -> no styling. Have a look at the source code for setText() to see how it's done: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/javax/swing/JEditorPane.java#JEditorPane.setText%28java.lang.String%29
Because of copyright, I can't copy the code here. This should get you started:
Document doc = editorPane.getDocument();
EditorKit kit = editorPane.getEditorKit();
StringReader r = new StringReader(newUrl);
kit.read(r, doc, doc.getLength());

Related

How to load local html file in java swing?

I have a tree list which will open a specific html file when I click at a node. I try loading my html into a Jeditorpanel but it can't seem to work.
Here's my code from main file:
private void treeItemMouseClicked(java.awt.event.MouseEvent evt) {
DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) treeItem.getSelectionPath().getLastPathComponent();
String checkLeaf = selectedNode.getUserObject().toString();
if (checkLeaf == "Java Turtorial 1") {
String htmlURL = "/htmlFILE/javaTurtorial1.html";
new displayHTML(htmlURL).setVisible(true);
}
}
Where I wanna display it:
public displayHTML(String htmlURL) {
initComponents();
try {
//Display html file
editorHTML.setPage(htmlURL);
} catch (IOException ex) {
Logger.getLogger(displayHTML.class.getName()).log(Level.SEVERE, null, ex);
}
}
My files:
One simple way to render HTML with JEditorPane is using it's setText method:
JEditorPane editorPane =...
editorPane.setContentType( "text/html" );
editorPane.setText( "<html><body><h1>I'm an html to render</h1></body></html>" );
Note that only certain HTML pages (relatively simple ones) can be rendered with this JEditoPane, if you need something more complicated you'll have to use thirdparty components
Based on OP's comment, I'm adding an update to the answer:
Update
Since the HTMLs that you're trying to load are files inside the JAR, you should read the file into some string variable and use the aforementioned method setText
Note that you shouldn't use java.io.File because it used to identify resources at the filesystem, and you're trying to access something inside the artifact:
Reading the resource like this can be done with the following construction:
InputStream is = getClass().getResourceAsStream("/htmls/myhtml.html");
// and then read with the help of variety of ways, depending on Java Version of your choice and by the availaility by auxiliary thirdparties
// here is the most simple way IMO for Java 9+
String htmlString = new String(input.readAllBytes(), StandardCharsets.UTF_8);
Read Here about many different ways to read InputStream into String

How to save a jsoup document as text file

I am trying to save all of the readable words on a web page into one text document while ignoring html markup.
Using JSoup to parse all of the words on a webpage, my only guess of how to seperate the real words from the code is through elements.
Is it possible to convert multiple elements of the jsoup document into a text file?
i.e.:
Elements titles = doc.select("title");
Elements paragraphs = doc.select("p");
Elements links = doc.select("a[href]");
Elements smallText = doc.select("a");
Currently saving the parse as a document with:
Document doc = Jsoup.connect("https:// (enter a url)").get();
Its simple way
Document doc = Jsoup.connect("https:// (enter a url)").get();
BufferedWriter writer = null;
try
{
writer = new BufferedWriter( new FileWriter("d://test.txt"));
writer.write(doc.toString());
}
catch ( IOException e)
{
}
Adding answer because I am unable to comment above.
Replace writer.write(doc.toString()); by writer.write(doc.select("html").text()); in the above code.
It will give you the text on the page.
Instead of "html" in doc.select("**html**").text() other tags can be used to extract text enclosed in those tags.
Edit: you can also use writer.write(doc.body().text());
After writing in the text with writer.write(doc.text()); the very next line you need to write writer.close(); this will fix the problem.

JAVA POI DOCX replace text in paragraph

Hi i m trying to replace some text in a docx file, but i got problemes with text to be replaced that can be on multiple runs. So i tried this : but it erase everything in the document :/
private void replaceText(XWPFParagraph p, String target, String replacement) {
if (p.getRuns() != null) {
String paragraph = p.getText();
for (int i = 0; i < p.getRuns().size(); i++) {
p.removeRun(i);
}
paragraph = paragraph.replace(target, replacement);
XWPFRun r = new XWPFRun(CTR.Factory.newInstance(), p);
r.setText(paragraph, 0);
}
}
It will surely erase everything because you are removing all the runs in the paragraph. Point to understand here is that the text in the paragraph is stored inside the runs. What getText() does is it returns all the text in all the runs of the paragraph.
Removing all runs and adding just one new run will surely disrupt the font and alignment of the text
You are removing all the runs and then adding one run with the replaced text.
I believe this is not what you wish to achieve.
Just loop over the runs and replace the text inside them.
For one of my projects I chose a different route, I work on the underlying XML data and do a search/replace there which usually works quite nicely.
See https://github.com/centic9/poi-mail-merge for the details, but basically I fetch the CTBody low-level item via
CTBody body = doc.getDocument().getBody();
And then read the full XML body text
// read the current full Body text
String srcString = body.xmlText();
then do the replacements.
Finally I create a new CTBody item with the new contents via
CTBody makeBody = CTBody.Factory.parse(resultStr);
See https://github.com/centic9/poi-mail-merge/blob/master/src/main/java/org/dstadler/poi/mailmerge/MailMerge.java#L81 for the full code-details as there are a few more things that are handled to make it work nicely.

JTextPane HTML Image integration

I have a JTextPane and I do it :
HTMLEditorKit kit = new HTMLEditorKit();
HTMLDocument doc = new HTMLDocument();`
this.setEditorKit(kit);
this.setDocument(doc);
Then I do :
profilePictureSrc = "http://ola/profilePicture1.jpg";
chatContent ="<img src=\"" + profilePictureSrc + "\">";
Where profilePictureSrc is a URL Object.
It works but I must use a String instead of the URL (Java Hashtable put method slow down my application)
How Can I do that ? Do I have to put the picture files somewhere and use a relative Path to reach them ? Thank you very much for your ideas
Best Regards
You can convert url objects to strings.
String urlstring = myurl.toString();

Java JTextPane HTML image cookies

I am using a JTextPane to display data from a webpage that isn't mine, so I have no control over its contents. It requires a user to be logged in, so I use URLConnections to connect to that webpage and use cookies in the URLConnection to retrieve data. That works fine. However, when I put this data in a JTextPane with the content type set to text/html, the images do not display as they require those cookies with the session id and stuff to be sent in order to retrieve the uploaded images.
Is there any way I can make the JTextPane (though I am able to use anything else in the jdk that displays html) use my cookies?
Thanks.
I store the cookies in a linked list:
loadText = "Logging in...";
url = new URL("http://www.example.com/login.php");
connection = url.openConnection();
connection.setDoOutput(true);
OutputStreamWriter out = new OutputStreamWriter(
connection.getOutputStream());
out.write("username=" + URLEncoder.encode(username, "UTF-8")
+ "&password=" + URLEncoder.encode(password, "UTF-8")
+ "&testcookies=1");
out.flush();
out.close();
List<String> cookies = new LinkedList<String>();
for (int i = 1; (headerName = connection.getHeaderFieldKey(i)) != null; i++) {
if (headerName.equals("Set-Cookie")) {
String cookie = connection.getHeaderField(i);
cookie = cookie.substring(0, cookie.indexOf(";"));
cookies.add(cookie);
}
}
And I also need to strip away unneccesary HTML, which gives me a string I plug into the textpane:
String p1 = rawPage.split("<div id=\"contentstart\">")[1]
.split("</div><!--id='contentstart'-->")[0];
p1 = p1.replaceAll("<p><strong></strong></p>", "");
p1 = p1.replaceAll("<p></p>", "");
parsed = true;
JTextPane tp = new JTextPane();
tp.setEditable(false);
JScrollPane js = new JScrollPane();
js.getViewport().add(tp);
js.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
getContentPane().add(js);
js.setSize(640, 480);
tp.setContentType("text/html");
tp.setText(p1);
Are you not reading the content from URLConnection? Something like this may help.
Post your code so that we can get more insight.
JTextPane pane;
..
HTMLDocument htmlDocument = (HTMLDocument) pane.getDocument();
htmlDocument.putProperty("IgnoreCharsetDirective", Boolean.TRUE);
htmlDocument.putProperty(Document.StreamDescriptionProperty, pageUrl);
pane.read(connection.getInputStream, htmlDocument);
-- or --
You may try the browser swing component instead of JTextPane.
http://djproject.sourceforge.net/ns/index.html
Cookies are stored in relation to your browser. For example, if you have some cookies in Firefox, Microsoft IE can't see those cookies. Similarly, the cookies you have obtained from the webpage you're looking for are not available to your Java application.
But also, JTextPane is not a full-featured HTML browser. You can use it to render basic HTML (actually HTML 2.0, a much older version of HTML), but it won't work with cookies, CSS, and other now-standard web features.
You may want to look at full-featured web browsers, such as Flying Saucer - see http://weblogs.java.net/blog/2007/07/14/flying-saucer-r7-out
But even if you do this, Flying Saucer won't see the cookies that you've obtained through other browsers.

Categories