AbiSaran
AbiSaran

Reputation: 2678

Text style and format is getting changed while converting to Uppercase or Lowercase in JTextPane

I am creating a simple RTF document editor. I have added code to create a new RTF document, open RTF document, save document and other formatting functionalities like Bold, Italics, Underline and Change Case (UpperCase to LowerCase and vice versa). I am using JTextPane component.

My problem: While the content of JTextPane contains different fonts and different font size with different colors, if I select all the content and select the 'UPPERCASE' menu option, the content is changing to uppercase, but all the different font, font size and colors are changing to same font, same font size and same color, verify the images: Before converting to Uppercase:

enter image description here

selecting all the content and choosing 'UPPERCASE' option:

enter image description here

after converting to Uppercase:

enter image description here

How can I resolve this? thanks in advance. Minimal code:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.JToolBar;
import javax.swing.UIManager;
import javax.swing.text.AttributeSet;
import javax.swing.text.Document;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.Style;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
import javax.swing.text.rtf.RTFEditorKit;

public class MyNotepadMini implements ActionListener {
    public JFrame frame;
    public JPanel panel;
    public JTextPane textPane;
    public RTFEditorKit rtf;
    public StyleContext styleContext;
    public Document document;
    public JScrollPane scrollPane;
    public JToolBar toolBar;
    public StyledDocument styledDocument;
    public Style defaultStyle;
    public AttributeSet attrs;
    public Style style;
    public MutableAttributeSet mas;
    public JButton lowerAndUpperCaseBtn;
    public JPopupMenu popupMenu;
    public JMenuItem lowerCaseMI;
    public JMenuItem upperCaseMI;
    public SimpleAttributeSet simpleAttrs;

    public MyNotepadMini() {
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
        } catch (Exception e) {
            e.printStackTrace();
        }

        frame = new JFrame("My Wordpad");
        panel = new JPanel(new BorderLayout());              
        toolBar = new JToolBar();
        toolBar.setBounds(0,0,100,30);

        rtf = new RTFEditorKit();
        textPane = new JTextPane();
        textPane.setEditorKit(rtf);
        textPane.setMargin(new Insets(10,5,5,5));
        styleContext = new StyleContext();
        mas = textPane.getInputAttributes();
        simpleAttrs = new SimpleAttributeSet();
        styledDocument = textPane.getStyledDocument();
        textPane.setDocument(styledDocument);

        scrollPane = new JScrollPane();
        scrollPane.getViewport().add(textPane);

        lowerAndUpperCaseBtn = new JButton("Change Case");
        lowerAndUpperCaseBtn.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent me) {
                int startPosition = 0;
                int endPosition = 0;
                if ((textPane.getSelectionStart() != textPane.getSelectionEnd())) {
                    startPosition = textPane.getSelectionStart();
                    endPosition = textPane.getSelectionEnd();
                    textPane.setSelectionStart(startPosition);
                    textPane.setSelectionEnd(endPosition);
                    textPane.getCaret().setSelectionVisible(true);
                }
            }
        });
        popupMenu = new JPopupMenu();
        lowerCaseMI = new JMenuItem("lowercase");
        upperCaseMI = new JMenuItem("UPPERCASE");
        popupMenu.add(lowerCaseMI);
        popupMenu.add(upperCaseMI);

        lowerAndUpperCaseBtn.addActionListener(this);
        lowerCaseMI.addActionListener(this);
        upperCaseMI.addActionListener(this);

        toolBar.setFloatable(false);        
        toolBar.add(lowerAndUpperCaseBtn);
        toolBar.setBackground(Color.WHITE);
        scrollPane.setPreferredSize(new Dimension(600,400));

        textPane.setFont(new Font("Arial", Font.PLAIN, 12));
        textPane.setInheritsPopupMenu(true);
        panel.add(toolBar, BorderLayout.NORTH);
        panel.add(scrollPane, BorderLayout.CENTER);
        panel.add(new JLabel(" "), BorderLayout.EAST);
        panel.add(new JLabel(" "), BorderLayout.WEST);
        panel.add(new JLabel(" "), BorderLayout.SOUTH);

        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        textPane.requestFocus();                
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new MyNotepadMini();
    }

    public void actionPerformed(ActionEvent ae) {
        if (ae.getSource() == lowerAndUpperCaseBtn) {                                               
            popupMenu.show(lowerAndUpperCaseBtn, 0, lowerAndUpperCaseBtn.getBounds().height);
        } else if (ae.getSource() == lowerCaseMI) { 
            boolean lowerCaseFlag = false;
            int startPosition = 0;
            int endPosition = 0;
            try {
                if ((textPane.getSelectionStart() != textPane.getSelectionEnd()) && (!lowerCaseFlag)) {
                    startPosition = textPane.getSelectionStart();
                    endPosition = textPane.getSelectionEnd();
                    System.out.println("Selected text: " + textPane.getSelectedText());
                    textPane.replaceSelection(textPane.getSelectedText().toLowerCase());
                    textPane.setSelectionStart(startPosition);
                    textPane.setSelectionEnd(endPosition);
                    textPane.getCaret().setSelectionVisible(true);
                    lowerCaseFlag = true;
                }
                lowerAndUpperCaseBtn.setFocusable(false);
                textPane.requestFocus();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (ae.getSource() == upperCaseMI) {
            boolean upperCaseFlag = false;
            int startPosition = 0;
            int endPosition = 0;
            try {
                if ((textPane.getSelectionStart() != textPane.getSelectionEnd()) && (!upperCaseFlag)) {
                    startPosition = textPane.getSelectionStart();
                    endPosition = textPane.getSelectionEnd();
                    System.out.println("Selected text: " + textPane.getSelectedText());
                    textPane.replaceSelection(textPane.getSelectedText().toUpperCase());
                    textPane.setSelectionStart(startPosition);
                    textPane.setSelectionEnd(endPosition);
                    textPane.getCaret().setSelectionVisible(true);
                    upperCaseFlag = true;
                }
                lowerAndUpperCaseBtn.setFocusable(false);
                textPane.requestFocus();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } 
    }
}

Upvotes: 0

Views: 693

Answers (1)

Sharcoux
Sharcoux

Reputation: 6105

When you replace the selection with textPane.replaceSelection, the selected text is removed, and then a new text is added, using the current input style.

To achieve what you want, you need to update the character attributes of the selection by using the method setCharacterAttributes provided by the Document.

Upvotes: 1

Related Questions