按 Ctrl+A 正在更改 JTextPane 中的字体
Pressing Ctrl+A is changing the Font in JTextPane
我正在使用 Java Swing 和 JTextPane 组件创建一个简单的文本编辑器。我添加了使文本成为粗体、斜体、下划线的代码,并且还添加了代码以在 JComboBox 中获取系统字体,以便我可以更改 JTextPane 内容的字体。并且如果内容有多种字体样式,会根据光标位置显示对应的字体名称。
我有一个问题:如果内容有多种字体样式,按 Ctrl+A 会选择所有内容,并且会将整个内容字体更改为相同的字体(这是第一个的字体样式线)。在按下 Ctrl+A 之前:
按Ctrl+A后,第一行的字体样式-Calibri字体应用于所有三行,如下图:
这是最简单的代码
import java.awt.BorderLayout;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledEditorKit;
import javax.swing.text.rtf.RTFEditorKit;
public class Editor2 {
private JTextPane editor;
private DefaultStyledDocument doc;
private DefaultComboBoxModel<String> fontFamilyComboBoxModel;
private JComboBox<String> fontSizeComboBox;
private JComboBox<String> fontFamilyComboBox;
private AttributeSet attrs;
private String fontFamilyStr;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Editor2().createAndShowGUI();
}
});
}
private void createAndShowGUI() {
editor = new JTextPane();
editor.setMargin(new Insets(5, 5, 5, 5));
RTFEditorKit rtf = new RTFEditorKit();
editor.setEditorKit(rtf);
editor.addCaretListener(new MyCaretListener());
JScrollPane editorScrollPane = new JScrollPane(editor);
doc = new DefaultStyledDocument();
initDocAttrs();
editor.setDocument(doc);
final String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
fontFamilyComboBoxModel = new DefaultComboBoxModel<>(fonts);
fontFamilyComboBox = new JComboBox<String>(fontFamilyComboBoxModel);
fontFamilyComboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
String name = (String) fontFamilyComboBox.getSelectedItem();
new StyledEditorKit.FontFamilyAction("font-family-" + name, name).actionPerformed(ae);
editor.requestFocus();
}
});
final String[] fontSizes = { "Font Size", "10", "11", "12", "14", "16", "18", "20", "24", "28", "30", "34",
"40", "50" };
fontSizeComboBox = new JComboBox<String>(fontSizes);
fontSizeComboBox.setEditable(false);
JFrame frame = new JFrame("Text Editor");
frame.add(fontFamilyComboBox, BorderLayout.SOUTH);
frame.add(fontSizeComboBox, BorderLayout.NORTH);
frame.add(editorScrollPane, BorderLayout.CENTER);
frame.add(editorScrollPane);
frame.setSize(800, 400);
frame.setLocation(300, 150);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
editor.requestFocusInWindow();
}
private void initDocAttrs() {
Style style = doc.addStyle("my_doc_style", null);
StyleConstants.setFontSize(style, 12);
StyleConstants.setFontFamily(style, "Arial");
doc.setParagraphAttributes(5, doc.getLength(), style, true);
}
private class MyCaretListener implements CaretListener {
@Override
public void caretUpdate(CaretEvent e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
attrs = ((StyledEditorKit) editor.getEditorKit()).getInputAttributes();
System.out.println(attrs);
fontFamilyStr = (String) attrs.getAttribute(StyleConstants.FontFamily);
System.out.println("Font: " + fontFamilyStr);
fontFamilyComboBox.setSelectedItem(fontFamilyStr);
}
});
System.out.println("---");
}
}
}
为什么按Ctrl+A会改变所有的字体样式?谁能帮我解决这个问题?
fontFamilyComboBox.setSelectedItem(fontFamilyStr);
在您的 CaretListener
中,您正在更改所选项目,这会导致调用组合框的 ActionListener
,这会导致您更改所选文本的字体。
一种解决方案是在更改所选项目之前从组合框中删除 ActionListner:
comboBox.removeActionListener(...);
comboBox.setSelectedItem(fontFamilyStr);
comboBox.addActionListener(..)
我正在使用 Java Swing 和 JTextPane 组件创建一个简单的文本编辑器。我添加了使文本成为粗体、斜体、下划线的代码,并且还添加了代码以在 JComboBox 中获取系统字体,以便我可以更改 JTextPane 内容的字体。并且如果内容有多种字体样式,会根据光标位置显示对应的字体名称。
我有一个问题:如果内容有多种字体样式,按 Ctrl+A 会选择所有内容,并且会将整个内容字体更改为相同的字体(这是第一个的字体样式线)。在按下 Ctrl+A 之前:
按Ctrl+A后,第一行的字体样式-Calibri字体应用于所有三行,如下图:
这是最简单的代码
import java.awt.BorderLayout;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledEditorKit;
import javax.swing.text.rtf.RTFEditorKit;
public class Editor2 {
private JTextPane editor;
private DefaultStyledDocument doc;
private DefaultComboBoxModel<String> fontFamilyComboBoxModel;
private JComboBox<String> fontSizeComboBox;
private JComboBox<String> fontFamilyComboBox;
private AttributeSet attrs;
private String fontFamilyStr;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Editor2().createAndShowGUI();
}
});
}
private void createAndShowGUI() {
editor = new JTextPane();
editor.setMargin(new Insets(5, 5, 5, 5));
RTFEditorKit rtf = new RTFEditorKit();
editor.setEditorKit(rtf);
editor.addCaretListener(new MyCaretListener());
JScrollPane editorScrollPane = new JScrollPane(editor);
doc = new DefaultStyledDocument();
initDocAttrs();
editor.setDocument(doc);
final String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
fontFamilyComboBoxModel = new DefaultComboBoxModel<>(fonts);
fontFamilyComboBox = new JComboBox<String>(fontFamilyComboBoxModel);
fontFamilyComboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
String name = (String) fontFamilyComboBox.getSelectedItem();
new StyledEditorKit.FontFamilyAction("font-family-" + name, name).actionPerformed(ae);
editor.requestFocus();
}
});
final String[] fontSizes = { "Font Size", "10", "11", "12", "14", "16", "18", "20", "24", "28", "30", "34",
"40", "50" };
fontSizeComboBox = new JComboBox<String>(fontSizes);
fontSizeComboBox.setEditable(false);
JFrame frame = new JFrame("Text Editor");
frame.add(fontFamilyComboBox, BorderLayout.SOUTH);
frame.add(fontSizeComboBox, BorderLayout.NORTH);
frame.add(editorScrollPane, BorderLayout.CENTER);
frame.add(editorScrollPane);
frame.setSize(800, 400);
frame.setLocation(300, 150);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
editor.requestFocusInWindow();
}
private void initDocAttrs() {
Style style = doc.addStyle("my_doc_style", null);
StyleConstants.setFontSize(style, 12);
StyleConstants.setFontFamily(style, "Arial");
doc.setParagraphAttributes(5, doc.getLength(), style, true);
}
private class MyCaretListener implements CaretListener {
@Override
public void caretUpdate(CaretEvent e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
attrs = ((StyledEditorKit) editor.getEditorKit()).getInputAttributes();
System.out.println(attrs);
fontFamilyStr = (String) attrs.getAttribute(StyleConstants.FontFamily);
System.out.println("Font: " + fontFamilyStr);
fontFamilyComboBox.setSelectedItem(fontFamilyStr);
}
});
System.out.println("---");
}
}
}
为什么按Ctrl+A会改变所有的字体样式?谁能帮我解决这个问题?
fontFamilyComboBox.setSelectedItem(fontFamilyStr);
在您的 CaretListener
中,您正在更改所选项目,这会导致调用组合框的 ActionListener
,这会导致您更改所选文本的字体。
一种解决方案是在更改所选项目之前从组合框中删除 ActionListner:
comboBox.removeActionListener(...);
comboBox.setSelectedItem(fontFamilyStr);
comboBox.addActionListener(..)