Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1071
  • Last Modified:

JTextPane font

Hi,
I'm trying to display a JTextPane that can change its font, characters size and style (bold/ italic/ underlined) by pressing a button.
I've tried using the method getAction of textPane and it works fine for changing the characters size and style but I can not change the font type this way, because Actions of JTextPane are very limited (only Serif, Monospaced and SansSerif.
Is there another way to change the font types?
I don't want to use setFont() of JTextPane because it changes the font of all of the text in the TextPane and I want to use different fonts on the text.
Thanks,
ofrit
0
ofritha
Asked:
ofritha
  • 9
  • 5
1 Solution
 
allelopathCommented:
The O'Reilly swing book has an example a JTextPane with different fonts, maybe it will help you.

// StyleFrame.java
// A JTextPane with a menu for Style manipulation.

import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.*;

public class StyleFrame extends JFrame implements ActionListener {

  protected StyleBox styleBox;
  protected JTextPane textPane;
  protected JMenuBar menuBar;
  protected JMenu applyStyleMenu, modifyStyleMenu;
  protected JMenuItem createItem;

  public StyleFrame() {
    super("StyleFrame");

    styleBox = new StyleBox();
    textPane = new JTextPane();
    getContentPane().add(new JScrollPane(textPane), BorderLayout.CENTER);

    // set up menu
    menuBar = new JMenuBar();
    JMenu styleMenu = new JMenu("Style");
    menuBar.add(styleMenu);
    setJMenuBar(menuBar);

    applyStyleMenu = new JMenu("Set Logical Style");
    applyStyleMenu.setToolTipText(
        "set the Logical Style for the paragraph at caret location");
    styleMenu.add(applyStyleMenu);

    modifyStyleMenu = new JMenu("Modify Style");
    modifyStyleMenu.setToolTipText(
        "redefine a named Style (will affect paragraphs using that style)");
    styleMenu.add(modifyStyleMenu);

    createItem = new JMenuItem("Create New Style");
    createItem.setToolTipText(
        "define a new Style (which can then be applied to paragraphs)");
    createItem.addActionListener(this);
    styleMenu.add(createItem);

    // add the default style to applyStyleMenu and modifyStyleMenu
    createMenuItems(StyleContext.DEFAULT_STYLE);
  }

  protected void createMenuItems(String styleName) {
    // add 'styleName' to applyStyleMenu and modifyStyleMenu
    JMenuItem applyItem = new JMenuItem(styleName);
    applyItem.addActionListener(this);
    applyStyleMenu.add(applyItem);

    JMenuItem modifyItem = new JMenuItem(styleName);
    modifyItem.addActionListener(this);
    modifyStyleMenu.add(modifyItem);
  }

  public void actionPerformed(ActionEvent e) {
    // determine which menuItem was invoked and process it
    JMenuItem source = (JMenuItem)e.getSource();

    if ( applyStyleMenu.isMenuComponent(source) ) {
      // apply an existing style to the paragraph at the caret position
      String styleName = source.getActionCommand();
      Style style = textPane.getStyle(styleName);
      textPane.setLogicalStyle(style);
    }

    if ( source == createItem ) {
      // define a new Style and add it to the menus
      styleBox.clear();
      int response = JOptionPane.showConfirmDialog(this, styleBox,
          "Style Editor", JOptionPane.OK_CANCEL_OPTION,
          JOptionPane.PLAIN_MESSAGE);
      if (response == JOptionPane.OK_OPTION &&
styleBox.getStyleName().length() > 0) {
        String styleName = styleBox.getStyleName();
        Style style = textPane.addStyle(styleName, null);
        styleBox.fillStyle(style);
        createMenuItems(styleName); // add new Style to the menus
      }  
    }

    if ( modifyStyleMenu.isMenuComponent(source) ) {
      // redefine a Style (will automatically redraw paragraphs using Style)
      String styleName = source.getActionCommand();
      Style style = textPane.getStyle(styleName);
      styleBox.loadFromStyle(style);
      int response = JOptionPane.showConfirmDialog(this, styleBox,
          "Style Editor", JOptionPane.OK_CANCEL_OPTION,
          JOptionPane.PLAIN_MESSAGE);
      if (response == JOptionPane.OK_OPTION) styleBox.fillStyle(style);
    }
  }

