Getting style from any offset in JTextPane - java

Is there a way to get Style, a style name or just even compare whether Style at a certain position of JTextPane with the style I gave the text when inserting? Because for my purpose I created custom JTextPane, StyledDocument and DocumentFilter. So I could choose Style to be used for say regular letters and another Style for numbers. I have also toggle button which while toggled sets DocumentFilter to format numbers differently and while not toggled numbers format regularly so at the end you can't distinguish which numbers have been affected just according to JTextPane's getText() method. Therefore the only way would be to compare styles which I have both regular and special number style as constants. Only thing I need to come up with is how to get Style for each character.
I know there is JTextPane's method to get AttributeSet from the caret's position called getCharacterAttributes() but I think it's no use for my issue.
Is it necessary to include code example? I don't think it's difficult to imagine. If you want me I will include it though.
Any input would be appreciated. Thanks!

Try calling StyledDocument.getCharacterElement(pos) to get the character element at that position and then call Element.getAttributes() to get its attribute set.
The AttributeSet contains styles which you can retrieve using methods provided by StyleConstants.

Related

How do I wrap text in a jTextPane?

I'm currently using a jTextArea, and that has a setLineWrap() method to indicate whether text should be wrapped or not. Do jTextPanes have an equivalent to this? I know it can wrap words, but I need it to wrap characters.
For example, "oooooooooooo..." should be wrapped and displayed as two or more lines of o's instead of one long line with a scroll bar. So is this possible with jTextPanes?
JTextPanes word wrap automatically, you have to set the size.
jTextPane.setSize(someValue);
The size should be set to something small.
But this doesn't help you because it doesn't do that with characters... Try using <br> maybe? Or check this link: http://java-sl.com/wrap.html

Obtaining an Apache POI XSSFRichTextString from a textbox

How do I get an XSSFRichTextString from an Textbox in an excel spreadsheet using POI?
The setText() method is overloaded to set either a String or XSSFRichTextString but the getText() method only returns a String.
My approaches were as follows:-
Change just the text in the textbox but leave the formatting unchanged. I was hoping to get the string and simply change the text but there seems to be no setText method in XSSFRichTextString. It appears that you set the text in the constructor then apply formatting using methods. Using this does put the text in the textbox but it loses all formatting.
Extract the entire XSSFRichTextString, extract the Formatting, create a new RTS with the new text and apply the formatting. The problem is that while there is a setFont(Font object) method the getFont() returns only a short so I cannot seem to get the Font object and change it.
3 My last option is to set the plain text in the Textbox and then programmatically set all the font and formatting elements but this means burying the formatting in the Java code which means re-coding if the user needs to tweak the format instead of just using Excel.
Any suggestions?
Promoting some comments to an answer
You can't get a RichTextString from an Excel textbox. The storage model for formatted text in a textbox was changed from that in plain cells, mostly it seems to support extra features and kinds of formatting. Textbox text is a bit more Word-like in how it's structured / stored
However, there's good news - you can do what you want, and change some specific text in a textbox without changing the formatting!
Firstly, from your XSSFTextBox, call getTextParagraphs() to get the paragraphs
Next, call getTextRuns() to get the individual runs of text sharing the same formatting. Search through those until you find the one(s) containing the text you want to change. Finally, call XSSFTextRun.setText(String) to change the text of that run. The formatting will be unchanged

How do I override the word wrap behavior of a JavaFX TextArea component?

