【问题标题】:JTextPane - a phrase with TWO stylesJTextPane - 具有两种样式的短语
【发布时间】:2011-11-29 06:27:48
【问题描述】:

我刚刚遇到了一件有趣的事情。

我正在更改选定的文本样式。问题是,当我一个一个地更改 ONE WORD 的样式时,这很好,但是接下来如果我选择一个完整样式的短语并更改其字体颜色,整个短语将变为 ONE 样式(所选文本中的第一个样式 ) 仅 :(

这里是sn-p的问题

  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) {

        }
    }

这里是加粗的制作方法代码... () 斜体和下划线都是相同的逻辑,所以我想它很清楚

private void setFontBoldStyle()
    {
         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...


    }

下面是粗体的方法调用代码:

private void setFontBold()
    {
        this.setFontBoldStyle(); 
    }

...和颜色方法调用

 private void setFontColor(Color fontColor)
    {
        this.fontColor=fontColor;
        this.setFontColorStyle();

    }

...和动作监听器(粗体)...

 private void boldButtonActionPerformed(java.awt.event.ActionEvent evt) {                                           
         this.getTextPane().requestFocusInWindow();
         this.setFontBold();
    }                                          

...对于颜色

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);
    }                                           

例如,当我想更改完全不同样式的选定文本颜色时,我非常需要您关于如何保持选定文本样式不变(如粗体或字体系列)的建议?

为了更清楚...

例如我有文字

我的 你好 世界不漂亮:)

接下来我选择整个短语并将其颜色从黑色更改为红色。下一个文本变为红色,但整个短语根据第一种样式变为粗体。但问题是保持粗体和斜体样式但同时使用红色短语会很有趣:) 非常简单但我只是混淆了如何在所选文本区域的框架中控制多个样式?

非常感谢任何有用的评论

【问题讨论】:

  • 考虑创建并发布SSCCE,以便我们修改和测试您的代码。
  • 不知道!这个问题很好。 +1
  • 一个不好的解决方案可能是逐个字符添加新属性。
  • Emm... 这就是整个 JButton actionPerformed 方法体。我刚刚编辑了 sn-p 请看一下
  • 同样,SSCCE 会比 sn-p 或整个代码更好。请阅读链接。如果您没有很快得到一个体面的答案,您可以考虑创建并发布其中之一,因为它会增加您获得良好帮助的机会。

标签: java swing


【解决方案1】:

TextComponentDemo(在How to Use Editor Panes and Text Panes 中讨论过)是一个很好的示例,说明了如何管理此功能以及其他文本组件功能。

附录:TextComponentDemo 依赖于预定义的 Action 对象来处理编辑任务。方便的是,StyledEditorKit 包含一系列从StyledTextAction 派生的嵌套类。作为一个具体的例子,下面是如何在方法createStyleMenu() 中将AlignmentAction 添加到TextComponentDemoStyle 菜单中:

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();
    ...
}

其余(任意)对齐动作名称在StyledEditorKit中私下定义。

附录:setCharacterAttributes() 是嵌套编辑操作使用的常用例程。它调用@StanislavL 提议的StyledDocument 中的同名方法。

附录:我无法重现您描述的效果。当我设置选择的颜色时,样式属性保持不变。

附录:StyledEditorKit 操作与 JButtonJToolBar 一样有效。

new JButton(new StyledEditorKit.ForegroundAction("Red", Color.red))

【讨论】:

  • 教程读了很多遍,没有找到任何提示。如果我错过了什么,请指出我。
  • 我也看了sn-p。事情不在于“使文本向左对齐”或仅一次,而是如果只是选择所有文本并将其设为“绿色”,如何保持对齐。我看了很多例子,但没有一个显示如何在需要时保留样式历史:(也许问题是在选定文本的框架中逐个更改样式符号,但我不确定如何:(实际上这就是我问这个问题的原因。
  • 在使用编辑器工具包动作的示例中,更改任何属性都会使其余属性保持不变。为什么不使用它们?
  • Emm 因为事情不是完全逐字更改而是选择整个短语(n 字长)并将其设置为绿色但同时保持其粗体或斜体样式。
  • IIUC,这正是示例中的操作的行为方式。
【解决方案2】:

使用 this.getTextPane().getStyledDocument().setCharacterAttributes()

【讨论】:

  • 你的意思是逐个字符获取?
  • 你的意思是用一种风格得到一个字符?但那怎么办?
猜你喜欢
  • 2018-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-10
  • 1970-01-01
  • 2019-03-18
  • 1970-01-01
相关资源
最近更新 更多