  public static void main(String[] args) {
    JFrame frame = new StyleFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400, 300);
    frame.setVisible(true);
  }
}
0
 
OviCommented:
       String name = "a - font - family";
        new StyledEditorKit.FontFamilyAction("font-family-" + name, name).actionPerformed('a dummy action event');
0
 
OviCommented:
will work on a selected text. The font family names are more that you are writing there, are all installed font families in the cient os.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
ofrithaAuthor Commented:
Hi allelopath and Ovi,
I've tried your suggestions but did not manage to get the results I was looking for.

allelopath - The solution your code gives me is to change the font of all of the text and not just of the selected parts.

Ovi - I did not find a way to use your code.
Can you suggest a way to plant it in a program.

Thanks,
ofrit
0
 
OviCommented:
Just wait ...
0
 
OviCommented:
package tests.swing.text;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.StyledEditorKit;

public class ChangingFonts {
     public static void main(String[] args) {
          JFrame f = new JFrame();
          final JTextPane pane = new JTextPane();

          JPanel actions = new JPanel();
          String[] fArray = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
          final JComboBox fonts = new JComboBox(fArray);
          fonts.addActionListener(new ActionListener() {
               public void actionPerformed(ActionEvent ae) {
                    String name = fonts.getSelectedItem().toString();
                    new StyledEditorKit.FontFamilyAction("font-family-" + name, name).actionPerformed(ae);
                    pane.requestFocus();
               }
          });
          actions.add(new JLabel("Available fonts: "));
          actions.add(fonts);

          //  THIS IS WORKING TOO          
          //          JButton change = new JButton("Change");
          //          change.addActionListener(new ActionListener() {
          //               public void actionPerformed(ActionEvent ae) {
          //                    String name = fonts.getSelectedItem().toString();
          //                    new StyledEditorKit.FontFamilyAction("font-family-" + name, name).actionPerformed(ae);
          //                    pane.requestFocus();
          //               }
          //          });
          //          actions.add(change);

          Container c = f.getContentPane();
          c.setLayout(new BorderLayout());
          c.add(actions, BorderLayout.NORTH);
          c.add(new JScrollPane(pane), BorderLayout.CENTER);
          f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          f.setSize(600, 500);
          f.setVisible(true);
     }
}
0
 
ofrithaAuthor Commented:
Hi Ovi,
It worked great, but I have one problem with this solution.
I'm working with 2 JTextPanes and I need both of them to use the chosen font. I do not succeed to make them both refer to the font.
How do I link another JTextPane (for example pane2) to the font chosen in the JComboBox?
Thanks,
ofrit.
0
 
OviCommented:
wait a little ...
0
 
OviCommented:
package tests.swing.text;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.UIManager;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledEditorKit;

