编程语言
首页 > 编程语言> > java – 如何在JTextPane中为文本设置StrikeThrough和Underline样式选项?

java – 如何在JTextPane中为文本设置StrikeThrough和Underline样式选项?

作者:互联网

我有一个JTextPane组件,我正在尝试将用户键入的文本设置为同时加下划线和删除线.

应该将下一个类型字符的删除线属性设置为true的相关代码片段如下:

JEditorPane editor = getEditor(e);
if (editor != null) {
     StyledEditorKit kit = getStyledEditorKit(editor);
     MutableAttributeSet attr = kit.getInputAttributes();            
     SimpleAttributeSet sas = new SimpleAttributeSet();
     StyleConstants.setStrikeThrough(sas, true);                
     setCharacterAttributes(editor, sas, false);
}

这样可以将文本设置为删除线,但如果它已经设置为下划线,则会丢失下划线样式信息.仔细看看StyleConstants.setStrikeThrough(…)背后的实际代码我注意到下划线和删除线属性的CSS样式标签将是相同的(即“文本装饰”)并且当值更新时保存属性的哈希表,它将被覆盖.

这意味着代码如下:

StyleConstants.setStrikeThrough(sas, true);
StyleConstants.setUnderlineThrough(sas, true);

将导致下一个键入的字符加下划线而没有删除线.我检查了属性值,对于“text-decoration”属性,值是“下划线”,而我期待“直通,下划线”.

有谁知道如何以一个干净的Swing兼容方式实现这一目标?我的方法有问题吗?在JTextPane样式的核心是否存在一个潜在的假设,即文本不应该同时删除并强调下划线?

解决方法:

为什么不使用StyledDocument并使用两个样式:primary和secondary,其中primary是secondary的父样式:

  StyledDocument styleDocument =  jTextPane1.getStyledDocument();
  Style primaryStyle = styleDocument.addStyle("Primary", null);
  Style secondaryStyle = styleDocument.addStyle("Secondary", primaryStyle);


  StyleConstants.setFontFamily(primaryStyle, "American Captain");
  StyleConstants.setFontSize(primaryStyle, 24);

//  StyleConstants.setFontFamily(secondaryStyle, "Bira PERSONAL USE ONLY");
  StyleConstants.setFontSize(secondaryStyle, 20);
  StyleConstants.setForeground(primaryStyle, new Color(0x552AFF));
  StyleConstants.setForeground(secondaryStyle, Color.black);
  StyleConstants.setStrikeThrough(secondaryStyle, true);
  StyleConstants.setUnderline(primaryStyle, true);

  try {
      styleDocument.insertString(0, "Title with American Captain font\n\n", primaryStyle);
      styleDocument.insertString(styleDocument.getLength(), "Font demonstration with JTextPane. "
              + "Seriously, it is powerful and has the power to do all kind of styling with text. "
              + "check it out, check its mighty power and be embrassed\n", secondaryStyle);
   } catch (BadLocationException ex) {
                Logger.getLogger(JTextPaneTest.class.getName()).log(Level.SEVERE, null, ex);
   }

编辑:

imagine you have 4 toggle buttons – italic, bold, underline and
strikethrough. Each time one of those is pressed or unpressed I need
to adjust the styling as necessary for the character that will be
typed next.

是的,答案仍然在于使用DefaultStyleDocument并扩展它的偏好.上面的示例应该让我们了解在使用styleDocument.insertString(int offs,String str,AttributeSet a)方法插入字符串时样式的样式是如何工作的.当我们使用KeyBoard插入数据或复制粘贴时,总是会调用关联的StyleDocument的insertString函数.

因此,要像文本编辑器一样设置样式,您所要做的就是扩展DefaultStyleDocument并覆盖此insertString函数并传递所需的特定样式属性.

满足您的完整要求的演示示例应该清楚地说明这一点.

class CStyleDocument extends DefaultStyledDocument
{
    private  Style primaryStyle;

    public CStyleDocument() {
        super();
         primaryStyle = this.addStyle("Primary", null);
    }
    public Style getAttrStyle()
    {
        return primaryStyle;
    }

    @Override
    public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
        super.insertString(offs, str, primaryStyle); 

    }

}

public class JTextPaneTest extends javax.swing.JFrame {

    CStyleDocument styleDocument;

    public JTextPaneTest() {
        initComponents();

        styleDocument = new CStyleDocument();
        jTextPane1.setDocument(styleDocument);

}

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jTextPane1 = new javax.swing.JTextPane();
        jPanel1 = new javax.swing.JPanel();
        boldSelButton = new javax.swing.JToggleButton();
        ulSelButton = new javax.swing.JToggleButton();
        strkSelButton = new javax.swing.JToggleButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setMinimumSize(new java.awt.Dimension(400, 200));

        jScrollPane1.setViewportView(jTextPane1);

        getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);

        boldSelButton.setText("Bold");
        boldSelButton.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                boldSelButtonStateChanged(evt);
            }
        });
        jPanel1.add(boldSelButton);

        ulSelButton.setText("Under Lined");
        ulSelButton.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                ulSelButtonStateChanged(evt);
            }
        });
        jPanel1.add(ulSelButton);

        strkSelButton.setText("Strike Through");
        strkSelButton.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                strkSelButtonStateChanged(evt);
            }
        });
        jPanel1.add(strkSelButton);

        getContentPane().add(jPanel1, java.awt.BorderLayout.PAGE_START);

        pack();
    }// </editor-fold>                        

    private void boldSelButtonStateChanged(javax.swing.event.ChangeEvent evt) {                                           
             StyleConstants.setBold(styleDocument.getAttrStyle(), ((JToggleButton)evt.getSource()).isSelected());
             jTextPane1.requestFocus();




    }                                          

    private void ulSelButtonStateChanged(javax.swing.event.ChangeEvent evt) {                                         
        StyleConstants.setUnderline(styleDocument.getAttrStyle(), ((JToggleButton)evt.getSource()).isSelected());
        jTextPane1.requestFocus();
    }                                        

    private void strkSelButtonStateChanged(javax.swing.event.ChangeEvent evt) {                                           
       StyleConstants.setStrikeThrough(styleDocument.getAttrStyle(), ((JToggleButton)evt.getSource()).isSelected());
       jTextPane1.requestFocus();
    }                                          


    public static void main(String args[]) {

        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JTextPaneTest();
                frame.setVisible(true);

            }
        });
    }
    // Variables declaration - do not modify                     
    private javax.swing.JToggleButton boldSelButton;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextPane jTextPane1;
    private javax.swing.JToggleButton strkSelButton;
    private javax.swing.JToggleButton ulSelButton;
    // End of variables declaration                   
}

标签:jeditorpane,java,swing
来源: https://codeday.me/bug/20190825/1718278.html