Newline char when creating text/html JTextPane - java

I have an editable JTextpane and want to enable HTML so the initial text appears formatted. This works, however, now the first char in the string is '\n', meaning the string is 1 char longer than expected. I can delete this (e.g. for the word 'foo', I can press backspace 4 times to delete the word first and then the '\n').
Obviously, I would prefer it if I only have the desired string right away, without any tricks to delete it afterwards. I would appreciate any help on this!
Here is my example code:
JTextPane testPane = new JTextPane();
testPane.setContentType("text/html");
testPane.setText("<html><body><span style='color:red'>My Text which will have a newline at the beginning.</span></body></html>");
// testPane.setText("the same newline at the start even without the HTML tags");
StyledDocument doc = testPane.getStyledDocument();
SimpleAttributeSet myAttributeSet = new SimpleAttributeSet();
StyleConstants.setFontSize(myAttributeSet, 14);
StyleConstants.setFontFamily(myAttributeSet, Font.DIALOG);
doc.setParagraphAttributes(0, doc.getLength(), myAttributeSet, false);
testPane.setDocument(doc);
myGridPanel.add(testPane, gbc);
Note that the newline char appears whether or not I have all this tag info (i.e. '').
I would appreciate any hints on what I'm doing wrong or what I should do to avoid this extra character at the beginning.
Thanks in advance!

The \n that you see is the place reserved in the document for the head.
Be careful, it also means that the body starts at char 1. Everything you write before that will not be displayed.
If you don't need it, you can do:
public static void removeHead(JTextPane testPane) {
javax.swing.text.Element head = testPane.getDocument().getDefaultRootElement().getElement(0);
if(head.getName().equals("head")) {
try {
testPane.getDocument().remove(0, head.getEndOffset());
} catch (BadLocationException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

Related

How to append a text field in JFrame?

For instance using textField.setText it replaces the text currently in the text field however I want the output to go one step down from the previous output. Any help would be appreciated. Thanks.
Add the text directly to the Document:
Document doc = textField.getDocument();
doc.insertString(doc.getLength(), "the text", null);
Another option might be to use:
textField.replaceSelection(...);
and the text will be added at the current caret position.
Edit:
Here is the code used by the append(...) method of a JTextArea
public void append(String str) {
Document doc = getDocument();
if (doc != null) {
try {
doc.insertString(doc.getLength(), str, null);
} catch (BadLocationException e) {
}
}
}
I suggest you could use the replaceSelection(...) method since there in not need for the try/catch block.

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'

How to insert clickable text into a JTextPane?

I've been making a chat program for a few days now and I'm completely stumped on how to create a nice looking clickable text without the use of HTML. I tried to use HTML, but had extremely weird results (see below). So I am now just using
basic text rather then text/html.
My first attempt to add clickable text was to use JTextPane's ability to insert Components along with the text. It inserted and worked perfectly, but it was vertically offset and looked very bad. I tried to mess with setAlignmentY, but had no luck aligning the components with the text.
JLabel l = new JLabel(test);
l.setFont(this.getFont());
l.setCursor(new Cursor(Cursor.HAND_CURSOR));
l.setBackground(Color.RED); //Just so i could see it better for testing
l.addMouseListener(new FakeMouseListener());
this.insertComponent(l);
I'm using JTextPane and inserting text using doc.insertString. I skip lines using the systems line separator, so a single line can contain multiple doc.insertStrings (Which is were I ran into trouble when attempting to use text/html).
This inserts HTML without any alignment problems. I think ("think" because I don't have enough of your code to know) that you had issues because of Document.insertString while I use HTMLEditorKit.insertHTML.
public class Example extends JFrame {
Example() {
JEditorPane pane = new JEditorPane();
pane.setEditable(false);
pane.setContentType("text/html");
HTMLDocument doc = (HTMLDocument) pane.getDocument();
HTMLEditorKit editorKit = (HTMLEditorKit) pane.getEditorKit();
try {
editorKit.insertHTML(doc, doc.getLength(), "clickable1", 0, 0, null);
editorKit.insertHTML(doc, doc.getLength(), "clickable2", 0, 0, null);
editorKit.insertHTML(doc, doc.getLength(), "clickable3", 0, 0, null);
} catch (BadLocationException | IOException e) {
e.printStackTrace();
}
pane.addHyperlinkListener(new HyperlinkListener() {
#Override
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
System.out.println(e.getSourceElement());
if (e.getURL() != null)
System.out.println(e.getURL());
else
System.out.println(e.getDescription());
System.out.println("-----");
}
}
});
add(pane);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
new Example();
}
}
Notes:
setEditable(false) must be called for this to work properly (probably there is some convoluted way to make it work otherwise).
The HyperlinkListener is just to prove that the links work, along with some demonstration of how to get the link string (getURL will only work if the link is a valid URL).
You don't need to set the cursor, with or without the HyperlinkListener.
Turns out i put setAlignmentY(0.85f); for the JTextPane instead of the JLable.
If you have an offset component you're attempting to insert into JTextPane, mess around with it's Y alignment. 0.85f works for me.

How to insert a html special character in a JTextPane

I have read many threads on JTextPane and it made me start writing a little text editor using JTextPane, but in the middle of the project am almost folding up! Please can some one explain to me how i can insert an html character int a textpane like
JTextPane pane = new JtextPane();
pane.settext("¢");
My problem is that if i have already keyed in some text and I then use the settext mathod to insert a special character on the same line of text then the special character is inserted while the previous text disappears. How can I stop that happening?
You haven't said when you want to call setText. If you want to do it in response to a button click, then you just need to:
Read the text from the (captured variable for the) pane
Append your desired character
(Optionally) use grabFocus to put the focus and input caret back into the text pane.
The code would look like this:
JButton btnAdd = new JButton("add");
jPanel1.add(btnAdd);
btnAdd.addActionListener(new ActionListener(){
#Override public void actionPerformed(ActionEvent arg0) {
String text = pane.getText();
pane.setText(text + "¢");
pane.grabFocus();
}
});
If you are working with HTMLDocument (you haven't posted your full code, so it is not clear what you are doing to produce HTML), you could do something like:
pane = new JTextPane();
jPanel1.add(pane);
final HTMLEditorKit kit = new HTMLEditorKit();
final HTMLDocument doc = new HTMLDocument();
pane.setEditorKit(kit);
pane.setDocument(doc);
...
btnAdd.addActionListener(new ActionListener(){
#Override public void actionPerformed(ActionEvent arg0) {
int start = pane.getSelectionStart();
try {
// add a span containing the desired element inside the current paragraph or other containing element
kit.insertHTML(doc, start, "<span>¢</span>", 0, 0, HTML.Tag.SPAN);
} catch ...
pane.grabFocus();
}
});

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