hor*_*tiu 3 java swing jeditorpane
我有一个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);
}
Run Code Online (Sandbox Code Playgroud)
这样可以将文本设置为删除线,但如果它已经设置为下划线,则会丢失下划线样式信息.仔细看看StyleConstants.setStrikeThrough(...)背后的实际代码我注意到下划线和删除线属性的CSS样式标记将是相同的(即"文本装饰"),并且当值更新时保存属性的哈希表,它将被覆盖.
这意味着代码如下:
StyleConstants.setStrikeThrough(sas, true);
StyleConstants.setUnderlineThrough(sas, true);
Run Code Online (Sandbox Code Playgroud)
将导致下一个键入的字符加下划线而没有删除线.我检查了属性值,对于"text-decoration"属性,值是"下划线",而我期待"直通,下划线".
有谁知道如何以一个干净的Swing兼容方式实现这一目标?我的方法有问题吗?在JTextPane样式的核心是否存在一个潜在的假设,即文本不应该同时删除并强调下划线?
为什么不使用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);
}
Run Code Online (Sandbox Code Playgroud)
编辑:
想象你有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
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1860 次 |
| 最近记录: |