Keeping the correct style on text retrieval
This has been solved by merging the document models of the two panes. The solution is in this question: Keeping the format on text retrieval
Keeping the format on text retrieval
Use the example to merge both Documents
http://java-sl.com/tip_merge_documents.html
Strange text wrapping with styled text in JTextPane with Java 7
for futures readers, bug is still present in JDK 1.7.0_04.,
comparing Java7 and with stable Java6,
<------ Java7 v.s. Java6 --->
<------ Java7 v.s. Java6 --->
<------ Java7 v.s. Java6 --->
<------ Java7 v.s. Java6 --->
from code
import java.awt.Dimension;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
public class BugWrapJava7 {
private JFrame frame = new JFrame();
private JTextPane jtp;
private StyledDocument doc;
public BugWrapJava7() {
jtp = new JTextPane();
jtp.setText("\ntype some text in the above empty line and check the wrapping behavior");
doc = jtp.getStyledDocument();
doc.addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) {
insert();
}
public void removeUpdate(DocumentEvent e) {
insert();
}
public void changedUpdate(DocumentEvent e) {
insert();
}
public void insert() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Style defaultStyle = jtp.getStyle(StyleContext.DEFAULT_STYLE);
doc.setCharacterAttributes(0, doc.getLength(), defaultStyle, false);
}
});
}
});
JScrollPane scroll = new JScrollPane(jtp);
scroll.setPreferredSize(new Dimension(200, 200));
frame.add(scroll);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
BugWrapJava7 bugWrapJava7 = new BugWrapJava7();
}
});
}
}
JTextPane highlighting issue
A JTextComponent
's getText()
and A JTextPane/JEditorPane
's getText()
has different implementation. JTextPane/JEditorPane
uses EditorKit
to write the document content(text) to a StringWriter
and then return the text with formatting and inserting a line/paragraph break into the document. But the JTextCompoent
returns document content directly by:
document.getText(0, document.getLength());
You will better understand if you try to compare the length : jTextPane1.getText().length()
and jTextPane1().getDocument().getLength()
.
Reproducing the difference in length by inserting string with:
DefaultStyleDocument.insertString(0, str, primaryStyle)
when str = "I\n not" ; document length = 6, getText().length = 7
when str = "I\r\n not" ; document length = 7, getText().length = 8
when str = "I\n\n not" ; document length = 7, getText().length = 9!
So, in your high-lighting text program try reading the content text using:
DefaultStyledDocument document = (DefaultStyledDocument) jTextPane1.getDocument();
try {
contText = document.getText(0, document.getLength());
} catch (BadLocationException ex) {
Logger.getLogger(JTextPaneTest.class.getName()).log(Level.SEVERE, null, ex);
}
Then search for your selected text position in the contText
as you were doing and you should be good to go. Because, highlighter.addHighlight(int p0, int p1, Highlighter.HighlightPainter p)
uses the document
for position offset.
Use CaretListener
:
To Highlight upon text selection, It is better to use CaretListener
, no need to add mouse and key board selection handling code at all:
jTextPane1.addCaretListener(new CaretListener() {
public void caretUpdate(CaretEvent evt) {
if(evt.getDot() == evt.getMark())return;
JTextPane txtPane = (JTextPane) evt.getSource();
DefaultHighlighter highlighter = (DefaultHighlighter) txtPane.getHighlighter();
highlighter.removeAllHighlights();
DefaultHighlightPainter hPainter = new DefaultHighlightPainter(new Color(0xFFAA00));
String selText = txtPane.getSelectedText();
String contText = "";// = jTextPane1.getText();
DefaultStyledDocument document = (DefaultStyledDocument) txtPane.getDocument();
try {
contText = document.getText(0, document.getLength());
} catch (BadLocationException ex) {
Logger.getLogger(JTextPaneTest.class.getName()).log(Level.SEVERE, null, ex);
}
int index = 0;
while((index = contText.indexOf(selText, index)) > -1){
try {
highlighter.addHighlight(index, selText.length()+index, hPainter);
index = index + selText.length();
} catch (BadLocationException ex) {
Logger.getLogger(JTextPaneTest.class.getName()).log(Level.SEVERE, null, ex);
//System.out.println(index);
}
}
}
});
Styling text in a JTextArea or JTextPane
If you want to diplaying Html
contents in the JTextPane then you have to set for JTextPane#setContentType("text/html");, example here
EDIT:
for JEditorPanes / JTextPanes
is there another way by implements StyledDocument, MutableAttributeSet and with customized Highlighter, example here
a.m. way is without using Html syntax
Get all text of specific style from JTextPane
You can define your own attribute and place it with all the other ones. Just use SimpleAttributeSet
and place there the new attribute (let's name it "MessageTypeAttribute") the value could be string constants for each required type.
To iterate the Document
use getCharacterElement()
method. Start from 0 and then move to the end offset of the element to retrieve the next one.
JTextPane: How to set the font size
Sure, you can create a font object and use it to set the font of your text pane.
Instantiate it like this:
Font f = new Font(Font.SANS_SERIF, 3, 5);
Related Topics
Increasing Heap Space in Eclipse: (Java.Lang.Outofmemoryerror)
How to Use Multiple Scanner Objects on System.In
Programmatically Change Log Level in Log4J2
General Strategy to Resolve Java Memory Leak
Bufferedimage Not Being Cleared Before Each Rendering
How to Convert a Java Object (Bean) to Key-Value Pairs (And Vice Versa)
How to Define Multiple Jbutton Actions from a Different Class
Java Swing: How to Implement a Login Screen Before Showing a Jframe
Java, How to Implement a Shift Cipher (Caesar Cipher)
Java Fileoutputstream Create File If Not Exists
Java Singleton and Synchronization
How to Read Request.Getinputstream() Multiple Times
How to Pass Parameters to Anonymous Class
Is Calling Static Methods via an Object "Bad Form"? Why