JTextPane - a phrase with TWO styles
I just faced an interesting thing.
I was changing selected text style. The thing is when I change style for ONE WORD one by one it's fine but next if I select a whole styled phrase and change its font color the whole phrase becomes ONE styled (the first style within the selected text) only :(
Here is the problem snippet
private void setFontColorStyle()
{
JTextPane editor=this.getTextPane();
String text=this.getTextPane().getSelectedText();
StyledDocument doc=(StyledDocument) editor.getDocument();
int selectionEnd=this.getTextPane().getSelectionEnd();
int selectionStart=this.getTextPane().getSelectionStart();
Element element=doc.getCharacterElement(selectionStart);
AttributeSet as = element.getAttributes();
String family = StyleConstants.getFontFamily(as);
int fontSize = StyleConstants.getFontSize(as);
boolean isBold=StyleConstants.isBold(as);
boolean isItalic=StyleConstants.isItalic(as);
boolean isUnderlined=StyleConstants.isUnderline(as);
StyleContext context = new StyleContext();
Style style;
this.getTextPane().replaceSelection("");
style = context.addStyle("mystyle", null);
style.addAttribute(StyleConstants.FontSize, fontSize);
style.addAttribute(StyleConstants.FontFamily, family);
style.addAttribute(StyleConstants.Foreground, this.fontColor);
style.addAttribute(StyleConstants.Bold, isBold);
style.addAttribute(StyleConstants.Italic, isItalic);
style.addAttribute(StyleConstants.Underline, isUnderlined);
this.getTextPane().replaceSelection("");
try {
this.getTextPane().getStyledDocument().insertString(selectionEnd - text.length(), text, style);
} catch (BadLocationException ex) {
}
}
And here is the bold making method code... () Italic and underlined all the same logic so I guess it is quite clear
private void setFontB开发者_如何学JAVAoldStyle()
{
if(this.getTextPane().getSelectedText()!=null)
{
String text = this.getTextPane().getSelectedText();
int selectionStart=this.getTextPane().getSelectionStart();
int selectionEnd=this.getTextPane().getSelectionEnd();
StyleContext context = new StyleContext();
Style style;
Element element=doc.getCharacterElement(selectionStart);
Enumeration en=doc.getStyleNames();
AttributeSet as = element.getAttributes();
/**
* Get style from history...
*/
String family = StyleConstants.getFontFamily(as);
int fontSize = StyleConstants.getFontSize(as);
Color currentColor=StyleConstants.getForeground(as);
boolean isBold=StyleConstants.isBold(as)?false:true;
boolean isItalic=StyleConstants.isItalic(as);
boolean isUnderlined=StyleConstants.isUnderline(as);
String styleName=String.valueOf(Math.random());
style = context.addStyle(styleName, null);
// style.addAttribute(StyleConstants.FontSize, fontSize);
// style.addAttribute(StyleConstants.FontFamily, family);
style.addAttribute(StyleConstants.Foreground, currentColor);
style.addAttribute(StyleConstants.FontFamily, family);
style.addAttribute(StyleConstants.FontSize, fontSize);
style.addAttribute(StyleConstants.Bold, isBold);
style.addAttribute(StyleConstants.Italic, isItalic);
style.addAttribute(StyleConstants.Underline, isUnderlined);
this.getTextPane().replaceSelection("");
try {
this.getTextPane().getStyledDocument().insertString(selectionEnd - text.length(), text, style);
} catch (BadLocationException ex) {
}
}//if end...
}
Here is the bold method invokation code:
private void setFontBold()
{
this.setFontBoldStyle();
}
... and color method invokation
private void setFontColor(Color fontColor)
{
this.fontColor=fontColor;
this.setFontColorStyle();
}
... and action listeners (for bold)...
private void boldButtonActionPerformed(java.awt.event.ActionEvent evt) {
this.getTextPane().requestFocusInWindow();
this.setFontBold();
}
... and for color
private void colorButtonActionPerformed(java.awt.event.ActionEvent evt) {
this.getTextPane().requestFocusInWindow();
ColorDialog colorEditor=new ColorDialog();
//returns rgb color...
Color color=colorEditor.getSelectedColor(this.getDialog(), true,false);
if(color==null){
JOptionPane.showMessageDialog(this.getDialog(), "null color");
return;
}
this.setFontColor(color);
}
I dearly need your advice about how to keep selected text styles unchanged (like bold or font family) when I want to change a whole different styled selected text color for example?
To be more clear...
For example I have text
My Hello World is not pretty :)
Next I select the whole phrase and change its color from black to lets say red. Next text becomes red but the whole phrase becomes bold according to first style. But the thing is it would be interesting to keep bold and italic styles but at the same time have the phrase red :) So quite simple but I have just confused how to control more than one style in the frames of selected text area?
Any useful comment is much appreciated
TextComponentDemo
, discussed in How to Use Editor Panes and Text Panes, is a good example of how to manage this as well as other text component features.
Addendum: TextComponentDemo
relies on pre-defined Action
objects to handle editing tasks. Conveniently, StyledEditorKit
contains a series of nested classes that derive from StyledTextAction
. As a concrete example, here's how one might add an AlignmentAction
to the Style
menu of TextComponentDemo
in the method createStyleMenu()
:
protected JMenu createStyleMenu() {
JMenu menu = new JMenu("Style");
Action action = new StyledEditorKit.AlignmentAction(
"left-justify", StyleConstants.ALIGN_LEFT);
action.putValue(Action.NAME, "Left");
menu.add(action);
menu.addSeparator();
...
}
The remaining (arbitrary) alignment action names are defined privately in StyledEditorKit
.
Addendum: setCharacterAttributes()
is the common routine used by the nested editing actions. It invokes a method of the same name in StyledDocument
, as proposed by @StanislavL.
Addendum: I am unable to reproduce the effect you describe. When I set the color of the selection, the style attributes remain unchanged.
Addendum: The StyledEditorKit
actions work just as well with a JButton
or JToolBar
.
new JButton(new StyledEditorKit.ForegroundAction("Red", Color.red))
Use this.getTextPane().getStyledDocument().setCharacterAttributes()
精彩评论