# Java: FontDemo example

MUST UPDATE TO CURRENT SOURCE!!!!!

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

    /**
      * FontDemo.java -- Demo of some Font class options.
      * @version 21 July 1998, July 1999, 2000-05-10, 2000-12-05, 2002-02-12 Java 2
      * @author Fred Swartz
      */

    //Improvements: setter method for style, constructor for initial values,
    //              antialising checkbox, font list (not combobox) in west,
    //              maybe make it a text area with sample text that can be
    //              changed, but also put prototype text in field.
    // Bug: starts with "null" as the font name.

    // Many classes are explicitly imported just to see what was being used.
    import java.awt.Font;
    import java.awt.FontMetrics;
    import java.awt.Container;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.GraphicsEnvironment;
    import java.awt.BorderLayout;
    import java.awt.GridLayout;
    import java.awt.geom.Rectangle2D;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JLabel;
    import javax.swing.JTextField;
    import javax.swing.JSlider;
    import javax.swing.JComboBox;
    import javax.swing.Box;
    import java.awt.event.*;
    import javax.swing.event.*;
    import java.util.Vector;

    ///////////////////////////////////////////////////////////// FontDemo
    class FontDemo extends JFrame {
        JTextField sizefield;  // shows the font size
        JSlider    sizeSlider; // sets the font size
        JComboBox  fontCombo;  // for selecting one of the installed fonts.
        JComboBox  styleCombo; // for selecting style (plain, bold, ...)

        int currentSize  = 24;
        int currentStyle = Font.PLAIN;
        String currentStyleString = "Font.PLAIN";
        String initialFontName    = "Monospaced";

        GraphicsPanel gp;  // Where the sample text is written
        static final String[] fontStyleString = new String[]
            {"Font.PLAIN", "Font.ITALIC", "Font.BOLD", "Font.ITALIC+Font.BOLD"};
        static final    int[] fontStyleInt    = new    int[]
            { Font.PLAIN ,  Font.ITALIC ,  Font.BOLD ,  Font.ITALIC+Font.BOLD };

        //============================================== constructor
        public FontDemo() {
            int row = 0, col = 0;

            // --- Create a GraphicsPanel
            gp = new GraphicsPanel();

            // --- Get all font families
            String[] fontNames = GraphicsEnvironment
                                 .getLocalGraphicsEnvironment()
                                 .getAvailableFontFamilyNames();

            // --- Make vector of all fonts that can display basic chars
            Vector visFonts = new Vector(fontNames.length);
            for (int i=0; i<fontNames.length; i++) {
                Font f = new Font(fontNames[i], Font.PLAIN, 12);
                if (f.canDisplay('a')) {
                    // Display only fonts that have the alphabetic characters.
                    // On my machine there are almost 20 fonts (eg, Wingdings)
                    // that don't display text.
                    visFonts.add(fontNames[i]);
                } else {
                    //System.out.println("No alphabetics in " + fontNames[i]);
                }
            }

            fontCombo = new JComboBox(visFonts);         // JComboBox of fonts
            fontCombo.setSelectedItem(initialFontName);  // select the default font
            fontCombo.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        gp.setFontName((String)fontCombo.getSelectedItem());
                    }
                });

            // --- Style: create a Choice drop-down menu ---------------
            styleCombo = new JComboBox(fontStyleString);
            styleCombo.setSelectedItem(currentStyleString);
            styleCombo.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        currentStyle = fontStyleInt[styleCombo.getSelectedIndex()];
                        gp.repaint();  // we changed something -  redraw
                    }
                });

            // --- Size: JSlider and JTextField ---------------
            // create and add a textfield to display the size
            sizefield = new JTextField(""+currentSize,3);
            sizefield.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        try {
                            currentSize = Integer.parseInt(sizefield.getText());
                            sizeSlider.setValue(currentSize);  // set the slider
                        }
                        catch (NumberFormatException ne) {
                            sizefield.setText("XX");
                            currentSize = 12;
                        }
                        gp.repaint();
                    }
                });

            // create a slider for setting the size value
            sizeSlider = new JSlider(JSlider.HORIZONTAL, 5, 60, currentSize);
            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) {
                         int size = sizeSlider.getValue();  // get slider value
                         sizefield.setText("" + size);
                         gp.setFontSize(size);
                     }
                 });

            //--- Layout components
            Container content = this.getContentPane();
            content.setBackground(new Color(0x00CCFF));
            content.setLayout(new BorderLayout());

            Box fontControlBox = Box.createHorizontalBox();
            fontControlBox.add(fontCombo);
            fontControlBox.add(Box.createHorizontalGlue());

            Box styleControlBox = Box.createHorizontalBox();
            styleControlBox.add(styleCombo);
            styleControlBox.add(Box.createHorizontalGlue());

            Box sizeControlBox = Box.createHorizontalBox();
            sizeControlBox.add(sizefield);
            sizeControlBox.add(Box.createHorizontalStrut(5));
            sizeControlBox.add(sizeSlider);
            sizeControlBox.add(Box.createHorizontalGlue());

            JPanel controls = new JPanel(new GridLayout(3, 2, 4, 4));
            controls.add(new JLabel("Font family name" , JLabel.RIGHT));
            controls.add(fontControlBox);
            controls.add(new JLabel("Style", JLabel.RIGHT));
            controls.add(styleControlBox);
            controls.add(new JLabel("Size" , JLabel.RIGHT));
            controls.add(sizeControlBox);

            content.add(gp, BorderLayout.CENTER);  // put in center to stretch.
            content.add(controls, BorderLayout.SOUTH);

            this.setTitle("Font Demo");
            this.pack();
        }//end constructor

        //////////////////////////////////////////////////////// GraphicsPanel class
        // A component to draw sample string with given font family, style, and size.
        class GraphicsPanel extends JPanel {
            private String currentFontName;
            private int    currentFontSize;

            //========================================================== constructor
            public GraphicsPanel() {
                this.setPreferredSize(new Dimension(600, 100));
                this.setBackground(Color.white);
                this.setForeground(Color.black);
            }//end constructor

            //======================================================= paintComponent
            public void paintComponent(Graphics g) {
                super.paintComponent(g);  // paint background
                String text = "Font(\""
                              + currentFontName + "\", "
                              + currentStyleString + ", "
                              + currentSize + ");";
                Font f = new Font(currentFontName, currentStyle, currentSize);
                g.setFont(f);

                // Find the size of this text so we can center it
                FontMetrics fm   = g.getFontMetrics(f);  // metrics for this object
                Rectangle2D rect = fm.getStringBounds(text, g); // size of string

                int textHeight = (int)(rect.getHeight());
                int textWidth  = (int)(rect.getWidth());
                int panelHeight= this.getHeight();
                int panelWidth = this.getWidth();

                // Center text horizontally and vertically
                int x = (panelWidth  - textWidth)  / 2;
                int y = (panelHeight - textHeight) / 2  + fm.getAscent();

                g.drawString(text, x, y);
            }//end paintComponent

            //======================================================== setFontName
            public void setFontName(String fn) {
                currentFontName = fn;
                this.repaint();
            }

            //======================================================== setFontSize
            public void setFontSize(int size) {
                currentSize = size;
                this.repaint();
            }
        }//endclass GraphicsPanel

        //===================================================================== main
        public static void main(String[] args) {
            JFrame myWindow = new FontDemo();
            myWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            myWindow.setVisible(true); // Make the window visible.
        }//endmethod main

    }//endclass FontDemo