Java Notes

FontDemo example

This program displays the available fonts and how they look in different sizes and styles.

Source for main program and user interface

  1 
  2 
  3 
  4 
  5 
  6 
  7 
  8 
  9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
 38 
 39 
 40 
 41 
 42 
 43 
 44 
 45 
 46 
 47 
 48 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 
 57 
 58 
 59 
 60 
 61 
 62 
 63 
 64 
 65 
 66 
 67 
 68 
 69 
 70 
 71 
 72 
 73 
 74 
 75 
 76 
 77 
 78 
 79 
 80 
 81 
 82 
 83 
 84 
 85 
 86 
 87 
 88 
 89 
 90 
 91 
 92 
 93 
 94 
 95 
 96 
 97 
 98 
 99 
100 
101 
102 
103 
104 
105 
106 
107 
108 
109 
110 
111 
112 
113 
114 
115 
116 
117 
118 
119 
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 
131 
132 
133 
134 
135 
136 
137 
138 
139 
140 
141 
142 
143 
144 
145 
146 
147 
148 
149 
150 
151 
152 
153 
154 
155 
156 
157 
158 
159 
160 
161 
162 
163 
164 
165 
166 
167 
168 
169 
170 
171 
172 
173 
174 
175 
176 
177 
178 
179 
180 
181 
182 
183 
184 
// File   : gui-appearance/font/fontdemo/FontDemo.java
// Purpose: Demo of how to work with fonts.  This class is primarily 
//          user interface.  The accomanying FontPanel class does the drawing.
// Author : Fred Swartz - 28 Sep 2006 - Placed in public domain.

package fontdemo;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSlider;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/////////////////////////////////////////////////////////////////////// FontDemo
class FontDemo extends JFrame {
    //=================================================================== fields
    private FontPanel  _displayArea;// Where the sample text is displayed.
    
    //... The following controls are instance variables because they are
    //    referenced at "runtime" in the listeners.  Alternate solutions:
    //    * Declare them as *final* local variables.
    //    * Obtain them from the Event object passed to the listeners, which
    //      is a good solution when a listener is shared (but not here).
    private JSlider    _sizeSlider; // Sets the font size.
    private JComboBox  _fontCombo;  // For selecting one of the installed fonts.
    private JCheckBox  _antialiasedCB; // To draw with antiliasing on/off.
    
    //================================================================ constants
    private static final int    INITIAL_SIZE  = 18;
    private static final int    INITIAL_STYLE = Font.PLAIN;
    private static final String INITIAL_STYLENAME = "Font.PLAIN";
    private static final String INITIAL_FONTNAME  = "Monospaced";
    
    //============================================================== constructor
    public FontDemo() {
        //... Create a FontPanel to display the fonts.
        _displayArea = new FontPanel(INITIAL_FONTNAME, INITIAL_STYLE, 
                INITIAL_SIZE, false);
        
        //... Get all font families
        String[] fontNames = GraphicsEnvironment
                .getLocalGraphicsEnvironment()
                .getAvailableFontFamilyNames();
        
        //... Make vector of all fonts that can display basic chars.
        //    Vector (not newer ArrayList) is used by JComboBox.
        Vector<String> visFonts = new Vector<String>(fontNames.length);
        for (String fontName : fontNames) {
            Font f = new Font(fontName, Font.PLAIN, 12);
            if (f.canDisplay('a')) {
                //... Display only fonts that have the alphabetic characters.
                visFonts.add(fontName);
            } else {
                //    On my machine there are almost 20 fonts (eg, Wingdings)
                //    that don't display text.
                //System.out.println("No alphabetics in " + fontName);
            }
        }
        
        _fontCombo = new JComboBox(visFonts);         // JComboBox of fonts
        _fontCombo.setSelectedItem(INITIAL_FONTNAME); // Select initial font
        _fontCombo.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                _displayArea.setFontName((String)_fontCombo.getSelectedItem());
            }
        });
        
        //... Style: Create radio buttons for the 4 style options.
        JRadioButton stylePlainRB  = new JRadioButton("Font.PLAIN", true);
        JRadioButton styleItalicRB = new JRadioButton("Font.ITALIC", false);
        JRadioButton styleBoldRB   = new JRadioButton("Font.BOLD", false);
        JRadioButton styleItalicBoldRB = new JRadioButton("Font.ITALIC+Font.BOLD"
                , false);
        
        //... Add the buttons to a button group
        ButtonGroup styleGroup = new ButtonGroup();
        styleGroup.add(stylePlainRB);
        styleGroup.add(styleItalicRB);
        styleGroup.add(styleBoldRB);
        styleGroup.add(styleItalicBoldRB);
        
        //... Add listeners.
        stylePlainRB.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                _displayArea.setFontStyle(Font.PLAIN);
            }
        });
        styleItalicRB.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                _displayArea.setFontStyle(Font.ITALIC);
            }
        });
        styleBoldRB.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                _displayArea.setFontStyle(Font.BOLD);
            }
        });
        styleItalicBoldRB.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                _displayArea.setFontStyle(Font.ITALIC + Font.BOLD);
            }
        });
        
        //... Antialiasing checkbox
        _antialiasedCB = new JCheckBox("Antialiased");
        _antialiasedCB.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                _displayArea.setAntialiasing(_antialiasedCB.isSelected());
            }
        });
        
        //... Create a slider for setting the size value
        _sizeSlider = new JSlider(JSlider.HORIZONTAL, 5, 60, INITIAL_SIZE);
        _sizeSlider.setMajorTickSpacing(10); // sets numbers for big tick marks
        _sizeSlider.setMinorTickSpacing(1);  // smaller tick marks
        _sizeSlider.setPaintTicks(true);     // display the ticks
        _sizeSlider.setPaintLabels(true);    // show the numbers
        _sizeSlider.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                _displayArea.setFontSize(_sizeSlider.getValue());
            }
        });
        
        //... Controls arranged in BoxLayout.
        //    This is pretty ugly, but I didn't feel like struggling with
        //    GridBagLayout, and didn't want to use any of the superior
        //    external layout managers in this program.
        JPanel controls = new JPanel();
        controls.setLayout(new BoxLayout(controls, BoxLayout.Y_AXIS));
        
        //... Add components to controls panel.
        addToBox(controls, Component.LEFT_ALIGNMENT
                , new JLabel("Font:"), _fontCombo
                , new JLabel("Size:"), _sizeSlider
                , new JLabel("Style:"), stylePlainRB, styleItalicRB
                , styleBoldRB, styleItalicBoldRB
                , _antialiasedCB
                );
        
        //... Put display+controls in the content pane.
        JPanel content = new JPanel();
        content.setLayout(new BorderLayout(5, 5));
        content.add(_displayArea, BorderLayout.CENTER);
        content.add(controls, BorderLayout.WEST);
        content.setBorder(new EmptyBorder(12, 12, 12, 12));
        
        //... Set window characteristics
        setContentPane(content);
        setTitle("Font Demo");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
    }
    
    //================================================================= addToBox
    // Utility method to add elements to a BoxLayout container.
    private void addToBox(Container cont, float align, JComponent... comps ) {
        for (JComponent comp : comps) {
            comp.setAlignmentX(align);
            cont.add(comp);
        }
    }
    
    //===================================================================== main
    public static void main(String[] args) {
        JFrame myWindow = new FontDemo();
        myWindow.setVisible(true);
    }
}

