Java Swing JEditorPane: manipulating styled documents - java

I have model that is a queue of Strings associated with enum types.
I'm trying to display that model in a JEditorPane, with each element in the queue as a separate HTML paragraph that has attributes based based on the associated enum type.
However, my updating methods are not doing what I want. I tried writing the HTML strings directly to the document (e.g., I take the Strings, prepend <p style="color:red"> and append </p> and then insert them at the end of the document), but that gives me the html tags in the output (instead of as formatting) - which of course is inconsistent with the result of putting the tags on the string that I use construct the document with JEditorPane("text/html",String foo). I've also tried inserting with an AttributeSet, but apparently I'm doing that wrong as well.
Any suggestions?

I've never had much luck playing with HTML in a JEditorPane. I just use attributes in a JTextPane. Something like:
SimpleAttributSet keyWord = new SimpleAttributeSet();
StyleConstants.setForeground(keyWord, Color.RED);
StyleConstants.setBackground(keyWord, Color.YELLOW);
StyleConstants.setBold(keyWord, true);
try
{
doc.insertString(doc.getLength(), "\nSome more text", keyWord );
}
catch(Exception e) {}

Related

Using W3C Document Object Model how to insert tag for particular text

For example i have html content like this.
<div>go to the text from here.<br> from there <br> Go to the text</div>
In the above content, i want to insert span tag for the word alone Like the below output using java.
I'm using org.w3c.dom package.
I tried but not able to make success
Element e = doc.createElement("span");
String text = preElement.getTextContent();
if(text.indexOf("text"){
e.setTextContent("text");
}
// Afterwards how to insert this to document. How to use insertBefore method for the //inbetween text.
Expected Output:
<div>go to the <span>text</span> from here.<br> from there <br> Go to the <span>text</span></div>
Please help.
You have to use the splitText method on your text node to split it into three nodes, isolating the word you need to wrap in your element. Then you only have to replace the text node you just isolated (use replaceChild) with the new element. There is no need to create a new text node, you can simply put the one you removed in the element you added.
Java implementation reference: http://docs.oracle.com/javase/7/docs/api/org/w3c/dom/Text.html#splitText%28int%29 http://docs.oracle.com/javase/7/docs/api/org/w3c/dom/Node.html#replaceChild%28org.w3c.dom.Node,%20org.w3c.dom.Node%29.

How to set colour of text from a certain point forward

I'm building a small conversation agent, where the text looks like follows:
I would like to set the System's text to always be red. The text is all placed in a JTextPane.
How can I accomplish this? I have tried doing the following:
agentTextPane.setForeground(Color.red); after the system's text is added, and then switching back to black, however that changes all the text in the JTextPane.
This is how the system's text is added:
//'output' is a stringBuilder
output.append("\nSystem: ").append(tempOutput).append("\n");
agentTextPane.setText(output.toString());
As shown here, you can define an attribute set representing a desired style. For example,
StyledDocument doc = (StyledDocument) jtp.getDocument();
SimpleAttributeSet system = new SimpleAttributeSet();
StyleConstants.setFontFamily(system, "Serif");
StyleConstants.setForeground(system, Color.red);
doc.insertString(doc.getLength(), "...", system);
The styles can be progressive, as shown here.
See Text Component Features for more examples.
You may want to use HTML tags to format your Strings in terms of colour. The following reference may be useful. setting JTextPane to content type HTML and using string builders
output.append("<font color=\"red\">");
output.append("\nSystem: ").append(tempOutput).append("\n");
output.append("</font>");

jmesa renders the html as text

I'm using jmesa in Java directly using the tableModel.render() to get the HTML directly. Some of my web objects in my result lists contain HTML - example:
class blah {
String email;
public String getEmailLink() {
return "<a href='" + email + "</a>"
}
}
In my Java code I would just do this:
htmlRow.addColumn(new HtmlColumn("emailLink"));
jmesa is rendering this as text. How can I tell jmesa to render the text as-is to be html in the document?
TIA
Looking at the JMesa soure code, HtmlCellEditor automatically escapes HTML.
I haven't tested it, but you should be able to override the default HtmlCellEditor with a different type... such as the bare-bones BasicCellEditor. It shouldn't be too much extra code:
HtmlColumn emailLinkColumn = new HtmlColumn("emailLink");
emailLinkColumn.setCellEditor(new BasicCellEditor());
htmlRow.addColumn(emailLinkColumn);
Another option to all of this is to create a custom CellEditor and have it create your <a> tag for you instead of doing it in your bean. This page should get you started with custom CellEditors if you want to go that route.
BTW, if you are messing with just a value inside of a cell, overriding/replacing CellEditor is probably all you need (CellEditor it is analogous to the body of a <td>). CellRenderer is concerned with the entire cell (analogous to the <td> as well as its contents).
Use a HtmlCellRenderer as shown in this tutorial.

extract text from HTML segment using standard java

I'm receiving a segment of HTML document as Java String and i would like to extract it's inner text.
for ex: hello world ----> hello world
is there a way to extract the text using java standard library ?
something maybe more efficient than open/close tag regex with empty string?
thanks,
Don't use regex to parse HTML but a dedicated parser like HtmlCleaner.
Using a regex will usually work at fist test, and then start to be more and more complex until it ends being impossible to adapt.
I will also say it - don't use regex with HTML. ;-)
You can give a shot with JTidy.
Don't use regular expression to parse HTML, use for instance jsoup: Java HTML Parser. It has a convenient way to select elements from the DOM.
Example
Fetch the Wikipedia homepage, parse it to a DOM, and select the headlines from the In the news section into a list of Elements:
Document doc = Jsoup.connect("http://en.wikipedia.org/").get();
Elements newsHeadlines = doc.select("#mp-itn b a");
There is also a HTML parser in the JDK: javax.swing.text.html.parser.Parser, which could be applied like this:
Reader in = new InputStreamReader(new URL(webpageURL).openConnection().getInputStream());
ParserDelegator parserDelegator = new ParserDelegator();
parserDelegator.parse(in, harvester, true);
Then, dependent on what kind you are looking for: start tags, end tags, attributes, etc. you define the appropriate callback function:
#Override
public void handleStartTag(HTML.Tag tag,
MutableAttributeSet mutableAttributeSet, int pos) {
// parses the HTML document until a <a> or <area> tag is found
if (tag == HTML.Tag.A || tag == HTML.Tag.AREA) {
// reading the href attribute of the tag
String address = (String) mutableAttributeSet
.getAttribute(Attribute.HREF);
/* ... */
You can use HTMLParser , this is a open source.

Which is the best Wicket component for rendering arbitrary HTML?

I am implementing a simple markdown wiki using Apache Wicket. The wiki would typically render any arbitrary HTML based on what the user has entered.
I am a bit confused about which Wicket component would be best suited to render such arbitrary HTML.
I tried the Label component but it does not render lists properly, neither does the MultilineLabel (which puts breaks instead of the regular list HTML).
Thanks for any help.
UPDATE: The Label component works perfectly. It was my mistake that I was not able to get it to work earlier. It was a combination of some bad stylesheets and late night coding. Thanks for the helpfull answers. As suggested, I am also going to check out some WYSIWYG editors, which actually might work out better than markdown. Visural Wicket seems especially promising.
If what you want to render is not big, or is already represented as a String, Label will work well, just call label.setEscapeModelStrings(false); to ensure it prints the string as is.
But, if your HTML content is generated dynamically, or read from an InputStream/Reader, and you don't want to keep it in memory, you could use WebComponent directly, and override the method onComponentTagBody(). This way, you write directly to the response, instead of filling a in-memory buffer, transform it to a String, and then write to the response (which happens if you use Label).
Sample code, for both cases:
HomePage.java
public class HomePage extends WebPage {
public HomePage() {
add(new Label("label", "<ul><li>test</li><li>test</li><li>test</li><li>test</li><li>test</li></ul>")
.setEscapeModelStrings(false));
add(new WebComponent("html") {
#Override
protected void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) {
Response response = getRequestCycle().getResponse();
response.write("<ul>");
for (int i = 0; i < 5; i++)
response.write("<li>test</li>");
response.write("</ul>");
}
});
}
}
HomePage.html
<html xmlns:wicket="http://wicket.apache.org">
<body>
<h2>Label</h2>
<div wicket:id="label"></div>
<h2>WebComponent</h2>
<div wicket:id="html"></div>
</body>
</html>
It is Label, call Component.setEscapeModelStrings(false) though to render the raw html your model returns.

Categories