How to preserve style of texts in JTextPane while append strings - java

Hi I have JTextPane and I want to load contents (text with font information) in different time. the appending text will always change in Font name or size or bold or italic. When I inserted new string(with diff fonts), TextPane always loosing font information of a previous loaded text. How to preserve font information always for a text pane? Also I want to insert images!! Do I have to use HtmlDocument for that? Any idea or suggestions are most welcome. Thanks in advance!! My code for JTextPane is,
textPane.setText("\n This is sample text editor ex");
styleDoc = textPane.getStyledDocument();
SimpleAttributeSet keyWord = new SimpleAttributeSet();
// set font information for new text
StyleConstants.setFontFamily(keyWord, fontName);
StyleConstants.setFontSize(keyWord, fontSize);
try {
styleDoc.insertString(0,
styleDoc.getText(0, styleDoc.getLength()), null);
styleDoc.insertString(styleDoc.getLength(), "ample", keyWord);
} catch (Exception e) {
e.printStackTrace();
}

Quick answer, for a quick question.
1) Use JTextPane.inserComponent or JTextPane.insertIcon to insert your images.
2) Use a StyledEditorKit to append your styled text. Remember that you can also use an HTMLDocument and HTMLEditorKit to handle html content.

Related

JTextPane adding large spaces every time i insertString

Hey i'm making a chat application and was at first using a simple JTextPane for a basic, color supporting, chat view pane. I then wanted to add html link support to make them clickable by adding an HTML listener and setting the content type to text/html. The clickable links work perfectly, but now every time i insert a String the chat will add a large space. Here is the code i use below:
Constructor:
public JTextPaneTest() {
this.addHyperlinkListener(new LinkController());
this.setContentType("text/html");
this.setEditable(false);
}
Here is how i append regular text:
public void append(Color c, String s) {
SimpleAttributeSet sas = new SimpleAttributeSet();
StyleConstants.setForeground(sas, c);
StyledDocument doc = (StyledDocument)this.getDocument();
int len = getDocument().getLength();
try {
doc.insertString(len, s, sas);
} catch (BadLocationException e) {
e.printStackTrace();
}
setCaretPosition(len + s.length());
}
And Here is how i insertlinks
public void addHyperlink(URL url, String text) {
try {
Document doc = this.getDocument();
SimpleAttributeSet hrefAttr = new SimpleAttributeSet();
hrefAttr.addAttribute(HTML.Attribute.HREF, url.toString());
SimpleAttributeSet attrs = new SimpleAttributeSet();
attrs.addAttribute(HTML.Tag.A, hrefAttr);
StyleConstants.setUnderline(attrs, true);
StyleConstants.setForeground(attrs, Color.blue);
doc.insertString(doc.getLength(), text, attrs);
}
catch (BadLocationException e) {
e.printStackTrace(System.err);
}
}
For whatever reason with the content type set to just basic text, i don't get this space issue.
Here are some pictures of it:
http://i.stack.imgur.com/dpMBB.png
In the picture, the Name is inserted, then :, Then the rest of the text.
Edit: For whatever reason the JTextPane is automatically centering my InsertStrings.
Edit2: Is it possible to remove the margin between the HTML inserted strings? I've been trying everything for hours on end and simply can't find a solution. Only possible solution i can think of is reformatting the text via getText/setText every time i insert a string to insure no margins are added..
Instead of inserting text ith attribute try to create a dummy element and replace it with outer HTML containing th link
SimpleAttributeSet a=new SimpleAttributeSet();
a.addAttribute("DUMMY_ATTRIBUTE_NAME","DUMMY_ATTRIBUTE_VALUE");
doc.setCharacterAttributes(start, text.length(), a, false);
Element elem=doc.getCharacterElement(start);
String html="<a href='"+text+"'>"+text+"</a>";
doc.setOuterHTML(elem, html);
Se working example here
I ended up using just basic 'text' and using components for click detection.
To fix this issue i was having with HTML, i simply used
editorKit.insertHTML(doc, doc.getLength(), "html code", 0, 0, null);
Rather then inserting my code directly usings doc's 'insertString'

JEditorKit color single chars without html

