Unicode.java Source code

Java tutorial

Introduction

Here is the source code for Unicode.java

Source

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GraphicsEnvironment;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.MenuShortcut;
import java.awt.Panel;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.DecimalFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

/**
 * Unicode - show a page of Unicode characters. BUG: Times throws a bunch of
 * exceptions on page 2 and 3, that can not be caught as they occur in the AWT
 * thread. On some platforms.
 * 
 * TODO - remove GoToPage as a dialog, move its textfield into main GUI.
 * 
 * @author Ian Darwin, http://www.darwinsys.com/
 * @version $Id: Unicode.java,v 1.7 2004/02/09 03:33:50 ian Exp $
 */
public class Unicode extends JFrame {

    /** "main program" method - construct and show */
    public static void main(String[] av) {
        // create a Unicode object, tell it to show up
        new Unicode().setVisible(true);
    }

    protected final int COLUMNS = 16, ROWS = 16;

    /** the unicode char at start of current page */
    protected int startNum = 0;

    protected final int QUADSIZE = ROWS * COLUMNS;

    /** the buttons that display the characters */
    protected JLabel buttons[][] = new JLabel[COLUMNS][ROWS];

    /** the font name display */
    protected JLabel fontName;

    /** the row labels, in a column at the left */
    protected JLabel rowLabs[] = new JLabel[ROWS];

    /** The page chooser pop-up */
    protected GoToPage gotoPageUI;

    /** How git to make the font samples */
    protected final int FONTSIZE = 8;