public class ChangingFonts {
      public static void main(String[] args) {
            JFrame f = new JFrame();
            final JTextPane pane1 = new JTextPane();
            final JTextPane pane2 = new JTextPane();
            final JTextPane pane3 = new JTextPane();
            final JTextPane pane4 = new JTextPane();
            final List editors = new ArrayList();
            editors.add(pane1);
            editors.add(pane2);
            editors.add(pane3);
            editors.add(pane4);
            final MultiEditorFontFamilyAction fontFamilyAction = new MultiEditorFontFamilyAction(editors, "", "");

            JPanel actions = new JPanel();
            String[] fArray = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
            final JComboBox fonts = new JComboBox(fArray);
            fonts.addActionListener(new ActionListener() {
                  public void actionPerformed(ActionEvent ae) {
                        String name = fonts.getSelectedItem().toString();
                        fontFamilyAction.setFamily("font-family-" + name, name);
                        fontFamilyAction.actionPerformed(ae);
//                        new StyledEditorKit.FontFamilyAction("font-family-" + name, name).actionPerformed(ae);
//                        pane.requestFocus();
                  }
            });
            actions.add(new JLabel("Available fonts: "));
            actions.add(fonts);
            
            JPanel editorsPanel = new JPanel();
            editorsPanel.setLayout(new GridLayout(1, 4, 5, 5));
            editorsPanel.add(new JScrollPane(pane1));
            editorsPanel.add(new JScrollPane(pane2));
            editorsPanel.add(new JScrollPane(pane3));
            editorsPanel.add(new JScrollPane(pane4));

            //  THIS IS WORKING TOO            
            //            JButton change = new JButton("Change");
            //            change.addActionListener(new ActionListener() {
            //                  public void actionPerformed(ActionEvent ae) {
            //                        String name = fonts.getSelectedItem().toString();
            //                        new StyledEditorKit.FontFamilyAction("font-family-" + name, name).actionPerformed(ae);
            //                        pane.requestFocus();
            //                  }
            //            });
            //            actions.add(change);

            Container c = f.getContentPane();
            c.setLayout(new BorderLayout());
            c.add(actions, BorderLayout.NORTH);
            c.add(editorsPanel, BorderLayout.CENTER);
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setSize(600, 500);
            f.setVisible(true);
      }

}

class MultiEditorFontFamilyAction extends StyledEditorKit.FontFamilyAction {
      private List editorPanes;
      private String family;
      
      public MultiEditorFontFamilyAction(List editors, String nm, String family) {
            super(nm, family);
            editorPanes = editors;
            this.family = family;
      }
      
      public void setFamily(String nm, String family) {
            this.family = family;
            putValue(Action.NAME, nm);
      }

      public void actionPerformed(ActionEvent e) {
            for (int i = 0; i < editorPanes.size(); i++) {
                  JEditorPane editor = (JEditorPane) editorPanes.get(i);
                  if (editor != null) {
                        String family = this.family;
                        if ((e != null) && (e.getSource() == editor)) {
                              String s = e.getActionCommand();
                              if (s != null) {
                                    family = s;
                              }
                        }
                        if (family != null) {
                              MutableAttributeSet attr = new SimpleAttributeSet();
                              StyleConstants.setFontFamily(attr, family);
                              setCharacterAttributes(editor, attr, false);
                        } else {
                              UIManager.getLookAndFeel().provideErrorFeedback(editor);
                        }
                  }
            }
      }
}
0
 
OviCommented:
Note: the focus is not returning right now to the last edited  JtextPane. You should implement yourself the logic for managing focus via focus listeners to track the last one.
0
 
ofrithaAuthor Commented:
Hi Ovi,
Although your suggestion worked fine when I used it as is in a program (both in j2sdk 1.4.1 and JBuilder 1.2), when I tried to combine it to my program it gives me an error when using J2sdk 1.4.1 and when I use the JBuilder 1.2 it does not give me any error.
The error is:
java.lang.NullPointerException
at javax.swing.plaf.basic.BasicPopupMenuUI$MouseGrabber.grabContainer(BasicPopupMenuUI.java.344)

and so on...
Any idea why this error occurs on the jdk 1.4.1?

Thanks,
ofrit
0
 
OviCommented:
This is an error from your code, and not mine ... Try to look at how your menus are created and used. In which contextyou receive this error? When you click on a menu entry, when your application loads, etc.
0
 
ofrithaAuthor Commented:
Yes I know this error is in my code because when I ran only your code in the j2sdk 1.4.1 I did not get this error.
I get this error when I'm choosing one of the fonts in the JComboBox.
Compilation is fine and all other functions of the program works fine, but only when I try to use the combo box the error occurs.
Any suggestion will be welcome.
Thanks,
ofrit
0
 
OviCommented:
post the full stack trace, or the class where you use'it. Try to add a main(..) method to that class and test'it as standalone. I cannot debug yyour code if I cannot see'it, beside of the fact that debugging is not part and not related with the problem proposed in this question, neither to the solution.
0
 
ofrithaAuthor Commented:
Thank you very much for your help, I'll try finding the solution to the debugging problem.
ofrit
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 9
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now