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