Pressing Ctrl+A is changing the Font in JTextPane

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-25 01:06:08

问题


I am creating a simple Text editor using Java Swing with JTextPane component. I have added the code to make the text as Bold, Italics, Underline and also I have added code to get the system fonts in a JComboBox, so that I can change the font of the JTextPane content. And if the content has multiple font styles, it will display the corresponding font name according to the cursor position.

I have an issue: if the content has more than one font styles, pressing Ctrl+A is selecting all the content and also it is changing whole content font to the same font (which is the font style of the first line). Before pressing Ctrl+A:

After pressing Ctrl+A, the first line's font style - Calibri font is applied to all the three lines, below picture:

here is the simplest code

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("---");
        }
    }
}

Why pressing Ctrl+A is changing all the font style? can anyone help me on this?


回答1:


fontFamilyComboBox.setSelectedItem(fontFamilyStr);

In your CaretListener you are changing the selected item which results in the ActionListener for the combo box to be invoked, which causes you to change the font for the selected text.

One solution would be to remove the ActionListner from the combo box before changing the selected item:

comboBox.removeActionListener(...);
comboBox.setSelectedItem(fontFamilyStr);
comboBox.addActionListener(..)


来源:https://stackoverflow.com/questions/53219470/pressing-ctrla-is-changing-the-font-in-jtextpane

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!