I want to mark parts of a jeditorpane content with a color, without using the html type content type. is there a way to accomplish this, maybe playing around with the document?
without using the html type content type
This means you have a plan text file and you should be using a JTextPane. Then you can use attributes to color the text.
JTextPane textPane = new JTextPane();
textPane.setText("Some text for the text pane.");
StyledDocument doc = textPane.getStyledDocument();
SimpleAttributeSet keyWord = new SimpleAttributeSet();
StyleConstants.setForeground(keyWord, Color.RED);
StyleConstants.setBackground(keyWord, Color.YELLOW);
StyleConstants.setBold(keyWord, true);
// Color existing text
doc.setCharacterAttributes(0, 5, keyWord, false);
// Add some text
try
{
doc.insertString(doc.getLength(), "\nEnd of text", keyWord );
}
catch(Exception e) { System.out.println(e); }

setContentType("text/html") for JTextPane doesn't work as it is expected

When you setContentType("text/html") it is applied only for the text that is set via JTextPane.setText(). All other text, that is put to the JTextPane via styles is "immune" to content type.
Here is what I mean:
private final String[] messages = {"first msg", "second msg <img src=\"file:src/test/2.png\"/> yeah", "<img src=\"file:src/test/2.png\"/> third msg"};
public TestGUI() throws BadLocationException {
JTextPane textPane = new JTextPane();
textPane.setEditable(false);
textPane.setContentType("text/html");
//Read all the messages
StringBuilder text = new StringBuilder();
for (String msg : messages) {
textext.append(msg).append("<br/>");
}
textPane.setText(text.toString());
//Add new message
StyledDocument styleDoc = textPane.getStyledDocument();
styleDoc.insertString(styleDoc.getLength(), messages[1], null);
JScrollPane scrollPane = new JScrollPane(textPane, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
//add scrollPane to the main window and launch
//...
}
In general, I have a chat that is represented by JTextPane. I receive messages from server, process them - set text color for specific cases, change smile markers to images path etc. everything is made within the bounds of HTML. But as it can be clearly seen from example above, only the setText is the subject of setContentType("text/html") and the second part, where new message added is represented by "text/plain" (if I'm not mistaken).
Is it possible to apply "text/html" content type to all data that is inserted to JTextPane? Without it, it is almost impossible to process messages without implemention of very complex algorithm.
I don't think you should be using the insertString() method to add text. I think you should be using something like:
JTextPane textPane = new JTextPane();
textPane.setContentType( "text/html" );
textPane.setEditable(false);
HTMLDocument doc = (HTMLDocument)textPane.getDocument();
HTMLEditorKit editorKit = (HTMLEditorKit)textPane.getEditorKit();
String text = "hyperlink";
editorKit.insertHTML(doc, doc.getLength(), text, 0, 0, null);
REEDIT
Sorry, I misunderstood the problem: inserting a string as HTML.
For that one needs to resort to the HTMLEditorKit capabilities:
StyledDocument styleDoc = textPane.getStyledDocument();
HTMLDocument doc = (HTMLDocument)styleDoc;
Element last = doc.getParagraphElement(doc.getLength());
try {
doc.insertBeforeEnd(last, messages[1] + "<br>");
} catch (BadLocationException ex) {
} catch (IOException ex) {
}
Here is a much simpler way to do that.
JTextPane pane = new JTextPane();
pane.setContentType("text/html");
pane.setText("<html><h1>My First Heading</h1><p>My first paragraph.</p></body></html>");

HTML in JTextArea of JEditorPane, JTextPane

Right I already worked out that JTextArea or JTextField don't support HTML.
I want to add text to a "screen" like a JTextArea and later keep appending text to it.
I tried with JTextArea which worked wonderfully, but it does not support formatting it seems...
So I tried using JEditorPane's subclass JTextPane, but this one does not have it's append function...
Can someone guid me in the right direction how I easily can append text to a JTextPane or format a JTextArea.
Or if there is any other component better for this please tell me :)
The update method is called by a subject which does this for multiple objects. This just gives a bunch of strings which are formatted and then put in a nice frame to show the user.
#Override
public void update(String channel, String sender, String message) {
if(channel.equals(this.subject) || sender.equals(subject)){
StringBuffer b = new StringBuffer();
b.append("<html>");
b.append("<b>");
b.append("</b>");
b.append("[");
b.append(sender);
b.append("] : ");
b.append("</b>");
b.append(message);
b.append("</html>");
b.append("\n");
chatArea.append(b.toString());
}
Can someone guid me in the right direction how I easily can append text to a JTextPane
Document doc = textPane.getDocument();
doc.insertString(doc.getLength(), "some text", green);
And use attributes instead of HTML, its much easier. For example you could define the "green" attributes to be:
SimpleAttributeSet green = new SimpleAttributeSet();
StyleConstants.setForeground(green, Color.GREEN);
You can use JEditorPane. But when you want to append some Strings that that contain HTML tag you should perform some methods not just a insertString() method.
For example, you have
//setup EditorPane
JEditorPane yourEditorPane = new JEditorPane();
yourEditorPane.setContentType("text/html");
//setup HTMLEditorKit
HTMLEditorKit htmlEditorKit = new HTMLEditorKit();
yourEditorPane.setEditorKit(htmlEditorKit);
If you only use insertString()
String htmlText = "<div class='test'><b>Testing</b></div>";
Document doc = yourEditorPane.getDocument();
doc.insertString(doc.getLength(), htmlText, null);
The output will be
< div class = 'test' >< b >Testing< /b >< /div >
You should do this method
htmlEditorKit.insertHTML((HTMLDocument) doc, doc.getLength(), htmlText, 0, 0, null);
So the output on your editorpane will be
Testing
Last, if you want to style your editorpane you can use this method
StyleSheet css = htmlEditorKit.getStyleSheet();
css.addRule(".test {color: green;}");
For formatted output the JEditorPAne is probably the best option.
You can use the getText() method of the JEditorPane to get the text that is currently in the pane, then append the new text and call setText() to put everything back.
e.g.
b.append(chatArea.getText());
b.append("All the other text")
chatArea.setTExt(b.toString());

JTextPane appending a new string

In an every article the answer to a question "How to append a string to a JEditorPane?" is something like
jep.setText(jep.getText + "new string");
I have tried this:
jep.setText("<b>Termination time : </b>" +
CriterionFunction.estimateIndividual_top(individual) + " </br>");
jep.setText(jep.getText() + "Processes' distribution: </br>");
And as a result I got "Termination time : 1000" without "Processes' distribution:"
Why did this happen???
I doubt that is the recommended approach for appending text. This means every time you change some text you need to reparse the entire document. The reason people may do this is because the don't understand how to use a JEditorPane. That includes me.
I much prefer using a JTextPane and then using attributes. A simple example might be something like:
JTextPane textPane = new JTextPane();
textPane.setText( "original text" );
StyledDocument doc = textPane.getStyledDocument();
// Define a keyword attribute
SimpleAttributeSet keyWord = new SimpleAttributeSet();
StyleConstants.setForeground(keyWord, Color.RED);
StyleConstants.setBackground(keyWord, Color.YELLOW);
StyleConstants.setBold(keyWord, true);
// Add some text
try
{
doc.insertString(0, "Start of text\n", null );
doc.insertString(doc.getLength(), "\nEnd of text", keyWord );
}
catch(Exception e) { System.out.println(e); }
A JEditorPane, just a like a JTextPane has a Document that you can use for inserting strings.
What you'll want to do to append text into a JEditorPane is this snippet:
JEditorPane pane = new JEditorPane();
/* ... Other stuff ... */
public void append(String s) {
try {
Document doc = pane.getDocument();
doc.insertString(doc.getLength(), s, null);
} catch(BadLocationException exc) {
exc.printStackTrace();
}
}
I tested this and it worked fine for me. The doc.getLength() is where you want to insert the string, obviously with this line you would be adding it to the end of the text.
setText is to set all text in a textpane. Use the StyledDocument interface to append, remove, ans so on text.
txtPane.getStyledDocument().insertString(
offsetWhereYouWant, "text you want", attributesYouHope);

Categories

Resources