Как изменить имя соответствующего шрифта в JCombobox при размещении курсора или выделении текста в JTextPane? - PullRequest
0 голосов
/ 05 ноября 2018

Я создаю приложение текстового редактора на Java Swing. Я использую JTextPane, и я добавил код, чтобы получить все системные шрифты и шрифты некоторых размеров в JComboBox.

Я ввел текст - «Hello World» в jtextpane и изменил шрифт слов «Hello» на «Arial», размер шрифта на 10 и «World» на «Calibri», размер шрифта на 12.

Мой ожидаемый сценарий: Если я выбираю слово «Hello» или помещаю курсор в слово «Hello», имя шрифта в шрифте JCombobox должно быть автоматически изменено на «Arial», а размер шрифта Jcombobox должен автоматически изменяться на 10, как и для слово «Мир», значения в Jcombobox должны быть изменены на «Calibri» и «12». Как мне этого добиться? Заранее спасибо.

1 Ответ

0 голосов
/ 06 ноября 2018

Это в основном решает проблему выбора элемента со списком, соответствующего выделенному тексту или позиции курсора в тексте. Для примера я выбрал только размер шрифта. Та же самая техника может быть применена и к семейству шрифтов.

Примером является текстовый редактор, использующий JTextPane, а его тип документа - DefaultStyledDocument. Существует JComboBox со списком размеров шрифта (от 16 до 50). Можно выбрать фрагмент текста в редакторе и выбрать размер шрифта в поле со списком, чтобы установить текст в этот размер шрифта. Это достигается с помощью ItemListener, добавленного к JComboBox. У слушателя есть код для установки атрибутов документа редактора для вновь выбранного размера шрифта - для выбранного текста.

Редактор допускает применение нескольких размеров шрифта к различным частям текста, как показано на рисунке ниже.

enter image description here


Требовалось, когда в текст или часть выделенного текста помещается каретка (или курсор) - соответствующий размер шрифта должен быть установлен в JComboBox с размерами шрифта. Для этого CaretListener добавляется к JTextPane.

Эта логика слушателя в основном находит позицию каретки, получает атрибуты текста документа в этой позиции и извлекает атрибут размера шрифта. Этот размер шрифта из этого атрибута задается в поле со списком размера шрифта.

Код примера:

public class Editor2 {

    private JTextPane editor;
    private DefaultStyledDocument doc;
    private JComboBox<String> fontSizeComboBox;
    private boolean caretControlFlag;
    private static final int DEFAULT_FONT_SIZE = 18;

    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));
        editor.addCaretListener(new MyCaretListener());     
        JScrollPane editorScrollPane = new JScrollPane(editor);
        doc = new DefaultStyledDocument();
        initDocAttrs();
        editor.setDocument(doc);

        final String [] fontSizes = {"Font Size", "16", "18", 
            "20", "24", "28", "30", "34", "40", "50"};
        fontSizeComboBox = new JComboBox<String>(fontSizes);
        fontSizeComboBox.setEditable(false);
        fontSizeComboBox.addItemListener(new FontSizeItemListener());
        JFrame frame = new JFrame("Text Editor");
        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, 18);
        StyleConstants.setFontFamily(style, "SansSerif");
        doc.setParagraphAttributes(0, doc.getLength(), style, true);
    }

    private class FontSizeItemListener implements ItemListener {
        @Override
        public void itemStateChanged(ItemEvent e) {
            if ((e.getStateChange() != ItemEvent.SELECTED) ||
                    (fontSizeComboBox.getSelectedIndex() == 0)) {
                return;
            }
            String fontSizeStr = (String) e.getItem();
            int newFontSize = 0;
            try {
                newFontSize = Integer.parseInt(fontSizeStr);
            }
            catch (NumberFormatException ex) {
                return;
            }
            if (caretControlFlag) {
                caretControlFlag = false;
                return;
            }
            setFontAttrs(newFontSize);
            editor.requestFocusInWindow();
        }

        private void setFontAttrs(int newFontSize) {
            SimpleAttributeSet attrs = new SimpleAttributeSet();
            Style docStyle = doc.getStyle("my_doc_style");  
            int size = StyleConstants.getFontSize(docStyle);
            StyleConstants.setFontSize(attrs, newFontSize);
            String attrName = "mysize" + Integer.toString(newFontSize);
            attrs.addAttribute(attrName, attrName);

            int startPos = editor.getSelectionStart();
            String selectedText = editor.getSelectedText();
            if (selectedText == null || selectedText.trim().isEmpty()) {
                return;
            }
            int length = selectedText.length(); 
            doc.setCharacterAttributes(startPos, length, attrs, false);     
            editor.setDocument(doc);
        }
    }


    private class MyCaretListener implements CaretListener {
        @Override
        public void caretUpdate(CaretEvent e) {
            caretControlFlag = true;
            int dot = e.getDot();
            Element ele = doc.getCharacterElement(dot);
            AttributeSet attrs = ele.getAttributes();
            String fontSizeStr = "18";
            for (Enumeration en = attrs.getAttributeNames(); en.hasMoreElements();) {
                String attrName = en.nextElement().toString();
                if (attrName.contains("mysize")) {
                    fontSizeStr = attrName.substring(6);
                }
            }
            fontSizeComboBox.setSelectedItem(fontSizeStr);
            caretControlFlag = false;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...