I have created a new JavaFX component to be used for Braille input by extending the TextArea component. Unfortunately, the default word wrap behavior of a TextArea component will break to a new line right in the middle of several braille characters rather than breaking only at the spaces between words. I have tried searching for the methods that define the word wrap behavior in the TextArea component so I could override them, but I have not been able to find those methods.
How can I override this word wrap behavior so that line breaks will only be inserted at spaces?
I've had a play around with the default behaviour of a JavaFX TextArea. I used both the standard latin alphabet as well as Unicode characters. Both behaved the same.
With text wrap enabled, the default policy seems to be to break at the first space before the width of the area is exceeded. If a single "word" (any consecutive sequence of characters) is too long to fit within the width of the container, it will start on a newline, break at the width of the container and carry on to the next line. This is exactly what I would expect in this situation. You've told it you want to enforce text wrapping and if a word doesn't fit on a line, there's not a great deal it can do.
Anyway, a TextArea has a property wrapText which allows us to control whether this text wrapping will be added or not. Looking at where this value is used in the source code may give us some insight into how its used.
private static final CssMetaData<TextArea,Boolean> WRAP_TEXT =
new CssMetaData<TextArea,Boolean>("-fx-wrap-text",
StyleConverter.getBooleanConverter(), false) {
#Override
public boolean isSettable(TextArea n) {
return !n.wrapText.isBound();
}
#Override
public StyleableProperty<Boolean> getStyleableProperty(TextArea n) {
return (StyleableProperty<Boolean>)(WritableValue<Boolean>)n.wrapTextProperty();
}
};
Effectively what's happening here is that this boolean property is being bound to a CSS property -fx-wrap-text. This CSS property only takes a boolean argument - text wrap is either on or off, there are no alternative modes. We can then presume that CSS property is being used by the renderer to enforce the text wrap policy. This is way too low-level to bother about overriding.
To solve your problem, I would turn text wrap off and set up a listener to the textProperty() of your TextArea. When the text changes, insert newlines yourself at whatever places you deem appropriate.

Highlighting specific instances of a string for output to TextArea

I have a search function that scrolls through a String and finds specific instances of a substring and then notes the index for the location of the substring.
For example, if I'm trying to find the String
"AATACG"
in the string
"TACGATCAATACGACGATCAGT",
it will return 7 as the index of the substring. What I need is a way to color the substring. So, the return text will be
"TACGATCAATACGACGATCAGT",
but with the substring colored. The text is outputted to a JavaFX TextArea.
I've tried using ANSI codes (which didn't work); I've also tried changing the string into a Text object and setting the fill color/applying a CSS id, but I can't find a way to change the Text back into a String with the color change remaining.
Is there a way to do this? Any help is much appreciated.
How about using javafx.scene.text.TextFlow? Seems like you want to highlight text without editing it. In this case TextFlow is appropriate component.

Making words different colors in JTextField/JTextPane/?

I'm trying and failing to understand how to use Java's text editor components to colorize text as you insert it. I don't want or need a fully featured syntax highlighting library.
Basically, I have a JTextField (or some other JText... component), and a list of words. I want any words in the field that appear in the list to be red, and the rest of the words be green. So for example, if "fire" is in the list, "fir" would appear green and "fire" would appear red.
I've tried using a JTextPane and a DefaultStyledDocument, using a KeyListener to go over the text in the document and using AbstractStyledDocument.replace to replace the existing words with versions that have the correct attributes. This didn't do anything. What am I doing wrong?
Neither JTextPane nor JTextField isn't able to present formatted text, i.e text having more than one format. For text-editor-like capabilities like you'd find in WordPad or HTML, the component to use is the JEditorPane or its descendant, JTextPane.
The simplest thing you can do is set the ContentType of the JEditorPane to "text/html" and simply set its text to a string containing HTML. The Java structured text components are surprisingly competent with HTML; you can display tables and/or DIVs, and there is support for much of CSS2. Simplest to do your styles inline, but you can even do external style hrefs.
If you want to get fancy programmatically, you can access the DocumentModel and create text from spans of text each having their own formatting. The DocumentModel works essentially like a programmable text editor.
EDIT: Re-reading your question, I see my answer doesn't quite address it. Since you want multi-colored text JEditorPane is your only option; but rather than just piping in pre-colored text via HTML or such, you'll have to put a listener on your document model to catch changes introduced when you type; and after every document change you'll want to examine the text (again from the Document model) for text that should or should not be highlighted, and you'll want to apply formatting to certain runs of text.
There are devils in the details, but this should get you started.

Categories