    /** Construct the object including its GUI */
    public Unicode() {
        super("Unicode");

        Container cp = getContentPane();

        // Used both for Buttons and Menus
        ResourceBundle b = ResourceBundle.getBundle("UnicodeWidgets");

        JButton quitButton, nextButton, prevButton;
        Panel p = new Panel();
        // Make a grid, add one for labels.
        p.setLayout(new GridLayout(ROWS + 1, COLUMNS + 1));
        DecimalFormat df2d = new DecimalFormat("00");

        // Add first row, just column labels.
        p.add(new JLabel(""));
        for (int i = 0; i < COLUMNS; i++)
            p.add(new JLabel(Integer.toString(i, 16), JLabel.CENTER));

        // Add subsequent rows, each with an offset label
        for (int i = 0; i < ROWS; i++) {
            JLabel l = new JLabel("0000"); // room for max, i.e. \uFFFF
            p.add(l);
            rowLabs[i] = l;
            for (int j = 0; j < COLUMNS; j++) {
                JLabel pb = new JLabel(" ");
                buttons[j][i] = pb;
                p.add(pb);
            }
        }

        // ActionListeners for jumping around; used by buttons and menus
        ActionListener firster = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                gotoPage(startNum = 0);
            }
        };
        ActionListener previouser = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (startNum > 0)
                    gotoPage(startNum -= QUADSIZE);
            }
        };
        ActionListener nexter = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (startNum < 65535)
                    gotoPage(startNum += QUADSIZE);
            }
        };
        ActionListener laster = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                gotoPage(65536 - QUADSIZE);
            }
        };

        cp.add(BorderLayout.NORTH, p);
        fontName = new JLabel("Default font", JLabel.CENTER);
        cp.add(BorderLayout.CENTER, fontName);
        Panel q = new Panel();
        cp.add(BorderLayout.SOUTH, q);
        q.add(prevButton = mkButton(b, "page.prev"));
        prevButton.addActionListener(previouser);

        q.add(nextButton = mkButton(b, "page.next"));
        nextButton.addActionListener(nexter);

        q.add(quitButton = mkButton(b, "exit"));
        quitButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                setVisible(false);
                dispose();
                System.exit(0);
            }
        });
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                setVisible(false);
                dispose();
                System.exit(0);
            }
        });

        MenuItem mi; // used in various spots

        MenuBar mb = new MenuBar();
        setMenuBar(mb);

        String titlebar;
        try {
            titlebar = b.getString("program" + ".title");
        } catch (MissingResourceException e) {
            titlebar = "Unicode Demo";
        }
        setTitle(titlebar);

        ActionListener fontSelector = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String font = e.getActionCommand();
                mySetFont(font, FONTSIZE);
            }
        };

        Menu fontMenu = mkMenu(b, "font");
        // String[] fontList = Toolkit.getDefaultToolkit().getFontList();
        String[] fontList = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
        for (int i = 0; i < fontList.length; i++) {
            fontMenu.add(mi = new MenuItem(fontList[i]));
            mi.addActionListener(fontSelector);
        }
        mb.add(fontMenu);

        gotoPageUI = new GoToPage("Unicode Page");
        centre(gotoPageUI);

        Menu vm = mkMenu(b, "page");
        vm.add(mi = mkMenuItem(b, "page", "first"));
        mi.addActionListener(firster);
        vm.add(mi = mkMenuItem(b, "page", "prev"));
        mi.addActionListener(previouser);
        vm.add(mi = mkMenuItem(b, "page", "next"));
        mi.addActionListener(nexter);
        vm.add(mi = mkMenuItem(b, "page", "last"));
        mi.addActionListener(laster);
        vm.add(mi = mkMenuItem(b, "page", "goto"));
        mi.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Unicode.this.gotoPageUI.setVisible(true);
            }
        });
        mb.add(vm);

        Menu hm = mkMenu(b, "help");
        hm.add(mi = mkMenuItem(b, "help", "about"));
        mb.setHelpMenu(hm); // needed for portability (Motif, etc.).

        pack();
        // After packing the Frame, centre it on the screen.
        centre(this);

        // start at a known place
        mySetFont(fontList[0], FONTSIZE);
        gotoPage(startNum);
    } // End of huge Constructor

    private void mySetFont(String font, int sz) {
        fontName.setText("Font = " + font);
        Font f = new Font(font, Font.PLAIN, sz);
        for (int i = 0; i < ROWS; i++) {
            for (int j = 0; j < COLUMNS; j++)
                buttons[i][j].setFont(f);
        }
        repaint();
    }

    public void centre(Window c) {
        Dimension us = c.getSize(), them = Toolkit.getDefaultToolkit().getScreenSize();
        int newX = (them.width - us.width) / 2;
        int newY = (them.height - us.height) / 2;
        c.setLocation(newX, newY);
    }

    /**
     * Go to a given page of Unicode. At present the parameter is a code value,
     * but it should be a page #.
     */
    private void gotoPage(int startNum) {
        // System.out.println("startAt(" + startNum + ")");
        char chars[] = new char[1];
        for (int i = 0; i < ROWS; i++) {
            JLabel l = rowLabs[i];
            // System.out.println("i=" + i + ", JLabel=" + l);
            l.setText(Integer.toString(startNum + (i * COLUMNS), 16));
            // l.validate(); // size may be too big now
            for (int j = 0; j < COLUMNS; j++) {
                chars[0] = (char) (startNum + ((j * ROWS) + i));
                JLabel b = buttons[i][j];
                b.setText(new String(chars));
            }
        }
        repaint();
    }

    /** Convenience routine to make a Button */
    public JButton mkButton(ResourceBundle b, String name) {
        String label;
        try {
            label = b.getString(name + ".label");
        } catch (MissingResourceException e) {
            label = name;
        }
        return new JButton(label);
    }

    /** Convenience routine to make a Menu */
    public Menu mkMenu(ResourceBundle b, String name) {
        String menuLabel;
        try {
            menuLabel = b.getString(name + ".label");
        } catch (MissingResourceException e) {
            menuLabel = name;
        }
        return new Menu(menuLabel);
    }

    /** Convenience routine to make a MenuItem */
    public MenuItem mkMenuItem(ResourceBundle b, String menu, String name) {
        String miLabel;
        try {
            miLabel = b.getString(menu + "." + name + ".label");
        } catch (MissingResourceException e) {
            miLabel = name;
        }
        String key = null;
        try {
            key = b.getString(menu + "." + name + ".key");
        } catch (MissingResourceException e) {
            key = null;
        }

        if (key == null)
            return new MenuItem(miLabel);
        else
            return new MenuItem(miLabel, new MenuShortcut(key.charAt(0)));
    }

    /**
     * Implement a simple "Go To Page" dialog Row one: "Go to Page", textfield
     * second OK, Cancel buttons.
     */
    class GoToPage extends Frame {
        /** TextField used to enter the number */
        protected JTextField tf;

        /** The OK button */
        protected Button ok;

        /** The cancel button */
        protected Button can;

        /** Construct a GoToPage window (no actions yet) */
        public GoToPage(String title) {
            setTitle(title);
            Container cp = getContentPane();

            Label l = new Label("Quadrant number (hex):");
            tf = new JTextField(4);
            tf.setText("1");
            // set the text initially selected so you can easily overtype it
            tf.selectAll();

            ok = new Button("OK");
            can = new Button("Cancel");
            can.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    setVisible(false);
                }
            });

            ActionListener doIt = new ActionListener() {
                public void actionPerformed(ActionEvent e) {

                    int n = -1;
                    try {
                        n = getValue();
                    } catch (IllegalArgumentException notANumber) {
                        // handled below
                    }
                    if (n >= 0 && n <= 255) {
                        gotoPage(startNum = n * QUADSIZE);
                        setVisible(false);
                    } else
                        Toolkit.getDefaultToolkit().beep();
                }
            };
            ok.addActionListener(doIt);
            tf.addActionListener(doIt);

            Panel top = new Panel();
            top.add(l);
            top.add(tf);

            Panel bottom = new Panel();
            bottom.add(ok);
            bottom.add(can);

            cp.add(BorderLayout.NORTH, top);
            cp.add(BorderLayout.SOUTH, bottom);

            pack();
        }

        protected int getValue() {
            int i = Integer.parseInt(tf.getText(), 16);
            return i;
        }
    }
}
//UnicodeWidgets.properties
/*
program.title=Unicode lister, by Ian Darwin
#
# The Exit button
exit.label=Close
#
# The Font Family Menu
#
font.label=Font Family
# font names, hence menuitems, are discovered from Toolkit by the program
#
# The Page Menu
#
page.label=Page
page.first.label=Quadrant 0 (ASCII)
page.first.key=F
page.prev.label=Previous Quadrant
page.prev.key=P
page.next.label=Next Quadrant
page.next.key=N
page.last.label=Last Quadrant
page.last.key=L
page.goto.label=Goto Page...
page.goto.key=G
#
# The Help Menu
#
help.label=Help
help.about.label=About
    
    
*/