我有一个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);将导致下一个类型字符在下划线上划线而不被删除。我已经检查了属性值,对于“文本-装饰”属性,值是“下划线”,而我期待的是“贯穿线,下划线”。
有谁知道如何以一种干净的挥杆柔顺的方式实现这一点吗?我的方法有什么问题吗?在JTextPane样式设计的核心是否有一个基本假设,即文本不应该同时划线和下划线?
发布于 2013-11-25 22:44:22
为什么不使用StyledDocument并使用两个Style: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);
}编辑:
想象一下你有4个按钮-斜体,粗体,下划线和划线。每次其中一个是按下或取消,我需要调整样式为必要的字符,将键入下。
是的,答案仍然是使用和扩展DefaultStyleDocument的偏好。上面的示例应该给出使用Style的样式是如何工作的,同时用styleDocument.insertString(int offs, String str, AttributeSet a)方法插入字符串。当我们使用KeyBoard或copy-paste插入数据时,总是调用关联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
}https://stackoverflow.com/questions/20204809
复制相似问题