Source for the graphics component that draws the text

This class shows how to turn on antialiasing and center text in an area.

  1 
  2 
  3 
  4 
  5 
  6 
  7 
  8 
  9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
 38 
 39 
 40 
 41 
 42 
 43 
 44 
 45 
 46 
 47 
 48 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 
 57 
 58 
 59 
 60 
 61 
 62 
 63 
 64 
 65 
 66 
 67 
 68 
 69 
 70 
 71 
 72 
 73 
 74 
 75 
 76 
 77 
 78 
 79 
 80 
 81 
 82 
 83 
 84 
 85 
 86 
 87 
 88 
 89 
 90 
 91 
// File   : gui-appearance/font/fontdemo/FontPanel.java
// Purpose: A component to draw sample string with given font family, style,
//          size, and aliasing.
// Author : Fred Swartz - 28 Sep 2006 - Placed in public domain.

package fontdemo;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import javax.swing.JPanel;

//////////////////////////////////////////////////////////////// FontPanel class
class FontPanel extends JPanel {
    private String _fontName;
    private int    _fontStyle;
    private int    _fontSize;
    private boolean _antialiased;
    
    //============================================================== constructor
    public FontPanel(String font, int style, int size, boolean antialiased) {
        this.setPreferredSize(new Dimension(400, 100));
        this.setBackground(Color.white);
        this.setForeground(Color.black);
        _fontName  = font;
        _fontStyle = style;
        _fontSize  = size;
        _antialiased = antialiased;
    }
    
    //================================================= @Override paintComponent
    @Override public void paintComponent(Graphics g) {
        super.paintComponent(g);        // Paint background.
        
        Graphics2D g2 = (Graphics2D)g;  // Graphics2 for antialiasing.
        
        String text = "Font(\""
                + _fontName + "\", "
                + fontStyleCodeToFontStyleString(_fontStyle) + ", "
                + _fontSize + ");";
        Font f = new Font(_fontName, _fontStyle, _fontSize);
        g2.setFont(f);
        
        if (_antialiased) {
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
        }
        
        //... Find the size of this text so we can center it.
        FontMetrics fm = g2.getFontMetrics(f);  // metrics for this object
        Rectangle2D rect = fm.getStringBounds(text, g2); // size of string
        int textHeight  = (int)(rect.getHeight());
        int textWidth   = (int)(rect.getWidth());
        
        //... Center text horizontally and vertically
        int x = (this.getWidth()  - textWidth)  / 2;
        int y = (this.getHeight() - textHeight) / 2  + fm.getAscent();
        
        g2.drawString(text, x, y);
    }
    
    //================================================================== SETTERS
    public void setFontName(String fn)  { _fontName = fn;    this.repaint();}
    public void setFontSize(int size)   { _fontSize = size;  this.repaint();}
    public void setFontStyle(int style) {_fontStyle = style; this.repaint();}
    public void setAntialiasing(boolean antialiased) {
        _antialiased = antialiased;
        this.repaint();
    }
    
    //=========================================== fontStyleCodeToFontStyleString
    // Utility method for converting font codes to name.
    public static String fontStyleCodeToFontStyleString(int styleCode) {
        String styleName;
        switch (styleCode) {
            case Font.PLAIN:            styleName = "Font.PLAIN";       break;
            case Font.ITALIC:           styleName = "Font.ITALIC";      break;
            case Font.BOLD:             styleName = "Font.BOLD";        break;
            case Font.ITALIC+Font.BOLD: styleName = "ITALIC+Font.BOLD"; break;
            default: throw new IllegalArgumentException(
                    "fontStyleCodeToFontStyleString: Unknown font code: " +
                    styleCode);
        };
        return styleName;
    }
}