?
Solved

JTextPane font

Posted on 2003-03-17
15
Medium Priority
?
1,052 Views
Last Modified: 2013-12-02
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
Comment
Question by:ofritha
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 5
15 Comments
 
LVL 1

Expert Comment

by:allelopath
ID: 8153056
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
 
LVL 9

Expert Comment

by:Ovi
ID: 8153136
       String name = "a - font - family";
        new StyledEditorKit.FontFamilyAction("font-family-" + name, name).actionPerformed('a dummy action event');
0
 
LVL 9

Expert Comment

by:Ovi
ID: 8153154
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
Optimize your web performance

What's in the eBook?
- Full list of reasons for poor performance
- Ultimate measures to speed things up
- Primary web monitoring types
- KPIs you should be monitoring in order to increase your ROI

 

Author Comment

by:ofritha
ID: 8157472
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
 
LVL 9

Expert Comment

by:Ovi
ID: 8157484
Just wait ...
0
 
LVL 9

Expert Comment

by:Ovi
ID: 8157555
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
 

Author Comment

by:ofritha
ID: 8158598
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
 
LVL 9

Expert Comment

by:Ovi
ID: 8158623
wait a little ...
0
 
LVL 9

Accepted Solution

by:
Ovi earned 80 total points
ID: 8158724
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
 
LVL 9

Expert Comment

by:Ovi
ID: 8158732
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
 

Author Comment

by:ofritha
ID: 8165130
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
 
LVL 9

Expert Comment

by:Ovi
ID: 8165307
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
 

Author Comment

by:ofritha
ID: 8165358
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
 
LVL 9

Expert Comment

by:Ovi
ID: 8165514
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
 

Author Comment

by:ofritha
ID: 8165547
Thank you very much for your help, I'll try finding the solution to the debugging problem.
ofrit
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
In this post we will learn different types of Android Layout and some basics of an Android App.
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…
This video teaches viewers about errors in exception handling.
Suggested Courses
Course of the Month11 days, 17 hours left to enroll

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question