// This example is from _Java Examples in a Nutshell_. (http://www.oreilly.com) // Copyright (c) 1997 by David Flanagan // This example is provided WITHOUT ANY WARRANTY either expressed or implied. // You may study, use, modify, and distribute it for non-commercial purposes. // For any commercial use, see http://www.davidflanagan.com/javaexamples import java.applet.*; import java.awt.*; import java.awt.event.*; /** * This program displays Unicode glyphs using user-specified fonts * and font styles. **/ public class UnicodeDisplay extends Frame implements ActionListener { int page = 0; UnicodePanel p; Scrollbar b; String fontfamily = "Serif"; int fontstyle = Font.PLAIN; /** * This constructor creates the frame, menubar, and scrollbar * that work along with the UnicodePanel class, defined below **/ public UnicodeDisplay(String name) { super(name); this.setLayout(new BorderLayout()); p = new UnicodePanel(); // Create the panel p.setBase((char)(page * 0x100)); // Initialize it this.add(p, "Center"); // Center it // Create and set up a scrollbar, and put it on the right b = new Scrollbar(Scrollbar.VERTICAL, 0, 1, 0, 0xFF); b.setUnitIncrement(1); b.setBlockIncrement(0x10); b.addAdjustmentListener(new AdjustmentListener() { public void adjustmentValueChanged(AdjustmentEvent e) { page = e.getValue(); p.setBase((char)(page * 0x100)); } }); this.add(b, "East"); // Set things up so we respond to window close requests this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { UnicodeDisplay.this.dispose(); System.exit(0); } }); // Handle Page Up and Page Down and the up and down arrow keys this.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { int code = e.getKeyCode(); int oldpage = page; if ((code == KeyEvent.VK_PAGE_UP) || (code == KeyEvent.VK_UP)) { if (e.isShiftDown()) page -= 0x10; else page -= 1; if (page < 0) page = 0; } else if ((code == KeyEvent.VK_PAGE_DOWN) || (code==KeyEvent.VK_DOWN)) { if (e.isShiftDown()) page += 0x10; else page += 1; if (page > 0xff) page = 0xff; } if (page != oldpage) { // if anything has changed... p.setBase((char) (page * 0x100)); // update the display b.setValue(page); // and update scrollbar to match } } }); // Set up a menu system to change fonts. Use a convenience method. MenuBar menubar = new MenuBar(); this.setMenuBar(menubar); menubar.add(makemenu("Font Family", new String[] {"Serif", "SansSerif", "Monospaced"}, this)); menubar.add(makemenu("Font Style", new String[]{"Plain", "Italic", "Bold", "BoldItalic"}, this)); } /** This method handles the items in the menubars */ public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); if (cmd.equals("Serif")) fontfamily = "Serif"; else if (cmd.equals("SansSerif")) fontfamily = "SansSerif"; else if (cmd.equals("Monospaced")) fontfamily = "Monospaced"; else if (cmd.equals("Plain")) fontstyle = Font.PLAIN; else if (cmd.equals("Italic")) fontstyle = Font.ITALIC; else if (cmd.equals("Bold")) fontstyle = Font.BOLD; else if (cmd.equals("BoldItalic")) fontstyle = Font.BOLD + Font.ITALIC; p.setFont(fontfamily, fontstyle); } /** A convenience method to create a Menu from an array of items */ private Menu makemenu(String name, String[] itemnames, ActionListener listener) { Menu m = new Menu(name); for(int i = 0; i < itemnames.length; i++) { MenuItem item = new MenuItem(itemnames[i]); item.addActionListener(listener); item.setActionCommand(itemnames[i]); // okay here, though m.add(item); } return m; } /** The main() program just create a window, packs it, and shows it */ public static void main(String[] args) { UnicodeDisplay f = new UnicodeDisplay("Unicode Displayer"); f.pack(); f.show(); } /** * This nested class is the one that displays one "page" of Unicode * glyphs at a time. Each "page" is 256 characters, arranged into 16 * rows of 16 columns each. **/ public static class UnicodePanel extends Canvas { protected char base; // What character we start the display at protected Font font = new Font("serif", Font.PLAIN, 18); protected Font headingfont = new Font("monospaced", Font.BOLD, 18); static final int lineheight = 25; static final int charspacing = 20; static final int x0 = 65; static final int y0 = 40; /** Specify where to begin displaying, and re-display */ public void setBase(char base) { this.base = base; repaint(); } /** Set a new font name or style, and redisplay */ public void setFont(String family, int style) { this.font = new Font(family, style, 18); repaint(); } /** * The paint() method actually draws the page of glyphs **/ public void paint(Graphics g) { int start = (int)base & 0xFFF0; // Start on a 16-character boundary // Draw the headings in a special font g.setFont(headingfont); // Draw 0..F on top for(int i=0; i < 16; i++) { String s = Integer.toString(i, 16); g.drawString(s, x0 + i*charspacing, y0-20); } // Draw column down left. for(int i = 0; i < 16; i++) { int j = start + i*16; String s = Integer.toString(j, 16); g.drawString(s, 10, y0+i*lineheight); } // Now draw the characters g.setFont(font); char[] c = new char[1]; for(int i = 0; i < 16; i++) { for(int j = 0; j < 16; j++) { c[0] = (char)(start + j*16 + i); g.drawChars(c, 0, 1, x0 + i*charspacing, y0 + j*lineheight); } } } /** Custom components like this one should always have this method */ public Dimension getPreferredSize() { return new Dimension(410, 430); } } }