# 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;
        }
    }