Java/Swing Components/Font Chooser — различия между версиями

Материал из Java эксперт
Перейти к: навигация, поиск
(Новая страница: «== A dialog allow selection and a font and its associated info. == <!-- start source code --> <source lang="java"> /* * Copyright (C) 2001-2004 Co…»)
 
(нет различий)

Текущая версия на 07:45, 1 июня 2010

A dialog allow selection and a font and its associated info.

   
/*
 * Copyright (C) 2001-2004 Colin Bell
 * colbell@users.sourceforge.net
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
import java.awt.BorderLayout;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.Serializable;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
 * A dialog allow selection and a font and its associated info.
 *
 * @author 
 */
public class FontChooser extends JDialog
{
  private final boolean _selectStyles;
  private JComboBox _fontNamesCmb;
  private final JComboBox _fontSizesCmb = new JComboBox(new String[]
                        { "8", "9", "10", "12", "14" });
  private final JCheckBox _boldChk = new JCheckBox("Bold");
  private final JCheckBox _italicChk = new JCheckBox("Italic");
  private final JLabel _previewLbl = new JLabel("PreviewText");
  private Font _font;
  private ActionListener _previewUpdater;
  /**
   * Default ctor.
   */
  public FontChooser()
  {
    this((Frame)null);
  }
  /**
   * ctor specifying whether styles can be selected.
   *
   * @param selectStyles  If <TT>true</TT> bold and italic checkboxes displayed.
   */
  public FontChooser(boolean selectStyles)
  {
    this((Frame)null, selectStyles);
  }
  /**
   * ctor specifying the parent frame.
   *
   * @param owner Parent frame.
   */
  public FontChooser(Frame owner)
  {
    super(owner, "Font Chooser", true);
    _selectStyles = true;
    createUserInterface();
  }
  /**
   * ctor specifying the parent frame and whether styles can be selected.
   *
   * @param owner     Parent frame.
   * @param selectStyles  If <TT>true</TT> bold and italic checkboxes displayed.
   */
  public FontChooser(Frame owner, boolean selectStyles)
  {
    super(owner, "Font Chooser", true);
    _selectStyles = selectStyles;
    createUserInterface();
  }
  /**
   * ctor specifying the parent dialog.
   *
   * @param owner Parent frame.
   */
  public FontChooser(Dialog owner)
  {
    super(owner, "Font Chooser", true);
    _selectStyles = true;
    createUserInterface();
  }
  /**
   * ctor specifying the parent dialog and whether styles can be selected.
   *
   * @param owner Parent frame.
   * @param selectStyles  If <TT>true</TT> bold and italic checkboxes displayed.
   */
  public FontChooser(Dialog owner, boolean selectStyles)
  {
    super(owner, "Font Chooser", true);
    _selectStyles = selectStyles;
    createUserInterface();
  }
  /**
   * Component is being added to its parent.
   */
  public void addNotify()
  {
    super.addNotify();
    if (_previewUpdater == null)
    {
      _previewUpdater = new PreviewLabelUpdater();
      _fontNamesCmb.addActionListener(_previewUpdater);
      _fontSizesCmb.addActionListener(_previewUpdater);
      _boldChk.addActionListener(_previewUpdater);
      _italicChk.addActionListener(_previewUpdater);
    }
  }
  /**
   * Component is being removed from its parent.
   */
  public void removeNotify()
  {
    super.removeNotify();
    if (_previewUpdater != null)
    {
      _fontNamesCmb.removeActionListener(_previewUpdater);
      _fontSizesCmb.removeActionListener(_previewUpdater);
      _boldChk.removeActionListener(_previewUpdater);
      _italicChk.removeActionListener(_previewUpdater);
      _previewUpdater = null;
    }
  }
  public Font showDialog()
  {
    return showDialog(null);
  }
  /**
   * Show dialog defaulting to the passed font.
   *
   * @param font  The font to default to.
   */
  public Font showDialog(Font font)
  {
    if (font != null)
    {
      _fontNamesCmb.setSelectedItem(font.getName());
      _fontSizesCmb.setSelectedItem("" + font.getSize());
      _boldChk.setSelected(_selectStyles && font.isBold());
      _italicChk.setSelected(_selectStyles && font.isItalic());
    }
    else
    {
      _fontNamesCmb.setSelectedIndex(0);
      _fontSizesCmb.setSelectedIndex(0);
      _boldChk.setSelected(false);
      _italicChk.setSelected(false);
    }
    setupPreviewLabel();
    setVisible(true);
    return _font;
  }
  public Font getSelectedFont()
  {
    return _font;
  }
  protected void setupFontFromDialog()
  {
    int size = 12;
    try
    {
      size = Integer.parseInt((String)_fontSizesCmb.getSelectedItem());
    }
    catch (Exception ignore)
    {
      // Ignore.
    }
    FontInfo fi = new FontInfo();
    fi.setFamily((String)_fontNamesCmb.getSelectedItem());
    fi.setSize(size);
    fi.setIsBold(_boldChk.isSelected());
    fi.setIsItalic(_italicChk.isSelected());
    _font = fi.createFont();
  }
  private void createUserInterface()
  {
    final JPanel content = new JPanel(new GridBagLayout());
    final GridBagConstraints gbc = new GridBagConstraints();
    setContentPane(content);
    content.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    gbc.anchor = GridBagConstraints.WEST;
    gbc.insets = new Insets(2, 2, 2, 2);
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.gridx = gbc.gridy = 0;
    content.add(new JLabel("Font"), gbc);
    ++gbc.gridx;
    content.add(new JLabel("Size"), gbc);
    if (_selectStyles)
    {
      ++gbc.gridx;
      content.add(new JLabel("Style"), gbc);
    }
    ++gbc.gridy;
    gbc.gridx = 0;
    _fontNamesCmb = new JComboBox(GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames());
    content.add(_fontNamesCmb, gbc);
    ++gbc.gridx;
    _fontSizesCmb.setEditable(true);
    content.add(_fontSizesCmb, gbc);
    if (_selectStyles)
    {
      ++gbc.gridx;
      content.add(_boldChk, gbc);
      ++gbc.gridy;
      content.add(_italicChk, gbc);
    }
    gbc.gridx = 0;
    ++gbc.gridy;
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    gbc.fill = GridBagConstraints.BOTH;
    gbc.anchor = GridBagConstraints.CENTER;
    content.add(createPreviewPanel(), gbc);
    ++gbc.gridy;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    content.add(createButtonsPanel(), gbc);
    pack();
    setResizable(true);
  }
  private JPanel createPreviewPanel()
  {
    final JPanel pnl = new JPanel(new BorderLayout());
    pnl.setBorder(BorderFactory.createTitledBorder("PreviewTitle"));
    Dimension prefSize = _previewLbl.getPreferredSize();
    prefSize.height = 50;
    _previewLbl.setPreferredSize(prefSize);
    pnl.add(_previewLbl, BorderLayout.CENTER);
    setupPreviewLabel();
    return pnl;
  }
  private JPanel createButtonsPanel()
  {
    JPanel pnl = new JPanel();
    JButton okBtn = new JButton("OK");
    okBtn.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent evt)
      {
        setupFontFromDialog();
        dispose();
      }
    });
    JButton cancelBtn = new JButton("Cancel");
    cancelBtn.addActionListener(new ActionListener()
    {
      public void actionPerformed(ActionEvent evt)
      {
        FontChooser.this._font = null;
        dispose();
      }
    });
    pnl.add(okBtn);
    pnl.add(cancelBtn);
    getRootPane().setDefaultButton(okBtn);
    return pnl;
  }
  private void setupPreviewLabel()
  {
    setupFontFromDialog();
    _previewLbl.setFont(_font);
  }
  private final class PreviewLabelUpdater implements ActionListener
  {
    public void actionPerformed(ActionEvent evt)
    {
      setupPreviewLabel();
    }
  }
}

/*
 * Copyright (C) 2001-2003 Colin Bell
 * colbell@users.sourceforge.net
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 class FontInfo implements Cloneable, Serializable
{
    private static final long serialVersionUID = 1L;
    public interface IPropertyNames
  {
    String FAMILY = "family";
    String IS_BOLD = "isBold";
    String IS_ITALIC = "isItalic";
    String SIZE = "size";
  }
  private static String DEFAULT_FAMILY = "Monospaced";
  private String _familyName;
  private boolean _isBold;
  private boolean _isItalic;
  private int _size;
  public FontInfo()
  {
    super();
    setFamily(DEFAULT_FAMILY);
    setSize(12);
  }
  public FontInfo(Font font)
  {
    super();
    if (font == null)
    {
      throw new IllegalArgumentException("Null Font passed");
    }
    setFont(font);
  }
  /**
   * Return a copy of this object.
   */
  public Object clone()
  {
    try
    {
      return super.clone();
    }
    catch (CloneNotSupportedException ex)
    {
      throw new InternalError(ex.getMessage()); // Impossible.
    }
  }
  public String getFamily()
  {
    return _familyName;
  }
  public void setFamily(String value)
  {
    _familyName = value != null ? value : DEFAULT_FAMILY;
  }
  public boolean isBold()
  {
    return _isBold;
  }
  public void setIsBold(boolean value)
  {
    _isBold = value;
  }
  public boolean isItalic()
  {
    return _isItalic;
  }
  public void setIsItalic(boolean value)
  {
    _isItalic = value;
  }
  public int getSize()
  {
    return _size;
  }
  public void setSize(int value)
  {
    _size = value;
  }
  public void setFont(Font font) throws IllegalArgumentException
  {
    if (font == null)
    {
      throw new IllegalArgumentException("Null Font passed");
    }
    _familyName = font.getFamily();
    _isBold = font.isBold();
    _isItalic = font.isItalic();
    _size = font.getSize();
  }
  public boolean doesFontMatch(Font font)
  {
    if (font == null)
    {
      return false;
    }
    return font.getFamily().equals(_familyName)
      && font.getSize() == getSize()
      && font.getStyle() == generateStyle();
  }
  public int generateStyle()
  {
    int style = 0;
    if (!_isBold && !_isItalic)
    {
      style = Font.PLAIN;
    }
    else
    {
      if (_isBold)
      {
        style |= Font.BOLD;
      }
      if (_isItalic)
      {
        style |= Font.ITALIC;
      }
    }
    return style;
  }
  public Font createFont()
  {
    return new Font(_familyName, generateStyle(), _size);
  }
  // i18n ? What is this used for?
  public String toString()
  {
    StringBuffer buf = new StringBuffer();
    buf.append(_familyName).append(", " + _size);
    if (_isBold)
    {
      buf.append(", bold");
    }
    if (_isItalic)
    {
      buf.append(", italic");
    }
    return buf.toString();
  }
    /**
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int PRIME = 31;
        int result = 1;
        result = PRIME * result + ((_familyName == null) ? 0 : _familyName.hashCode());
        result = PRIME * result + (_isBold ? 1231 : 1237);
        result = PRIME * result + (_isItalic ? 1231 : 1237);
        result = PRIME * result + _size;
        return result;
    }
    /**
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        final FontInfo other = (FontInfo) obj;
        if (_familyName == null) {
            if (other._familyName != null)
                return false;
        } else if (!_familyName.equals(other._familyName))
            return false;
        if (_isBold != other._isBold)
            return false;
        if (_isItalic != other._isItalic)
            return false;
        if (_size != other._size)
            return false;
        return true;
    }
}




FontChooser, adapted from NwFontChooserS by Noah Wairauch

   
/*BEGIN_COPYRIGHT_BLOCK
 *
 * Copyright (c) 2001-2008, JavaPLT group at Rice University (drjava@rice.edu)
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
 *      names of its contributors may be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software is Open Source Initiative approved Open Source Software.
 * Open Source Initative Approved is a trademark of the Open Source Initiative.
 * 
 * This file is part of DrJava.  Download the current version of this project
 * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
 * 
 * END_COPYRIGHT_BLOCK*/

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.*;
/**
 * FontChooser, adapted from NwFontChooserS by Noah Wairauch.
 * (see http:///forum.java.sun.ru/thread.jsp?forum=57&thread=195067)
 *
 * @version $Id: FontChooser.java 4872 2009-04-06 21:37:28Z mgricken $
 */
public class FontChooser extends JDialog {
  /** Available font styles.
   */
  private static final String[] STYLES =
      new String[] { "Plain", "Bold", "Italic", "Bold Italic" };
  /** Available font sizes.
   */
  private static final String[] SIZES =
      new String[] { "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
                     "13", "14", "15", "16", "17", "18", "19", "20", "22",
                     "24", "27", "30", "34", "39", "45", "51", "60"};
  // Lists to display
  private NwList _styleList;
  private NwList _fontList;
  private NwList _sizeList;
  // Swing elements
  private JButton _okButton;
  private JButton _cancelButton;
  private JLabel _sampleText = new JLabel();
  private boolean _clickedOK = false;
  /** Constructs a new modal FontChooser for the given frame,
   * using the specified font.
   */
  private FontChooser(Frame parent, Font font) {
    super(parent, true);
    initAll();
    if (font == null) font = _sampleText.getFont();
    _fontList.setSelectedItem(font.getName());
    _sizeList.setSelectedItem(font.getSize() + "");
    _styleList.setSelectedItem(STYLES[font.getStyle()]);
    //this.setResizable(false);
    resize();
  }
  /** Method used to show the font chooser, and select a new font.
   *
   * @param parent The parent frame.
   * @param title  The title for this window.
   * @param font   The previously chosen font.
   * @return the newly chosen font.
   */
  public static Font showDialog(Frame parent, String title, Font font) {
    FontChooser fd = new FontChooser(parent, font);
    fd.setTitle(title);
    
    fd.setVisible(true);
    Font chosenFont = null;
    if (fd.clickedOK()) {
      chosenFont = fd.getFont();
    }
    fd.dispose();
    return (chosenFont);
  }
  /** Shows the font chooser with a standard title ("Font Chooser").
   */
  public static Font showDialog(Frame parent, Font font) {
    return showDialog(parent, "Font Chooser", font);
  }
  private void initAll() {
    getContentPane().setLayout(null);
    setBounds(50, 50, 425, 400);
    _sampleText = new JLabel();
    addLists();
    addButtons();
    _sampleText.setForeground(Color.black);
    getContentPane().add(_sampleText);
    addWindowListener(new WindowAdapter() {
      public void windowClosing(java.awt.event.WindowEvent e) {
        setVisible(false);
      }
    });
    addComponentListener(new ComponentAdapter() {
      public void componentResized(ComponentEvent evt) {
        resize();
      }
    });
  }
  private void resize() {
    int w = getWidth();
    int h = getHeight();
    double wf = (double) w / 425;
    int w2 = (int) (80 * wf);
    int w3 = (int) (50 * wf);
    if (w3 < 30) w3 = 30;
    int w1 = w - w2 - w3 - 25;
    _fontList.setBounds(5, 5, w1, h - 91);
    _styleList.setBounds(w1 + 10, 5, w2, h - 91);
    _sizeList.setBounds(w1 + w2 + 15, 5, w3, h - 91);
    _sampleText.setBounds(10, h - 78, w - 20, 45);
    _okButton.setBounds(w - 165, h - 55, 70, 20);
    _cancelButton.setBounds(w - 81, h - 55, 70, 20);
    validate();
  }
  private void addLists() {
    _fontList = new NwList(GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames());
    _styleList = new NwList(STYLES);
    _sizeList = new NwList(SIZES);
    getContentPane().add(_fontList);
    getContentPane().add(_styleList);
    getContentPane().add(_sizeList);
  }
  private void addButtons() {
    _okButton = new JButton("OK");
    _okButton.setMargin(new Insets(0, 0, 0, 0));
    _cancelButton = new JButton("Cancel");
    _cancelButton.setMargin(new Insets(0, 0, 0, 0));
    _okButton.setFont(new Font(" ", 1, 11));
    _cancelButton.setFont(new Font(" ", 1, 12));
    getContentPane().add(_okButton);
    getContentPane().add(_cancelButton);
    _okButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        setVisible(false);
        _clickedOK = true;
      }
    });
    _cancelButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        setVisible(false);
        _clickedOK = false;
      }
    });
  }
  private void showSample() {
    int g = 0;
    try { g = Integer.parseInt(_sizeList.getSelectedValue()); }
    catch (NumberFormatException nfe) { /* do nothing */ }
    String st = _styleList.getSelectedValue();
    int s = Font.PLAIN;
    if (st.equalsIgnoreCase("Bold")) s = Font.BOLD;
    if (st.equalsIgnoreCase("Italic")) s = Font.ITALIC;
    if (st.equalsIgnoreCase("Bold Italic")) s = Font.BOLD | Font.ITALIC;
    _sampleText.setFont(new Font(_fontList.getSelectedValue(), s, g));
    _sampleText.setText("The quick brown fox jumped over the lazy dog.");
    _sampleText.setVerticalAlignment(SwingConstants.TOP);
  }
  /** Returns whether the user clicked OK when the dialog was closed. (If false, the user clicked cancel.) */
  public boolean clickedOK() { return _clickedOK; }
  /** Returns the currently selected Font. */
  public Font getFont() { return _sampleText.getFont(); }
  /** Private inner class for a list which displays a list of options in addition to a label indicating the currently
    * selected item.
    */
  public class NwList extends JPanel {
    JList jl;
    JScrollPane sp;
    JLabel jt;
    String si = " ";
    public NwList(String[] values) {
      setLayout(null);
      jl = new JList(values);
      sp = new JScrollPane(jl);
      jt = new JLabel();
      jt.setBackground(Color.white);
      jt.setForeground(Color.black);
      jt.setOpaque(true);
      jt.setBorder(new JTextField().getBorder());
      jt.setFont(getFont());
      jl.addListSelectionListener(new ListSelectionListener() {
        public void valueChanged(ListSelectionEvent e) {
          jt.setText((String) jl.getSelectedValue());
          si = (String) jl.getSelectedValue();
          showSample();
        }
      });
      add(sp);
      add(jt);
    }
    public void setBounds(int x, int y, int w, int h) {
      super.setBounds(x, y, w, h);
      sp.setBounds(0, y + 16, w, h - 23);
      sp.revalidate();
      jt.setBounds(0, 0, w, 20);
    }
    public String getSelectedValue() { return (si); }
    public void setSelectedItem(String s) { jl.setSelectedValue(s, true);}
  }
}




FontChooser by Noah w

   
/* This code was found posted on a forum without any copyright
 * restrictions. It was written by someone named Noah W.
 * That"s all I know */
/* I have modified the original code but claim no copyright on it of any kind */

/*
This file is part of BORG.
    BORG is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    BORG is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with BORG; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Copyright 2003 by Mike Berger
 */

import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Enumeration;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.plaf.FontUIResource;

//
// FontChooser by Noah w.
//
public class NwFontChooserS extends JDialog {
    String[] styleList = new String[] { "Plain", "Bold", "Italic" };
    String[] sizeList =
    new String[] {
        "3",
        "4",
        "5",
        "6",
        "7",
        "8",
        "9",
        "10",
        "11",
        "12",
        "13",
        "14",
        "15",
        "16",
        "17",
        "18",
        "19",
        "20",
        "22",
        "24",
        "27",
        "30",
        "34",
        "39",
        "45",
        "51",
        "60" };
        NwList StyleList;
        NwList FontList;
        NwList SizeList;
        static JLabel Sample = new JLabel();
        boolean ob = false;
        
        private NwFontChooserS(Frame parent, boolean modal, Font font) {
            super(parent, modal);
            initAll();
            setTitle("Font Choosr");
            if (font == null)
                font = Sample.getFont();
            FontList.setSelectedItem(font.getName());
            SizeList.setSelectedItem(font.getSize() + "");
            StyleList.setSelectedItem(styleList[font.getStyle()]);
            
        }
        public static Font showDialog(Frame parent, String s, Font font) {
            NwFontChooserS fd = new NwFontChooserS(parent, true, font);
            if (s != null)
                fd.setTitle(s);
            fd.setVisible(true);
            Font fo = null;
            if (fd.ob)
                fo = Sample.getFont();
            fd.dispose();
            return (fo);
        }
        private void initAll() {
            getContentPane().setLayout(null);
            setBounds(50, 50, 450, 450);
            addLists();
            addButtons();
            Sample.setBounds(10, 320, 415, 25);
            Sample.setForeground(Color.black);
            getContentPane().add(Sample);
            addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    setVisible(false);
                }
            });
        }
        private void addLists() {
            FontList =
            new NwList(
            GraphicsEnvironment
            .getLocalGraphicsEnvironment()
            .getAvailableFontFamilyNames());
            StyleList = new NwList(styleList);
            SizeList = new NwList(sizeList);
            FontList.setBounds(10, 10, 260, 295);
            StyleList.setBounds(280, 10, 80, 295);
            SizeList.setBounds(370, 10, 40, 295);
            getContentPane().add(FontList);
            getContentPane().add(StyleList);
            getContentPane().add(SizeList);
        }
        private void addButtons() {
            JButton ok = new JButton("OK");
            ok.setMargin(new Insets(0, 0, 0, 0));
            JButton ca = new JButton("Cancel");
            ca.setMargin(new Insets(0, 0, 0, 0));
            ok.setBounds(260, 350, 70, 20);
            ok.setFont(new Font(" ", 1, 11));
            ca.setBounds(340, 350, 70, 20);
            ca.setFont(new Font(" ", 1, 12));
            getContentPane().add(ok);
            getContentPane().add(ca);
            ok.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    setVisible(false);
                    ob = true;
                }
            });
            ca.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    setVisible(false);
                    ob = false;
                }
            });
        }
        private void showSample() {
            int g = 0;
            try {
                g = Integer.parseInt(SizeList.getSelectedValue());
            }
            catch (NumberFormatException nfe) {
            }
            String st = StyleList.getSelectedValue();
            int s = Font.PLAIN;
            if (st.equalsIgnoreCase("Bold"))
                s = Font.BOLD;
            if (st.equalsIgnoreCase("Italic"))
                s = Font.ITALIC;
            Sample.setFont(new Font(FontList.getSelectedValue(), s, g));
            Sample.setText("The quick brown fox jumped over the lazy dog.");
        }
        //////////////////////////////////////////////////////////////////////
        private class NwList extends JPanel {
            JList jl;
            JScrollPane sp;
            JLabel jt;
            String si = " ";
            
            public NwList(String[] values) {
                setLayout(null);
                jl = new JList(values);
                sp = new JScrollPane(jl);
                jt = new JLabel();
                jt.setBackground(Color.white);
                jt.setForeground(Color.black);
                jt.setOpaque(true);
                jt.setBorder(new JTextField().getBorder());
                jt.setFont(getFont());
                jl.setBounds(0, 0, 100, 1000);
                jl.setBackground(Color.white);
                jl.addListSelectionListener(new ListSelectionListener() {
                    public void valueChanged(ListSelectionEvent e) {
                        jt.setText((String) jl.getSelectedValue());
                        si = (String) jl.getSelectedValue();
                        showSample();
                    }
                });
                add(sp);
                add(jt);
            }
            public String getSelectedValue() {
                return (si);
            }
            public void setSelectedItem(String s) {
                jl.setSelectedValue(s, true);
            }
            public void setBounds(int x, int y, int w, int h) {
                super.setBounds(x, y, w, h);
                sp.setBounds(0, y + 12, w, h - 23);
                sp.revalidate();
                jt.setBounds(0, 0, w, 20);
            }
        }
        
        static public String fontString(Font font) {
            String fs = font.getFamily();
            if( !font.isPlain() ) {
                fs += "-";
                if( font.isBold()) {
                    fs += "BOLD";
                }
                if( font.isItalic()) {
                    fs += "ITALIC";
                }
            }
            fs += "-" + font.getSize();
            return(fs);
        }
        
        static public void setDefaultFont(Font f ) {
            FontUIResource fui = new FontUIResource(f);
            Enumeration<Object> keys = UIManager.getDefaults().keys();
            while (keys.hasMoreElements()) {
                Object key = keys.nextElement();
                Object value = UIManager.get(key);
                if (value instanceof FontUIResource)
                    UIManager.put(key, fui);
            }
            
        }
        
        public static void main(String args[]) {
            Font font = null;
            font = NwFontChooserS.showDialog(null, null, null);
            
            System.out.println(fontString(font));
        }
}




Font Chooser extends javax.swing.JDialog

   
/*
Atlantida is an open source (GPL) multilingual dictionary written in Java.
It can translate words from one language to another and pronounce them.
Copyright (C) 2006 Sergey S. http://atla.revdanica.ru/
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
/**
* FontChooser
* @author Janos Szatmary, Sergei S.
* @version 003
*/
/*
 * http://forum.java.sun.ru/thread.jsp?forum=57&thread=124810
 * For those who asked where"s the constructor, have in mind that the constructor provided
 * is private. As the author of the code says, the use of this class is as
 * follows (supposing we are in a Frame class):
 * FontChooser.showDialog(this,"FontChooser",new Font("Dialog", 0, 12));
 * This file originally writter by Janos Szatmary, then modifyed by Sergei S. for
 * Atlantida Multilingual Dictionary http://atla.sf.net
*/

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class FontChooser extends javax.swing.JDialog
{
  String[] styleList = new String[]
  { "Plain","Bold","Italic"};
  String[] sizeList = new String[]
  { "2","4","6","8","10","12","14","16","18","20","22","24","30","36","48","72"};
  String currentFont = null;
  int currentStyle = -1;
  int currentSize = -1;
  public boolean ok = false;
  /* ------------------------------------------------------------- */
  private FontChooser(java.awt.Frame parent,boolean modal)
  {
    super (parent,modal);
    initComponents();
    setListValues(jFontList,GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames());
    setListValues(jStyleList,styleList);
    setListValues(jSizeList,sizeList);
    setCurrentFont(jSample.getFont());
    pack();
  }
  private FontChooser(java.awt.Frame parent,boolean modal,Font font)
  {
    this(parent,modal);
    setCurrentFont(font);
  }
  /* ------------------------------------------------------------- */
  private void setListValues(JList list,String[] values)
  {
    if(list.getModel() instanceof DefaultListModel)
    {
      DefaultListModel model = (DefaultListModel)
                               list.getModel();
      model.removeAllElements();
      for( String value : values )
      {
        model.addElement( value );
      }
    }
  }
  /* ------------------------------------------------------------- */
  private void setSampleFont()
  {
    if(currentFont != null && currentStyle >= 0 && currentSize > 0)
    {
      jSample.setFont(new Font
                      (currentFont,currentStyle,currentSize));
    }
  }
  private String styleToString(int style)
  {
    String str = "";
    if((style&Font.BOLD) == Font.BOLD)
    {
      if(str.length() > 0)
      {
        str += ",";
      }
      str += "Bold";
    }
    if((style&Font.ITALIC) == Font.ITALIC)
    {
      if(str.length() > 0)
      {
        str += ",";
      }
      str += "Italic";
    }
    if( str.length() <= 0 )
    {
      str = "Plain";
    }
    return str;
  }
  /* ------------------------------------------------------------- */
  public Font getCurrentFont()
  {
    return jSample.getFont();
  }
  /* ------------------------------------------------------------- */
  public void setCurrentFont(Font font)
  {
    if(font==null)
    {
      font = jSample.getFont();
    }
    jFont.setText(font.getName());
    jFontActionPerformed(null);
    jStyle.setText(styleToString(font.getStyle()));
    jStyleActionPerformed(null);
    jSize.setText(Integer.toString(font.getSize()));
    jSizeActionPerformed(null);
  }

  // Create font chooser dialog.
  // If user selected a font (i.e. clicked OK button) - return the font that user has selected.
  // If user didn"t click OK button - return "null".
  public static Font showDialog( Frame parent, String title, Font font)
  {
    FontChooser dialog = new FontChooser(parent,true,font);
    Point p1 = parent.getLocation();
    Dimension d1 = parent.getSize();
    Dimension d2 = dialog.getSize();
    int x = p1.x+(d1.width-d2.width)/2;
    int y = p1.y+(d1.height-d2.height)/2;
    if(x < 0)
    {
      x = 0;
    }
    if(y < 0)
    {
      y = 0;
    }
    if(title!=null)
    {
      dialog.setTitle(title);
    }
    dialog.setLocation(x,y);
    dialog.setVisible(true);
    Font newfont = null;
    if(dialog.ok)
    {
      newfont = dialog.getCurrentFont();
    }
    dialog.dispose();
    return newfont;
  }
  /** This method is called from within the constructor to
  * initialize the form.
  * WARNING: Do NOT modify this code. The content of this method is
  * always regenerated by the FormEditor.
  */
  private void initComponents()
  {
    jPanel3 = new javax.swing.JPanel();
    jFont = new javax.swing.JTextField();
    jScrollPane1 = new javax.swing.JScrollPane();
    jFontList = new javax.swing.JList();
    jPanel4 = new javax.swing.JPanel();
    jStyle = new javax.swing.JTextField();
    jScrollPane2 = new javax.swing.JScrollPane();
    jStyleList = new javax.swing.JList();
    jPanel5 = new javax.swing.JPanel();
    jSize = new javax.swing.JTextField();
    jScrollPane3 = new javax.swing.JScrollPane();
    jSizeList = new javax.swing.JList();
    jPanel1 = new javax.swing.JPanel();
    jScrollPane4 = new javax.swing.JScrollPane();
    jSample = new javax.swing.JTextArea();
    jButtons = new javax.swing.JPanel();
    jOk = new javax.swing.JButton();
    jCancel = new javax.swing.JButton();
    jLabel6 = new javax.swing.JLabel();
    getContentPane().setLayout(new java.awt.GridBagLayout());
    java.awt.GridBagConstraints gridBagConstraints1;
    setTitle("Font Chooser");
    addWindowListener(new java.awt.event.WindowAdapter()
                      {
                        public void windowClosing(java.awt.event.WindowEvent evt)
                        {
                          closeDialog(evt);
                        }
                      }
                     );
    jPanel3.setLayout(new java.awt.GridBagLayout());
    java.awt.GridBagConstraints gridBagConstraints2;
    jPanel3.setBorder(new javax.swing.border.TitledBorder(new javax.swing.border.EtchedBorder(), " Font "));
    jFont.setColumns(24);
    jFont.addActionListener(new java.awt.event.ActionListener()
                            {
                              public void actionPerformed(java.awt.event.ActionEvent evt)
                              {
                                jFontActionPerformed(evt);
                              }
                            }
                           );
    gridBagConstraints2 = new java.awt.GridBagConstraints();
    gridBagConstraints2.gridwidth = 0;
    gridBagConstraints2.fill =
    java.awt.GridBagConstraints.HORIZONTAL;
    gridBagConstraints2.insets = new java.awt.Insets(0, 3, 0, 3);
    gridBagConstraints2.anchor = java.awt.GridBagConstraints.NORTHWEST;
    gridBagConstraints2.weightx = 1.0;
    jPanel3.add(jFont, gridBagConstraints2);

    jFontList.setModel(new DefaultListModel());
    jFontList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
    jFontList.addListSelectionListener(new javax.swing.event.ListSelectionListener()
                                       {
                                         public void valueChanged(javax.swing.event.ListSelectionEvent evt)
                                         {
                                           jFontListValueChanged(evt);
                                         }
                                       }
                                      );
    jScrollPane1.setViewportView(jFontList);
    gridBagConstraints2 = new java.awt.GridBagConstraints();
    gridBagConstraints2.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints2.insets = new java.awt.Insets(3, 3, 3, 3);
    gridBagConstraints2.anchor = java.awt.GridBagConstraints.NORTHWEST;
    gridBagConstraints2.weightx = 1.0;
    gridBagConstraints2.weighty = 1.0;
    jPanel3.add(jScrollPane1, gridBagConstraints2);

    gridBagConstraints1 = new java.awt.GridBagConstraints();
    gridBagConstraints1.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints1.insets = new java.awt.Insets(5, 5, 0, 0);
    gridBagConstraints1.weightx = 0.5;
    gridBagConstraints1.weighty = 1.0;
    getContentPane().add(jPanel3, gridBagConstraints1);

    jPanel4.setLayout(new java.awt.GridBagLayout());
    java.awt.GridBagConstraints gridBagConstraints3;
    jPanel4.setBorder(new javax.swing.border.TitledBorder(new javax.swing.border.EtchedBorder(), " Style "));
    jStyle.setColumns(18);
    jStyle.addActionListener(new java.awt.event.ActionListener()
                             {
                               public void actionPerformed(java.awt.event.ActionEvent evt)
                               {
                                 jStyleActionPerformed(evt);
                               }
                             }
                            );
    gridBagConstraints3 = new java.awt.GridBagConstraints();
    gridBagConstraints3.gridwidth = 0;
    gridBagConstraints3.fill =
    java.awt.GridBagConstraints.HORIZONTAL;
    gridBagConstraints3.insets = new java.awt.Insets(0, 3, 0, 3);
    gridBagConstraints3.anchor = java.awt.GridBagConstraints.NORTHWEST;
    gridBagConstraints3.weightx = 1.0;
    jPanel4.add(jStyle, gridBagConstraints3);
    jStyleList.setModel(new DefaultListModel());
    jStyleList.setVisibleRowCount(4);
    jStyleList.addListSelectionListener(new javax.swing.event.ListSelectionListener()
                                        {
                                          public void valueChanged(javax.swing.event.ListSelectionEvent evt)
                                          {
                                            jStyleListValueChanged(evt);
                                          }
                                        }
                                       );
    jScrollPane2.setViewportView(jStyleList);
    gridBagConstraints3 = new java.awt.GridBagConstraints();
    gridBagConstraints3.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints3.insets = new java.awt.Insets(3, 3, 3, 3);
    gridBagConstraints3.anchor = java.awt.GridBagConstraints.NORTHWEST;
    gridBagConstraints3.weightx = 0.5;
    gridBagConstraints3.weighty = 1.0;
    jPanel4.add(jScrollPane2, gridBagConstraints3);
    gridBagConstraints1 = new java.awt.GridBagConstraints();
    gridBagConstraints1.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints1.insets = new java.awt.Insets(5, 5, 0, 0);
    gridBagConstraints1.weightx = 0.375;
    gridBagConstraints1.weighty = 1.0;
    getContentPane().add(jPanel4, gridBagConstraints1);
    jPanel5.setLayout(new java.awt.GridBagLayout());
    java.awt.GridBagConstraints gridBagConstraints4;
    jPanel5.setBorder(new javax.swing.border.TitledBorder(new javax.swing.border.EtchedBorder(), " Size "));
    jSize.setColumns(6);
    jSize.addActionListener(new
                            java.awt.event.ActionListener()
                            {
                              public void actionPerformed(java.awt.event.ActionEvent evt)
                              {
                                jSizeActionPerformed(evt);
                              }
                            }
                           );
    gridBagConstraints4 = new java.awt.GridBagConstraints();
    gridBagConstraints4.gridwidth = 0;
    gridBagConstraints4.fill = java.awt.GridBagConstraints.HORIZONTAL;
    gridBagConstraints4.insets = new java.awt.Insets(0, 3, 0, 3);
    gridBagConstraints4.anchor = java.awt.GridBagConstraints.NORTHWEST;
    gridBagConstraints4.weightx = 1.0;
    jPanel5.add(jSize, gridBagConstraints4);
    jSizeList.setModel(new DefaultListModel());
    jSizeList.setVisibleRowCount(4);
    jSizeList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
    jSizeList.addListSelectionListener(new javax.swing.event.ListSelectionListener()
                                       {
                                         public void valueChanged(javax.swing.event.ListSelectionEvent evt)
                                         {
                                           jSizeListValueChanged(evt);
                                         }
                                       }
                                      );
    jScrollPane3.setViewportView(jSizeList);
    gridBagConstraints4 = new java.awt.GridBagConstraints();
    gridBagConstraints4.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints4.insets = new java.awt.Insets(3, 3, 3, 3);
    gridBagConstraints4.anchor = java.awt.GridBagConstraints.NORTHWEST;
    gridBagConstraints4.weightx = 0.25;
    gridBagConstraints4.weighty = 1.0;
    jPanel5.add(jScrollPane3, gridBagConstraints4);
    gridBagConstraints1 = new java.awt.GridBagConstraints();
    gridBagConstraints1.gridwidth = 0;
    gridBagConstraints1.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints1.insets = new java.awt.Insets(5, 5, 0, 5);
    gridBagConstraints1.weightx = 0.125;
    gridBagConstraints1.weighty = 1.0;
    getContentPane().add(jPanel5, gridBagConstraints1);
    jPanel1.setLayout(new java.awt.GridBagLayout());
    java.awt.GridBagConstraints gridBagConstraints5;
    jPanel1.setBorder(new javax.swing.border.TitledBorder(new javax.swing.border.EtchedBorder(), " Sample "));
    jSample.setWrapStyleWord(true);
    jSample.setLineWrap(true);
    jSample.setColumns(20);
    jSample.setRows(3);
    jSample.setText("The quick brown fox jumped over the lazy dog.");
    jScrollPane4.setViewportView(jSample);
    gridBagConstraints5 = new java.awt.GridBagConstraints();
    gridBagConstraints5.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints5.insets = new java.awt.Insets(0, 3, 3, 3);
    gridBagConstraints5.weightx = 1.0;
    gridBagConstraints5.weighty = 1.0;
    jPanel1.add(jScrollPane4, gridBagConstraints5);
    gridBagConstraints1 = new java.awt.GridBagConstraints();
    gridBagConstraints1.gridwidth = 0;
    gridBagConstraints1.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints1.insets = new java.awt.Insets(0, 5, 0, 5);
    gridBagConstraints1.anchor = java.awt.GridBagConstraints.NORTHWEST;
    gridBagConstraints1.weightx = 1.0;
    getContentPane().add(jPanel1, gridBagConstraints1);
    jButtons.setLayout(new java.awt.GridBagLayout());
    java.awt.GridBagConstraints gridBagConstraints6;
    jOk.setMnemonic(KeyEvent.VK_O);
    jOk.setText("OK");
    jOk.setRequestFocusEnabled(false);
    jOk.addActionListener(new java.awt.event.ActionListener()
                          {
                            public void actionPerformed(java.awt.event.ActionEvent evt)
                            {
                              jOkActionPerformed(evt);
                            }
                          }
                         );
    gridBagConstraints6 = new java.awt.GridBagConstraints();
    gridBagConstraints6.insets = new java.awt.Insets(5, 5, 5, 0);
    gridBagConstraints6.anchor = java.awt.GridBagConstraints.WEST;
    jButtons.add(jOk, gridBagConstraints6);

    jCancel.setMnemonic(KeyEvent.VK_C);
    jCancel.setText("Cancel");
    jCancel.setRequestFocusEnabled(false);
    jCancel.addActionListener(new
                              java.awt.event.ActionListener()
                              {
                                public void actionPerformed(java.awt.event.ActionEvent evt)
                                {
                                  jCancelActionPerformed(evt);
                                }
                              }
                             );
    gridBagConstraints6 = new java.awt.GridBagConstraints();
    gridBagConstraints6.gridwidth = 0;
    gridBagConstraints6.insets = new java.awt.Insets(5, 5, 5, 5);
    gridBagConstraints6.anchor = java.awt.GridBagConstraints.WEST;
    gridBagConstraints6.weightx = 1.0;
    jButtons.add(jCancel, gridBagConstraints6);
    gridBagConstraints6 = new java.awt.GridBagConstraints();
    gridBagConstraints6.weightx = 1.0;
    jButtons.add(jLabel6, gridBagConstraints6);
    gridBagConstraints1 = new java.awt.GridBagConstraints();
    gridBagConstraints1.gridwidth = 0;
    gridBagConstraints1.anchor = java.awt.GridBagConstraints.SOUTHWEST;
    gridBagConstraints1.weightx = 1.0;
    getContentPane().add(jButtons, gridBagConstraints1);
  }
  private void jCancelActionPerformed(java.awt.event.ActionEvent evt)
  {
    // Add your handling code here:
    setVisible(false);
  }
  private void jOkActionPerformed (java.awt.event.ActionEvent evt)
  {
    // Add your handling code here:
    ok = true;
    setVisible(false);
  }
  private void jSizeActionPerformed (java.awt.event.ActionEvent evt)
  {
    // Add your handling code here:
    int size = Integer.parseInt(jSize.getText());
    if(size > 0)
    {
      currentSize = size;
      setSampleFont();
    }
  }
  private void jStyleActionPerformed (java.awt.event.ActionEvent evt)
  {
    // Add your handling code here:
    StringTokenizer st = new StringTokenizer(jStyle.getText(),",");
    int style = 0;
    while(st.hasMoreTokens())
    {
      String str = st.nextToken().trim();
      if(str.equalsIgnoreCase("Plain"))
      {
        style |= Font.PLAIN;
      }
      else
        if(str.equalsIgnoreCase("Bold"))
      {
        style |= Font.BOLD;
      }
      else
        if(str.equalsIgnoreCase("Italic"))
      {
        style |= Font.ITALIC;
      }
    }
    if(style >= 0)
    {
      currentStyle = style;
      setSampleFont();
    }
  }
  private void jFontActionPerformed (java.awt.event.ActionEvent evt)
  {
    // Add your handling code here:
    DefaultListModel model = (DefaultListModel)
                             jFontList.getModel();
    if(model.indexOf(jFont.getText()) >= 0)
    {
      currentFont = jFont.getText();
      setSampleFont();
    }
  }
  private void jStyleListValueChanged(javax.swing.event.ListSelectionEvent evt)
  {
    // Add your handling code here:
    String str = "";
    Object[] values = jStyleList.getSelectedValues();
    if(values.length > 0)
    {
      int j;
      for(j=0; j < values.length; j++)
      {
        String s = (String) values[j];
        if(s.equalsIgnoreCase("Plain"))
        {
          str = "Plain";  break;
        }
        if(str.length() > 0)
        {
          str += ",";
        }
        str += (String) values[j];
      }
    }
    else
    {
      str = styleToString(currentStyle);
    }
    jStyle.setText(str);
    jStyleActionPerformed(null);
  }
  private void jSizeListValueChanged(javax.swing.event.ListSelectionEvent evt)
  {
    // Add your handling code here:
    String str = (String) jSizeList.getSelectedValue();
    if(str==null || str.length() <= 0)
    {
      str = Integer.toString(currentSize);
    }
    jSize.setText(str);
    jSizeActionPerformed(null);
  }
  private void jFontListValueChanged(javax.swing.event.ListSelectionEvent evt)
  {
    // Add your handling code here:
    String str = (String) jFontList.getSelectedValue();
    if(str==null || str.length() <= 0)
    {
      str = currentFont;
    }
    jFont.setText(str);
    jFontActionPerformed(null);
  }
  /** Closes the dialog */
  private void closeDialog(java.awt.event.WindowEvent evt)
  {
    setVisible (false);
  }
  // Variables declaration - do not modify
  private javax.swing.JPanel jPanel3;
  private javax.swing.JTextField jFont;
  private javax.swing.JScrollPane jScrollPane1;
  private javax.swing.JList jFontList;
  private javax.swing.JPanel jPanel4;
  private javax.swing.JTextField jStyle;
  private javax.swing.JScrollPane jScrollPane2;
  private javax.swing.JList jStyleList;
  private javax.swing.JPanel jPanel5;
  private javax.swing.JTextField jSize;
  private javax.swing.JScrollPane jScrollPane3;
  private javax.swing.JList jSizeList;
  private javax.swing.JPanel jPanel1;
  private javax.swing.JScrollPane jScrollPane4;
  private javax.swing.JTextArea jSample;
  private javax.swing.JPanel jButtons;
  private javax.swing.JButton jOk;
  private javax.swing.JButton jCancel;
  private javax.swing.JLabel jLabel6;
  // End of variables declaration
}




Font Chooser Source Code

Font dialog

 
/* 
 * JCommon : a free general purpose class library for the Java(tm) platform
 * 
 *
 * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
 * 
 * Project Info:  http://www.jfree.org/jcommon/index.html
 *
 * This library is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License as published by 
 * the Free Software Foundation; either version 2.1 of the License, or 
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
 * USA.  
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
 * in the United States and other countries.]
 * 
 * ----------------------
 * FontChooserDialog.java
 * ----------------------
 * (C) Copyright 2000-2004, by Object Refinery Limited.
 *
 * Original Author:  David Gilbert (for Object Refinery Limited);
 * Contributor(s):   -;
 *
 * $Id: FontChooserDialog.java,v 1.5 2007/11/02 17:50:36 taqua Exp $
 *
 * Changes (from 26-Oct-2001)
 * --------------------------
 * 26-Oct-2001 : Changed package to com.jrefinery.ui.*;
 * 14-Oct-2002 : Fixed errors reported by Checkstyle (DG);
 *
 */
import java.awt.BorderLayout;
import java.awt.Dialog;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GraphicsEnvironment;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListModel;
/**
 * A dialog for choosing a font from the available system fonts.
 *
 * @author David Gilbert
 */
public class FontChooserDialog extends StandardDialog {
    /** The panel within the dialog that contains the font selection controls. */
    private FontChooserPanel fontChooserPanel;
    /**
     * Standard constructor - builds a font chooser dialog owned by another dialog.
     *
     * @param owner  the dialog that "owns" this dialog.
     * @param title  the title for the dialog.
     * @param modal  a boolean that indicates whether or not the dialog is modal.
     * @param font  the initial font displayed.
     */
    public FontChooserDialog(final Dialog owner, final String title, final boolean modal, final Font font) {
        super(owner, title, modal);
        setContentPane(createContent(font));
    }
    /**
     * Standard constructor - builds a font chooser dialog owned by a frame.
     *
     * @param owner  the frame that "owns" this dialog.
     * @param title  the title for the dialog.
     * @param modal  a boolean that indicates whether or not the dialog is modal.
     * @param font  the initial font displayed.
     */
    public FontChooserDialog(final Frame owner, final String title, final boolean modal, final Font font) {
        super(owner, title, modal);
        setContentPane(createContent(font));
    }
    /**
     * Returns the selected font.
     *
     * @return the font.
     */
    public Font getSelectedFont() {
        return this.fontChooserPanel.getSelectedFont();
    }
    /**
     * Returns the panel that is the user interface.
     *
     * @param font  the font.
     *
     * @return the panel.
     */
    private JPanel createContent(Font font) {
        final JPanel content = new JPanel(new BorderLayout());
        content.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
        if (font == null) {
            font = new Font("Dialog", 10, Font.PLAIN);
        }
        this.fontChooserPanel = new FontChooserPanel(font);
        content.add(this.fontChooserPanel);
        final JPanel buttons = createButtonPanel();
        buttons.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));
        content.add(buttons, BorderLayout.SOUTH);
        return content;
    }
}
/* 
 * JCommon : a free general purpose class library for the Java(tm) platform
 * s
 *
 * (C) Copyright 2000-2008, by Object Refinery Limited and Contributors.
 *
 * Project Info:  http://www.jfree.org/jcommon/index.html
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
 * USA.
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
 * in the United States and other countries.]
 *
 * ---------------------
 * FontChooserPanel.java
 * ---------------------
 * (C) Copyright 2000-2008, by Object Refinery Limited.
 *
 * Original Author:  David Gilbert (for Object Refinery Limited);
 * Contributor(s):   Arnaud Lelievre;
 *
 * $Id: FontChooserPanel.java,v 1.6 2008/12/18 09:57:32 mungady Exp $
 *
 * Changes (from 26-Oct-2001)
 * --------------------------
 * 26-Oct-2001 : Changed package to com.jrefinery.ui.*;
 * 14-Oct-2002 : Fixed errors reported by Checkstyle (DG);
 * 08-Sep-2003 : Added internationalization via use of properties resourceBundle (RFE 690236) (AL);
 * 21-Feb-2004 : The FontParameter of the constructor was never used (TM);
 * 18-Dec-2008 : Use ResourceBundleWrapper - see JFreeChart patch 1607918 by
 *               Jess Thrysoee (DG);
 *
 */
/**
 * A panel for choosing a font from the available system fonts - still a bit of
 * a hack at the moment, but good enough for demonstration applications.
 *
 * @author David Gilbert
 */
class FontChooserPanel extends JPanel {
    /** The font sizes that can be selected. */
    public static final String[] SIZES = {"9", "10", "11", "12", "14", "16",
            "18", "20", "22", "24", "28", "36", "48", "72"};
    /** The list of fonts. */
    private JList fontlist;
    /** The list of sizes. */
    private JList sizelist;
    /** The checkbox that indicates whether the font is bold. */
    private JCheckBox bold;
    /** The checkbox that indicates whether or not the font is italic. */
    private JCheckBox italic;

    /**
     * Standard constructor - builds a FontChooserPanel initialised with the
     * specified font.
     *
     * @param font  the initial font to display.
     */
    public FontChooserPanel(final Font font) {
        final GraphicsEnvironment g
                = GraphicsEnvironment.getLocalGraphicsEnvironment();
        final String[] fonts = g.getAvailableFontFamilyNames();
        setLayout(new BorderLayout());
        final JPanel right = new JPanel(new BorderLayout());
        final JPanel fontPanel = new JPanel(new BorderLayout());
        fontPanel.setBorder(BorderFactory.createTitledBorder(
                            BorderFactory.createEtchedBorder(),
                            "Font"));
        this.fontlist = new JList(fonts);
        final JScrollPane fontpane = new JScrollPane(this.fontlist);
        fontpane.setBorder(BorderFactory.createEtchedBorder());
        fontPanel.add(fontpane);
        add(fontPanel);
        final JPanel sizePanel = new JPanel(new BorderLayout());
        sizePanel.setBorder(BorderFactory.createTitledBorder(
                            BorderFactory.createEtchedBorder(),
                            "Size"));
        this.sizelist = new JList(SIZES);
        final JScrollPane sizepane = new JScrollPane(this.sizelist);
        sizepane.setBorder(BorderFactory.createEtchedBorder());
        sizePanel.add(sizepane);
        final JPanel attributes = new JPanel(new GridLayout(1, 2));
        this.bold = new JCheckBox("Bold");
        this.italic = new JCheckBox("Italic");
        attributes.add(this.bold);
        attributes.add(this.italic);
        attributes.setBorder(BorderFactory.createTitledBorder(
                BorderFactory.createEtchedBorder(),
                "Attributes"));
        right.add(sizePanel, BorderLayout.CENTER);
        right.add(attributes, BorderLayout.SOUTH);
        add(right, BorderLayout.EAST);
        setSelectedFont(font);
    }
    /**
     * Returns a Font object representing the selection in the panel.
     *
     * @return the font.
     */
    public Font getSelectedFont() {
        return new Font(getSelectedName(), getSelectedStyle(),
                getSelectedSize());
    }
    /**
     * Returns the selected name.
     *
     * @return the name.
     */
    public String getSelectedName() {
        return (String) this.fontlist.getSelectedValue();
    }
    /**
     * Returns the selected style.
     *
     * @return the style.
     */
    public int getSelectedStyle() {
        if (this.bold.isSelected() && this.italic.isSelected()) {
            return Font.BOLD + Font.ITALIC;
        }
        if (this.bold.isSelected()) {
            return Font.BOLD;
        }
        if (this.italic.isSelected()) {
            return Font.ITALIC;
        }
        else {
            return Font.PLAIN;
        }
    }
    /**
     * Returns the selected size.
     *
     * @return the size.
     */
    public int getSelectedSize() {
        final String selected = (String) this.sizelist.getSelectedValue();
        if (selected != null) {
            return Integer.parseInt(selected);
        }
        else {
            return 10;
        }
    }
    /**
     * Initializes the contents of the dialog from the given font
     * object.
     *
     * @param font the font from which to read the properties.
     */
    public void setSelectedFont (final Font font) {
        if (font == null) {
            throw new NullPointerException();
        }
        this.bold.setSelected(font.isBold());
        this.italic.setSelected(font.isItalic());
        final String fontName = font.getName();
        ListModel model = this.fontlist.getModel();
        this.fontlist.clearSelection();
        for (int i = 0; i < model.getSize(); i++) {
            if (fontName.equals(model.getElementAt(i))) {
                this.fontlist.setSelectedIndex(i);
                break;
            }
        }
        final String fontSize = String.valueOf(font.getSize());
        model = this.sizelist.getModel();
        this.sizelist.clearSelection();
        for (int i = 0; i < model.getSize(); i++) {
            if (fontSize.equals(model.getElementAt(i))) {
                this.sizelist.setSelectedIndex(i);
                break;
            }
        }
    }
}
/* 
 * JCommon : a free general purpose class library for the Java(tm) platform
 * 
 *
 * (C) Copyright 2000-2008, by Object Refinery Limited and Contributors.
 *
 * Project Info:  http://www.jfree.org/jcommon/index.html
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
 * USA.
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
 * in the United States and other countries.]
 *
 * -------------------
 * StandardDialog.java
 * -------------------
 * (C) Copyright 2000-2008, by Object Refinery Limited.
 *
 * Original Author:  David Gilbert (for Object Refinery Limited);
 * Contributor(s):   Arnaud Lelievre;
 *
 * $Id: StandardDialog.java,v 1.7 2008/12/18 09:57:32 mungady Exp $
 *
 * Changes (from 26-Oct-2001)
 * --------------------------
 * 26-Oct-2001 : Changed package to com.jrefinery.ui.*;
 * 08-Sep-2003 : Added internationalization via use of properties
 *               resourceBundle (RFE 690236) (AL);
 * 18-Dec-2008 : Use ResourceBundleWrapper - see JFreeChart patch 1607918 by
 *               Jess Thrysoee (DG);
 *
 */

/**
 * The base class for standard dialogs.
 *
 * @author David Gilbert
 */
class StandardDialog extends JDialog implements ActionListener {
    /** Flag that indicates whether or not the dialog was cancelled. */
    private boolean cancelled;

    /**
     * Standard constructor - builds a dialog...
     *
     * @param owner  the owner.
     * @param title  the title.
     * @param modal  modal?
     */
    public StandardDialog(final Frame owner, final String title,
            final boolean modal) {
        super(owner, title, modal);
        this.cancelled = false;
    }
    /**
     * Standard constructor - builds a dialog...
     *
     * @param owner  the owner.
     * @param title  the title.
     * @param modal  modal?
     */
    public StandardDialog(final Dialog owner, final String title,
            final boolean modal) {
        super(owner, title, modal);
        this.cancelled = false;
    }
    /**
     * Returns a flag that indicates whether or not the dialog has been
     * cancelled.
     *
     * @return boolean.
     */
    public boolean isCancelled() {
        return this.cancelled;
    }
    /**
     * Handles clicks on the standard buttons.
     *
     * @param event  the event.
     */
    public void actionPerformed(final ActionEvent event) {
        final String command = event.getActionCommand();
        if (command.equals("helpButton")) {
            // display help information
        }
        else if (command.equals("okButton")) {
            this.cancelled = false;
            setVisible(false);
        }
        else if (command.equals("cancelButton")) {
            this.cancelled = true;
            setVisible(false);
        }
    }
    /**
     * Builds and returns the user interface for the dialog.  This method is
     * shared among the constructors.
     *
     * @return the button panel.
     */
    protected JPanel createButtonPanel() {
        final L1R2ButtonPanel buttons = new L1R2ButtonPanel(
                "Help",
                "OK",
                "Cancel");
        final JButton helpButton = buttons.getLeftButton();
        helpButton.setActionCommand("helpButton");
        helpButton.addActionListener(this);
        final JButton okButton = buttons.getRightButton1();
        okButton.setActionCommand("okButton");
        okButton.addActionListener(this);
        final JButton cancelButton = buttons.getRightButton2();
        cancelButton.setActionCommand("cancelButton");
        cancelButton.addActionListener(this);
        buttons.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));
        return buttons;
    }
}
/* 
 * JCommon : a free general purpose class library for the Java(tm) platform
 * 
 *
 * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
 * 
 * Project Info:  http://www.jfree.org/jcommon/index.html
 *
 * This library is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License as published by 
 * the Free Software Foundation; either version 2.1 of the License, or 
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
 * USA.  
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
 * in the United States and other countries.]
 * 
 * --------------------
 * L1R2ButtonPanel.java
 * --------------------
 * (C) Copyright 2000-2004, by Object Refinery Limited.
 *
 * Original Author:  David Gilbert (for Object Refinery Limited);
 * Contributor(s):   -;
 *
 * $Id: L1R2ButtonPanel.java,v 1.4 2007/11/02 17:50:36 taqua Exp $
 *
 * Changes (from 26-Oct-2001)
 * --------------------------
 * 26-Oct-2001 : Changed package to com.jrefinery.ui.*;
 * 26-Jun-2002 : Removed unnecessary import (DG);
 * 14-Oct-2002 : Fixed errors reported by Checkstyle (DG);
 *
 */

/**
 * A "ready-made" panel that has one button on the left and two buttons on the right - nested
 * panels and layout managers take care of resizing.
 *
 * @author David Gilbert
 */
class L1R2ButtonPanel extends JPanel {
    /** The left button. */
    private JButton left;
    /** The first button on the right of the panel. */
    private JButton right1;
    /** The second button on the right of the panel. */
    private JButton right2;
    /**
     * Standard constructor - creates a three button panel with the specified button labels.
     *
     * @param label1  the label for button 1.
     * @param label2  the label for button 2.
     * @param label3  the label for button 3.
     */
    public L1R2ButtonPanel(final String label1, final String label2, final String label3) {
        setLayout(new BorderLayout());
        // create the pieces...
        this.left = new JButton(label1);
        final JPanel rightButtonPanel = new JPanel(new GridLayout(1, 2));
        this.right1 = new JButton(label2);
        this.right2 = new JButton(label3);
        rightButtonPanel.add(this.right1);
        rightButtonPanel.add(this.right2);
        // ...and put them together
        add(this.left, BorderLayout.WEST);
        add(rightButtonPanel, BorderLayout.EAST);
    }
    /**
     * Returns a reference to button 1, allowing the caller to set labels, action-listeners etc.
     *
     * @return the left button.
     */
    public JButton getLeftButton() {
        return this.left;
    }
    /**
     * Returns a reference to button 2, allowing the caller to set labels, action-listeners etc.
     *
     * @return the right button 1.
     */
    public JButton getRightButton1() {
        return this.right1;
    }
    /**
     * Returns a reference to button 3, allowing the caller to set labels, action-listeners etc.
     *
     * @return  the right button 2.
     */
    public JButton getRightButton2() {
        return this.right2;
    }
}
/* 
 * JCommon : a free general purpose class library for the Java(tm) platform
 * 
 *
 * (C) Copyright 2000-2008, by Object Refinery Limited and Contributors.
 *
 * Project Info:  http://www.jfree.org/jcommon/index.html
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
 * USA.
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
 * in the United States and other countries.]
 *
 * ---------------------
 * FontDisplayField.java
 * ---------------------
 * (C) Copyright 2000-2008, by Object Refinery Limited.
 *
 * Original Author:  David Gilbert (for Object Refinery Limited);
 * Contributor(s):   Arnaud Lelievre;
 *
 * $Id: FontDisplayField.java,v 1.6 2008/12/18 09:57:32 mungady Exp $
 *
 * Changes (from 26-Oct-2001)
 * ----------------------------------
 * 26-Oct-2001 : Changed package to com.jrefinery.ui.*;
 * 14-Oct-2002 : Fixed errors reported by Checkstyle (DG);
 * 08-Sep-2003 : Added internationalization via use of properties
 *               resourceBundle (RFE 690236) (AL);
 * 18-Dec-2008 : Use ResourceBundleWrapper - see JFreeChart patch 1607918 by
 *               Jess Thrysoee (DG);
 *
 */

/**
 * A field for displaying a font selection.  The display field itself is
 * read-only, to the developer must provide another mechanism to allow the
 * user to change the font.
 *
 * @author David Gilbert
 */
class FontDisplayField extends JTextField {
    /** The current font. */
    private Font displayFont;

    /**
     * Standard constructor - builds a FontDescriptionField initialised with
     * the specified font.
     *
     * @param font  the font.
     */
    public FontDisplayField(final Font font) {
        super("");
        setDisplayFont(font);
        setEnabled(false);
    }
    /**
     * Returns the current font.
     *
     * @return the font.
     */
    public Font getDisplayFont() {
        return this.displayFont;
    }
    /**
     * Sets the font.
     *
     * @param font  the font.
     */
    public void setDisplayFont(final Font font) {
        this.displayFont = font;
        setText(fontToString(this.displayFont));
    }
    /**
     * Returns a string representation of the specified font.
     *
     * @param font  the font.
     *
     * @return a string describing the font.
     */
    private String fontToString(final Font font) {
        if (font != null) {
            return font.getFontName() + ", " + font.getSize();
        }
        else {
            return "No Font Selected";
        }
    }
}




Font Dialog from claribole

   
/*   FILE: FontDialog.java
 *   DATE OF CREATION:   Wed Jan 15 17:07:07 2002
 *   AUTHOR :            Emmanuel Pietriga (emmanuel@w3.org)
 *   MODIF:              Emmanuel Pietriga (emmanuel.pietriga@inria.fr)
 *   Copyright (c) Emmanuel Pietriga, 2002. All Rights Reserved
 *   Copyright (c) INRIA, 2008. All Rights Reserved
 *   Licensed under the GNU LGPL. For full terms see the file COPYING.
 *
 * $Id: FontDialog.java 1207 2008-08-13 16:03:07Z epietrig $
 */

import java.awt.Container;
import java.awt.Dialog;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ruponentAdapter;
import java.awt.event.ruponentEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.StringTokenizer;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class FontDialog extends JDialog implements ActionListener {
  static final String ZVTM_FONT_CHOOSER = "ZVTM Font Chooser";
    static String DEFAULT_FAMILY="Dialog";
    static int DEFAULT_STYLE=Font.PLAIN;
    static int DEFAULT_SIZE=10;
    FontTracker ft;
    JButton okBt,cancelBt;
    JList familyList,styleList,sizeList;
    String[] allFontFamilies=java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
    String[] allFontStyles={"Plain","Bold","Italic","BoldItalic"};
    String[] allFontSizes={"4","6","8","10","12","14","16","18","20","24"};
    
    /** Call a FontDialog window that will return  the font selected in the window
     *@param owner application frame that owns this Modal component
     */
    public static Font getFontDialog(Frame owner){
  FontTracker res=new FontTracker();
  FontDialog fd=new FontDialog(res,owner);
  fd.addWindowListener(new FontDialog.Closer());
        fd.addComponentListener(new FontDialog.DisposeOnClose());
  fd.setLocationRelativeTo(owner);
  fd.setVisible(true);  //blocks until the dialog is closed
  return res.getFont();
    }
    /** Call a FontDialog window that will return  the font selected in the window
     *@param owner application dialog that owns this Modal component
     */
    public static Font getFontDialog(Dialog owner){
  FontTracker res=new FontTracker();
  FontDialog fd=new FontDialog(res,owner);
  fd.addWindowListener(new FontDialog.Closer());
        fd.addComponentListener(new FontDialog.DisposeOnClose());
  fd.setLocationRelativeTo(owner);
  fd.setVisible(true);  //blocks until the dialog is closed
  return res.getFont();
    }
    /** Call a FontDialog window that will return  the font selected in the window
     *@param owner application frame that owns this Modal component
     *@param f a font giving the default parameters with which the dialog should be initialized (family, size, style)
     */
    public static Font getFontDialog(Frame owner,Font f){
  if (f!=null){
      DEFAULT_FAMILY=f.getFamily();
      DEFAULT_STYLE=f.getStyle();
      DEFAULT_SIZE=f.getSize();
  }
  FontTracker res=new FontTracker();
  FontDialog fd=new FontDialog(res,owner);
  fd.addWindowListener(new FontDialog.Closer());
        fd.addComponentListener(new FontDialog.DisposeOnClose());
  fd.setLocationRelativeTo(owner);
  fd.setVisible(true);  //blocks until the dialog is closed
  return res.getFont();
    }
    /** Call a FontDialog window that will return  the font selected in the window
     *@param owner application dialog that owns this Modal component
     *@param f a font giving the default parameters with which the dialog should be initialized (family, size, style)
     */
    public static Font getFontDialog(Dialog owner,Font f){
  if (f!=null){
      DEFAULT_FAMILY=f.getFamily();
      DEFAULT_STYLE=f.getStyle();
      DEFAULT_SIZE=f.getSize();
  }
  FontTracker res=new FontTracker();
  FontDialog fd=new FontDialog(res,owner);
  fd.addWindowListener(new FontDialog.Closer());
        fd.addComponentListener(new FontDialog.DisposeOnClose());
  fd.setLocationRelativeTo(owner);
  fd.setVisible(true);  //blocks until the dialog is closed
  return res.getFont();
    }
    /**
     * Font.decode does not seem to work that well, or I don;t understand how it is supposed to work
     * Anyway, this one does what I want (decodes family+" "+style+" "+size)
     */
    public static Font decode(String fontSpec){
  if (fontSpec!=null && fontSpec.length()>0){
      StringTokenizer st=new StringTokenizer(fontSpec," ",false);
      String[] tokens=new String[st.countTokens()];
      if (tokens.length>=3){
    int i=0;
    while (st.hasMoreTokens()) {
        tokens[i++]=st.nextToken();
    }
    String tokenizedFamily="";
    for (int j=0;j<tokens.length-3;j++){
        tokenizedFamily+=tokens[j]+" ";
    }
    tokenizedFamily+=tokens[tokens.length-3];
    String family=tokenizedFamily;if (family==null){family=DEFAULT_FAMILY;}
    String tokenizedStyle=tokens[tokens.length-2];
    String tokenizedSize=tokens[tokens.length-1];
    int style;
    if (tokenizedStyle.equals("Bold")){style=Font.BOLD;}
    else if (tokenizedStyle.equals("Italic")){style=Font.ITALIC;}
    else if (tokenizedStyle.equals("BoldItalic")){style=Font.BOLD+Font.ITALIC;}
    else {style=Font.PLAIN;}//"Plain"
    int size;
    try {
        size=Integer.parseInt(tokenizedSize);
        if (size<=0){size=DEFAULT_SIZE;}
    }
    catch (NumberFormatException ex){size=DEFAULT_SIZE;}
    return new Font(family,style,size);
      }
      else {return new Font(DEFAULT_FAMILY,DEFAULT_STYLE,DEFAULT_SIZE);}
  }
  else {return new Font(DEFAULT_FAMILY,DEFAULT_STYLE,DEFAULT_SIZE);}
    }
    FontDialog(FontTracker ftt,Frame owner){
  super(owner,ZVTM_FONT_CHOOSER,true);
  setLocation(owner.getLocation());
  ft=ftt;
  initUI();
    }
    FontDialog(FontTracker ftt,Dialog owner){
  super(owner,ZVTM_FONT_CHOOSER,true);
  setLocation(owner.getLocation());
  ft=ftt;
  initUI();
    }
    void initUI(){//depending on selected item/default shape type
  Container cp=this.getContentPane();
  try {
     okBt.removeActionListener(this);
     cancelBt.removeActionListener(this);
  }
  catch (NullPointerException ex){/*all these might be null (for instance when poping up a GlyphFactory for the first time)*/}
  cp.removeAll();
  //main font panel
  JPanel mainPanel=new JPanel();
  GridBagLayout gridBag1=new GridBagLayout();
  GridBagConstraints constraints1=new GridBagConstraints();
  mainPanel.setLayout(gridBag1);
  constraints1.fill=GridBagConstraints.BOTH;
  constraints1.anchor=GridBagConstraints.CENTER;
  familyList=new JList(allFontFamilies);
  JScrollPane sp1=new JScrollPane(familyList);
  buildConstraints(constraints1,0,0,1,1,30,100);
  gridBag1.setConstraints(sp1,constraints1);
  mainPanel.add(sp1);
  styleList=new JList(allFontStyles);
  JScrollPane sp2=new JScrollPane(styleList);
  buildConstraints(constraints1,1,0,1,1,30,0);
  gridBag1.setConstraints(sp2,constraints1);
  mainPanel.add(sp2);
  sizeList=new JList(allFontSizes);
  JScrollPane sp3=new JScrollPane(sizeList);
  buildConstraints(constraints1,2,0,1,1,25,0);
  gridBag1.setConstraints(sp3,constraints1);
  mainPanel.add(sp3);
  //ok, cancel, reset buttons
  JPanel btPanel=new JPanel();
  btPanel.setLayout(new FlowLayout());
  okBt=new JButton("OK"); 
  okBt.addActionListener(this);
  btPanel.add(okBt);
  cancelBt=new JButton("Cancel"); 
  cancelBt.addActionListener(this);
  btPanel.add(cancelBt);
  //main components
  GridBagLayout gridBag=new GridBagLayout();
  GridBagConstraints constraints=new GridBagConstraints();
  cp.setLayout(gridBag);
  constraints.fill=GridBagConstraints.BOTH;
  constraints.anchor=GridBagConstraints.CENTER;
  buildConstraints(constraints,0,0,1,1,100,99);
  gridBag.setConstraints(mainPanel,constraints);
  cp.add(mainPanel);
  buildConstraints(constraints,0,1,1,1,100,1);
  gridBag.setConstraints(btPanel,constraints);
  cp.add(btPanel);
  this.setSize(350,200);
  this.setResizable(false);
  familyList.setSelectedValue(DEFAULT_FAMILY,true);
  if (DEFAULT_STYLE==Font.PLAIN){styleList.setSelectedValue("Plain",true);}
  else if (DEFAULT_STYLE==Font.BOLD){styleList.setSelectedValue("Bold",true);}
  else if (DEFAULT_STYLE==Font.ITALIC){styleList.setSelectedValue("Italic",true);}
  else if (DEFAULT_STYLE==Font.BOLD+Font.ITALIC){styleList.setSelectedValue("BoldItalic",true);}
  sizeList.setSelectedValue((new Integer(DEFAULT_SIZE)).toString(),true);
    }
    public void actionPerformed(ActionEvent e){
  Object source=e.getSource();
  if (source==okBt){
      ft.setFont(getSelectedFont());
      this.dispose();
  }
  else if (source==cancelBt){
      ft.setFont(null);
      this.dispose();
  }
    }
    
    Font getSelectedFont(){
  String family=(String)familyList.getSelectedValue();if (family==null){family=DEFAULT_FAMILY;}
  String selectedStyle=(String)styleList.getSelectedValue();
  int style;
  if (selectedStyle.equals("Bold")){style=Font.BOLD;}
  else if (selectedStyle.equals("Italic")){style=Font.ITALIC;}
  else if (selectedStyle.equals("BoldItalic")){style=Font.BOLD+Font.ITALIC;}
  else {style=Font.PLAIN;}//"Plain"
  int size;
  try {
      String selectedSize=(String)sizeList.getSelectedValue();
      size=Integer.parseInt(selectedSize);
      if (size<=0){size=DEFAULT_SIZE;}
  }
  catch (NumberFormatException ex){size=DEFAULT_SIZE;}
  return new Font(family,style,size);
    }
    static void buildConstraints(GridBagConstraints gbc, int gx,int gy,int gw,int gh,int wx,int wy){
  gbc.gridx=gx;
  gbc.gridy=gy;
  gbc.gridwidth=gw;
  gbc.gridheight=gh;
  gbc.weightx=wx;
  gbc.weighty=wy;
    }
    
    static class Closer extends WindowAdapter {
        public void windowClosing(WindowEvent e) {
            Window w = e.getWindow();
            w.setVisible(false);
        }
    }
    static class DisposeOnClose extends ComponentAdapter {
        public void componentHidden(ComponentEvent e) {
            Window w = (Window)e.getComponent();
            w.dispose();
        }
    }
    public static String getFontStyleName(int i){
  if (i==java.awt.Font.BOLD){return "Bold";}
  else if (i==java.awt.Font.ITALIC){return "Italic";}
  else if (i==java.awt.Font.BOLD+java.awt.Font.ITALIC){return "BoldItalic";}
  else {return "Plain";}
    }
}
class FontTracker {
    Font font;
    public void setFont(Font f){
  font=f;
    }
    public Font getFont() {
        return font;
    }
}




Font Loader Dialog

   
/*
 * FontLoaderDialog.java
 *
 * Created on November 13, 2006, 8:30 AM
 */

// Revised from jaspersoft designer
import java.lang.reflect.InvocationTargetException;
import javax.swing.SwingUtilities;
/**
 *
 * @author  gtoffoli
 */
public class FontLoaderDialog extends javax.swing.JDialog {
    
    /** Creates new form FontLoaderDialog */
    public FontLoaderDialog(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
        //applyI18n();
        this.pack();
        
        setLocationRelativeTo(null);
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;
        jLabelStatus = new javax.swing.JLabel();
        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        getContentPane().setLayout(new java.awt.GridBagLayout());
        jLabelStatus.setText("FontLoaderDialog.Label.LoadingStatus"); // NOI18N
        jLabelStatus.setVerticalAlignment(javax.swing.SwingConstants.TOP);
        jLabelStatus.setPreferredSize(new java.awt.Dimension(391, 51));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
        getContentPane().add(jLabelStatus, gridBagConstraints);
        pack();
    }// </editor-fold>//GEN-END:initComponents
    
    public void setStatus(String s)
    {
        jLabelStatus.setText(s);
    }
    
    public void fontsLoadingStatusUpdated(String statusMsg) {
        
        final String s = statusMsg;
        try {
            SwingUtilities.invokeAndWait( new Runnable()
            {
                public void run()
                {
                    setStatus(s);
                }
            }
            );
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        } catch (InvocationTargetException ex) {
            ex.printStackTrace();
        }
        
    }
    public void fontsLoadingStarted() {
        
        try {
            SwingUtilities.invokeAndWait( new Runnable()
            {
                public void run()
                {
                    setVisible(true);
                }
            }
            );
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        } catch (InvocationTargetException ex) {
            ex.printStackTrace();
        }
    }
    public void fontsLoadingFinished() {
        try {
            SwingUtilities.invokeAndWait( new Runnable()
            {
                public void run()
                {
                    setVisible(false);
                }
            }
            );
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        } catch (InvocationTargetException ex) {
            ex.printStackTrace();
        }
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel jLabelStatus;
    // End of variables declaration//GEN-END:variables
    
//    public void applyI18n(){
//                // Start autogenerated code ----------------------
//                jLabelStatus.setText(I18n.getString("fontLoaderDialog.labelStatus","Loading status"));
//                // End autogenerated code ----------------------
//    }
}




JFont Chooser

   
// revised from greef ui
import java.awt.BorderLayout;
import java.awt.ruponent;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ruponentAdapter;
import java.awt.event.ruponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.Serializable;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
/**
 * <code>JFontChooser</code> provides a pane of controls designed to allow
 * a user to manipulate and select a font.
 *
 * This class provides three levels of API:
 * <ol>
 * <li>A static convenience method which shows a modal font-chooser
 * dialog and returns the font selected by the user.
 * <li>A static convenience method for creating a font-chooser dialog
 * where <code>ActionListeners</code> can be specified to be invoked when
 * the user presses one of the dialog buttons.
 * <li>The ability to create instances of <code>JFontChooser</code> panes
 * directly (within any container). <code>PropertyChange</code> listeners
 * can be added to detect when the current "font" property changes.
 * </ol>
 * <p>
 *
 * @author Adrian BER
 */
public class JFontChooser extends JComponent {
    /** The list of possible font sizes. */
    private static final Integer[] SIZES =
            {8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 24, 26, 28, 32, 36, 40, 48, 56, 64, 72};
    /** The list of possible fonts. */
    private static final String[] FONTS = GraphicsEnvironment.getLocalGraphicsEnvironment()
            .getAvailableFontFamilyNames();

    private FontSelectionModel selectionModel;
    private JList fontList;
    private JList sizeList;
    private JCheckBox boldCheckBox;
    private JCheckBox italicCheckBox;
    private JLabel previewLabel;
    /** The preview text, if null the font name will be the preview text. */
    private String previewText;
    /** Listener used to update the font of the selection model. */
    private SelectionUpdater selectionUpdater = new SelectionUpdater();
    /** Listener used to update the font in the components. This should be registered
     * with the selection model. */
    private LabelUpdater labelUpdater = new LabelUpdater();
    /** True if the components are being updated and no event should be generated. */
    private boolean updatingComponents = false;
    /** Listener class used to update the font in the components. This should be registered
      * with the selection model. */
    private class LabelUpdater implements ChangeListener {
        public void stateChanged(ChangeEvent e) {
            updateComponents();
        }
    }
    /** Listener class used to update the font of the preview label. */
    private class SelectionUpdater implements ChangeListener, ListSelectionListener {
        public void stateChanged(ChangeEvent e) {
            if (!updatingComponents) {
                setFont(buildFont());
            }
        }
        public void valueChanged(ListSelectionEvent e) {
            if (!updatingComponents) {
                setFont(buildFont());
            }
        }
    }
    /**
     * Shows a modal font-chooser dialog and blocks until the
     * dialog is hidden.  If the user presses the "OK" button, then
     * this method hides/disposes the dialog and returns the selected color.
     * If the user presses the "Cancel" button or closes the dialog without
     * pressing "OK", then this method hides/disposes the dialog and returns
     * <code>null</code>.
     *
     * @param component    the parent <code>Component</code> for the dialog
     * @param title        the String containing the dialog"s title
     * @return the selected font or <code>null</code> if the user opted out
     * @exception HeadlessException if GraphicsEnvironment.isHeadless()
     * returns true.
     * @see java.awt.GraphicsEnvironment#isHeadless
     */
    public Font showDialog(Component component, String title) {
        FontTracker ok = new FontTracker(this);
        JDialog dialog = createDialog(component, title, true, ok, null);
        dialog.addWindowListener(new FontChooserDialog.Closer());
        dialog.addComponentListener(new FontChooserDialog.DisposeOnClose());
        dialog.setVisible(true); // blocks until user brings dialog down...
        return ok.getFont();
    }

    /**
     * Creates and returns a new dialog containing the specified
     * <code>ColorChooser</code> pane along with "OK", "Cancel", and "Reset"
     * buttons. If the "OK" or "Cancel" buttons are pressed, the dialog is
     * automatically hidden (but not disposed).  If the "Reset"
     * button is pressed, the color-chooser"s color will be reset to the
     * font which was set the last time <code>show</code> was invoked on the
     * dialog and the dialog will remain showing.
     *
     * @param c              the parent component for the dialog
     * @param title          the title for the dialog
     * @param modal          a boolean. When true, the remainder of the program
     *                       is inactive until the dialog is closed.
     * @param okListener     the ActionListener invoked when "OK" is pressed
     * @param cancelListener the ActionListener invoked when "Cancel" is pressed
     * @return a new dialog containing the font-chooser pane
     * @exception HeadlessException if GraphicsEnvironment.isHeadless()
     * returns true.
     * @see java.awt.GraphicsEnvironment#isHeadless
     */
    public JDialog createDialog(Component c, String title, boolean modal,
        ActionListener okListener, ActionListener cancelListener) {
        return new FontChooserDialog(c, title, modal, this,
                okListener, cancelListener);
    }
    /**
     * Creates a color chooser pane with an initial font which is the same font
     * as the default font for labels.
     */
    public JFontChooser() {
        this(new DefaultFontSelectionModel());
    }
    /**
     * Creates a font chooser pane with the specified initial font.
     *
     * @param initialFont the initial font set in the chooser
     */
    public JFontChooser(Font initialFont) {
        this(new DefaultFontSelectionModel(initialFont));
    }
    /**
     * Creates a font chooser pane with the specified
     * <code>FontSelectionModel</code>.
     *
     * @param model the font selection model used by this component
     */
    public JFontChooser(FontSelectionModel model) {
        selectionModel = model;
        init(model.getSelectedFont());
        selectionModel.addChangeListener(labelUpdater);
    }
    private void init(Font font) {
        setLayout(new GridBagLayout());
        Insets ins = new Insets(2, 2, 2, 2);
        fontList = new JList(FONTS);
        fontList.setVisibleRowCount(10);
        fontList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        add(new JScrollPane(fontList), new GridBagConstraints(0, 0, 1, 1, 2, 2,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                ins, 0, 0));
        sizeList = new JList(SIZES);
        ((JLabel)sizeList.getCellRenderer()).setHorizontalAlignment(JLabel.RIGHT);
        sizeList.setVisibleRowCount(10);
        sizeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        add(new JScrollPane(sizeList), new GridBagConstraints(1, 0, 1, 1, 1, 2,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                ins, 0, 0));
        boldCheckBox = new JCheckBox("Bold");
        add(boldCheckBox, new GridBagConstraints(0, 1, 2, 1, 1, 0,
                GridBagConstraints.WEST, GridBagConstraints.NONE,
                ins, 0, 0));
        italicCheckBox = new JCheckBox("Italic");
        add(italicCheckBox, new GridBagConstraints(0, 2, 2, 1, 1, 0,
                GridBagConstraints.WEST, GridBagConstraints.NONE,
                ins, 0, 0));
        previewLabel = new JLabel("");
        previewLabel.setHorizontalAlignment(JLabel.CENTER);
        previewLabel.setVerticalAlignment(JLabel.CENTER);
        add(new JScrollPane(previewLabel), new GridBagConstraints(0, 3, 2, 1, 1, 1,
                GridBagConstraints.CENTER, GridBagConstraints.BOTH,
                ins, 0, 0));
        setFont(font == null ? previewLabel.getFont() : font);
        fontList.addListSelectionListener(selectionUpdater);
        sizeList.addListSelectionListener(selectionUpdater);
        boldCheckBox.addChangeListener(selectionUpdater);
        italicCheckBox.addChangeListener(selectionUpdater);
    }
    private Font buildFont() {
//        Font labelFont = previewLabel.getFont();
        String fontName = (String)fontList.getSelectedValue();
        if (fontName == null) {
            return null;
//            fontName = labelFont.getName();
        }
        Integer sizeInt = (Integer)sizeList.getSelectedValue();
        if (sizeInt == null) {
//            size = labelFont.getSize();
            return null;
        }
        // create the font
//        // first create the font attributes
//        HashMap map = new HashMap();
//        map.put(TextAttribute.BACKGROUND, Color.white);
//        map.put(TextAttribute.FAMILY, fontName);
//        map.put(TextAttribute.FOREGROUND, Color.black);
//        map.put(TextAttribute.SIZE , new Float(size));
//        map.put(TextAttribute.UNDERLINE, italicCheckBox.isSelected() ? TextAttribute.UNDERLINE_LOW_ONE_PIXEL : TextAttribute.UNDERLINE_LOW_TWO_PIXEL);
//        map.put(TextAttribute.STRIKETHROUGH, italicCheckBox.isSelected() ? TextAttribute.STRIKETHROUGH_ON : Boolean.FALSE);
//        map.put(TextAttribute.WEIGHT, boldCheckBox.isSelected() ? TextAttribute.WEIGHT_BOLD : TextAttribute.WEIGHT_REGULAR);
//        map.put(TextAttribute.POSTURE,
//                italicCheckBox.isSelected() ? TextAttribute.POSTURE_OBLIQUE : TextAttribute.POSTURE_REGULAR);
//
//        return new Font(map);
        return new Font(fontName,
                (italicCheckBox.isSelected() ? Font.ITALIC : Font.PLAIN)
                | (boldCheckBox.isSelected() ? Font.BOLD : Font.PLAIN),
                sizeInt);
    }
    /** Updates the font in the preview component according to the selected values. */
    private void updateComponents() {
        updatingComponents = true;
        Font font = getFont();
        fontList.setSelectedValue(font.getName(), true);
        sizeList.setSelectedValue(font.getSize(), true);
        boldCheckBox.setSelected(font.isBold());
        italicCheckBox.setSelected(font.isItalic());
        if (previewText == null) {
            previewLabel.setText(font.getName());
        }
        // set the font and fire a property change
        Font oldValue = previewLabel.getFont();
        previewLabel.setFont(font);
        firePropertyChange("font", oldValue, font);
        updatingComponents = false;
    }
    /**
     * Returns the data model that handles font selections.
     *
     * @return a FontSelectionModel object
     */
    public FontSelectionModel getSelectionModel() {
        return selectionModel;
    }

    /**
     * Set the model containing the selected font.
     *
     * @param newModel   the new FontSelectionModel object
     */
    public void setSelectionModel(FontSelectionModel newModel ) {
        FontSelectionModel oldModel = selectionModel;
        selectionModel = newModel;
        oldModel.removeChangeListener(labelUpdater);
        newModel.addChangeListener(labelUpdater);
        firePropertyChange("selectionModel", oldModel, newModel);
    }
    /**
     * Gets the current font value from the font chooser.
     *
     * @return the current font value of the font chooser
     */
    public Font getFont() {
        return selectionModel.getSelectedFont();
    }
    /**
     * Sets the current font of the font chooser to the specified font.
     * The <code>ColorSelectionModel</code> will fire a <code>ChangeEvent</code>
     * @param font the font to be set in the font chooser
     * @see JComponent#addPropertyChangeListener
     */
    public void setFont(Font font) {
        selectionModel.setSelectedFont(font);
    }
    /** Returns the preview text displayed in the preview component.
     * @return the preview text, if null the font name will be displayed
     */
    public String getPreviewText() {
        return previewText;
    }
    /** Sets the preview text displayed in the preview component.
     * @param previewText the preview text, if null the font name will be displayed
     */
    public void setPreviewText(String previewText) {
        this.previewText = previewText;
        previewLabel.setText("");
        updateComponents();
    }
}

/*
 * Class which builds a font chooser dialog consisting of
 * a JFontChooser with "Ok", "Cancel", and "Reset" buttons.
 *
 * Note: This needs to be fixed to deal with localization!
 */
class FontChooserDialog extends JDialog {
    private Font initialFont;
    private JFontChooser chooserPane;
    public FontChooserDialog(Component c, String title, boolean modal,
              JFontChooser chooserPane,
              ActionListener okListener, ActionListener cancelListener) {
        super(JOptionPane.getFrameForComponent(c), title, modal);
        //setResizable(false);
        String okString = UIManager.getString("ColorChooser.okText");
        String cancelString = UIManager.getString("ColorChooser.cancelText");
        String resetString = UIManager.getString("ColorChooser.resetText");
        /*
         * Create Lower button panel
         */
        JPanel buttonPane = new JPanel();
        buttonPane.setLayout(new FlowLayout(FlowLayout.CENTER));
        JButton okButton = new JButton(okString);
        getRootPane().setDefaultButton(okButton);
        okButton.setActionCommand("OK");
        if (okListener != null) {
            okButton.addActionListener(okListener);
        }
        okButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                setVisible(false);
            }
        });
        buttonPane.add(okButton);
        JButton cancelButton = new JButton(cancelString);
        // The following few lines are used to register esc to close the dialog
        Action cancelKeyAction = new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                // todo make it in 1.3
//                ActionListener[] listeners
//                        = ((AbstractButton) e.getSource()).getActionListeners();
//                for (int i = 0; i < listeners.length; i++) {
//                    listeners[i].actionPerformed(e);
//                }
            }
        };
        KeyStroke cancelKeyStroke = KeyStroke.getKeyStroke((char) KeyEvent.VK_ESCAPE);
        InputMap inputMap = cancelButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        ActionMap actionMap = cancelButton.getActionMap();
        if (inputMap != null && actionMap != null) {
            inputMap.put(cancelKeyStroke, "cancel");
            actionMap.put("cancel", cancelKeyAction);
        }
        // end esc handling
        cancelButton.setActionCommand("cancel");
        if (cancelListener != null) {
            cancelButton.addActionListener(cancelListener);
        }
        cancelButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                setVisible(false);
            }
        });
        buttonPane.add(cancelButton);
        JButton resetButton = new JButton(resetString);
        resetButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                reset();
            }
        });
        int mnemonic = UIManager.getInt("ColorChooser.resetMnemonic");
        if (mnemonic != -1) {
            resetButton.setMnemonic(mnemonic);
        }
        buttonPane.add(resetButton);

        // initialiase the content pane
        this.chooserPane = chooserPane;
        Container contentPane = getContentPane();
        contentPane.setLayout(new BorderLayout());
        contentPane.add(chooserPane, BorderLayout.CENTER);
        contentPane.add(buttonPane, BorderLayout.SOUTH);
        pack();
        setLocationRelativeTo(c);
    }
    public void setVisible(boolean visible) {
        if (visible)
            initialFont = chooserPane.getFont();
        super.setVisible(visible);
    }
    public void reset() {
        chooserPane.setFont(initialFont);
    }
    static class Closer extends WindowAdapter implements Serializable {
        public void windowClosing(WindowEvent e) {
            Window w = e.getWindow();
            w.setVisible(false);
        }
    }
    static class DisposeOnClose extends ComponentAdapter implements Serializable {
        public void componentHidden(ComponentEvent e) {
            Window w = (Window) e.getComponent();
            w.dispose();
        }
    }
}
class FontTracker implements ActionListener, Serializable {
    JFontChooser chooser;
    Font color;
    public FontTracker(JFontChooser c) {
        chooser = c;
    }
    public void actionPerformed(ActionEvent e) {
        color = chooser.getFont();
    }
    public Font getFont() {
        return color;
    }
}

/**
 * A generic implementation of <code>{@link FontSelectionModel}</code>.
 *
 * @author Adrian BER
 */
class DefaultFontSelectionModel implements FontSelectionModel {
    /** The default selected font. */
    private static final Font DEFAULT_INITIAL_FONT = new Font("Dialog", Font.PLAIN, 12);
    
    /** The selected font. */
    private Font selectedFont;
    /** The change listeners notified by a change in this model. */
    private EventListenerList listeners = new EventListenerList();
    /**
     * Creates a <code>DefaultFontSelectionModel</code> with the
     * current font set to <code>Dialog, 12</code>.  This is
     * the default constructor.
     */
    public DefaultFontSelectionModel() {
        this(DEFAULT_INITIAL_FONT);
    }
    /**
     * Creates a <code>DefaultFontSelectionModel</code> with the
     * current font set to <code>font</code>, which should be
     * non-<code>null</code>.  Note that setting the font to
     * <code>null</code> is undefined and may have unpredictable
     * results.
     *
     * @param selectedFont the new <code>Font</code>
     */
    public DefaultFontSelectionModel(Font selectedFont) {
        if (selectedFont == null) {
            selectedFont = DEFAULT_INITIAL_FONT;
        }
        this.selectedFont = selectedFont;
    }
    public Font getSelectedFont() {
        return selectedFont;
    }
    public void setSelectedFont(Font selectedFont) {
        if (selectedFont != null) {
            this.selectedFont = selectedFont;
            fireChangeListeners();
        }
    }
    public void addChangeListener(ChangeListener listener) {
        listeners.add(ChangeListener.class, listener);
    }
    public void removeChangeListener(ChangeListener listener) {
        listeners.remove(ChangeListener.class, listener);
    }
    /** Fires the listeners registered with this model. */
    protected void fireChangeListeners() {
        ChangeEvent ev = new ChangeEvent(this);
        Object[] l = listeners.getListeners(ChangeListener.class);
        for (Object listener : l) {
            ((ChangeListener) listener).stateChanged(ev);
        }
    }
}

/**
 * A model that supports selecting a <code>Font</code>.
 *
 * @author Adrian BER
 *
 * @see java.awt.Font
 */
interface FontSelectionModel {
    /**
     * Returns the selected <code>Font</code> which should be
     * non-<code>null</code>.
     *
     * @return  the selected <code>Font</code>
     * @see     #setSelectedFont
     */
    Font getSelectedFont();
    /**
     * Sets the selected font to <code>font</code>.
     * Note that setting the font to <code>null</code>
     * is undefined and may have unpredictable results.
     * This method fires a state changed event if it sets the
     * current font to a new non-<code>null</code> font.
     *
     * @param font the new <code>Font</code>
     * @see   #getSelectedFont
     * @see   #addChangeListener
     */
    void setSelectedFont(Font font);
    /**
     * Adds <code>listener</code> as a listener to changes in the model.
     * @param listener the <code>ChangeListener</code> to be added
     */
    void addChangeListener(ChangeListener listener);
    /**
     * Removes <code>listener</code> as a listener to changes in the model.
     * @param listener the <code>ChangeListener</code> to be removed
     */
    void removeChangeListener(ChangeListener listener);
}
//////////////////////////////
package com.greef.ui.font;
import com.greef.ui.UIUtilities;
import javax.swing.*;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
/**
 * @author Adrian BER (beradrian@yahoo.ru)
 */
public class JFontChooserDemo extends JPanel {
    private static final Insets INSETS = new Insets(5, 5, 5, 5);
    private JFontChooser fontChooser;
    private JCheckBox defaultPreviewCheckBox;
    private JTextField previewTextField;
    private JLabel previewLabel;
    private JTextArea codeTextArea;
    public JFontChooserDemo() {
        init();
    }
    private void init() {
        setLayout(new GridBagLayout());
        defaultPreviewCheckBox = new JCheckBox("Use font name as the preview text");
        defaultPreviewCheckBox.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                boolean selected = defaultPreviewCheckBox.isSelected();
                fontChooser.setPreviewText(selected ? null : previewTextField.getText());
                previewLabel.setEnabled(!selected);
                previewTextField.setEnabled(!selected);
                updateCode();
            }
        });
        add(defaultPreviewCheckBox, new GridBagConstraints(0, 0, 2, 1, 0, 0, GridBagConstraints.WEST,
                GridBagConstraints.NONE, INSETS, 0, 0));
        previewLabel = new JLabel("Preview text:");
        add(previewLabel, new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.EAST,
                GridBagConstraints.NONE, INSETS, 0, 0));
        previewTextField = new JTextField();
        previewTextField.getDocument().addDocumentListener(new DocumentListener() {
            private void changePreviewText() {
                fontChooser.setPreviewText(previewTextField.getText());
                updateCode();
            }
            public void insertUpdate(DocumentEvent e) {
                changePreviewText();
            }
            public void removeUpdate(DocumentEvent e) {
                changePreviewText();
            }
            public void changedUpdate(DocumentEvent e) {
                changePreviewText();
            }
        });
        add(previewTextField, new GridBagConstraints(1, 1, 1, 1, 1, 0, GridBagConstraints.WEST,
                GridBagConstraints.HORIZONTAL, INSETS, 0, 0));
        JButton testButton = new JButton("Test");
        testButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Font font = fontChooser.showDialog(JFontChooserDemo.this, "Choose a font");
                JOptionPane.showMessageDialog(JFontChooserDemo.this, font == null ? "You canceled the dialog."
                        : "You have selected " + font.getName() + ", " + font.getSize()
                        + (font.isBold() ? ", Bold" : "") + (font.isItalic() ? ", Italic" : ""));
            }
        });
        add(testButton, new GridBagConstraints(0, 2, 2, 1, 1, 0, GridBagConstraints.NORTHEAST,
                GridBagConstraints.NONE, INSETS, 0, 0));
        codeTextArea = new JTextArea(5, 30);
        codeTextArea.setOpaque(false);
        codeTextArea.setEditable(false);
        codeTextArea.setBorder(BorderFactory.createTitledBorder("Code"));
        add(codeTextArea, new GridBagConstraints(0, 3, 2, 1, 1, 1, GridBagConstraints.CENTER,
                GridBagConstraints.BOTH, INSETS, 0, 0));
        setFontChooser(new JFontChooser());
    }
    private void setFontChooser(JFontChooser fontChooser) {
        this.fontChooser = fontChooser;
        String previewText = fontChooser.getPreviewText();
        defaultPreviewCheckBox.setSelected(previewText == null);
        previewTextField.setText(previewText);
        updateCode();
    }
    private void updateCode() {
        codeTextArea.setText("JFontChooser fontChooser = new JFontChooser();\n"
                + (defaultPreviewCheckBox.isSelected() ? "" : "fontChooser.setPreviewText(\""
                    + previewTextField.getText() + "\");\n")
                + "Font font = fontChooser.showDialog(invokerComponent, \"Choose a font\");\n"
                + "System.out.println(font == null ? \"You have canceled the dialog.\" : \"You have selected \" + font);");
    }
    public void updateUI() {
        super.updateUI();
        if (fontChooser != null)
            SwingUtilities.updateComponentTreeUI(fontChooser);
    }
}




JFreeChart: Font Dialog

Word like special font chooser

   
/*
 * @(#)Font2DTest.java  1.28 05/11/17
 * 
 * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * -Redistribution of source code must retain the above copyright notice, this
 *  list of conditions and the following disclaimer.
 * 
 * -Redistribution in binary form must reproduce the above copyright notice, 
 *  this list of conditions and the following disclaimer in the documentation
 *  and/or other materials provided with the distribution.
 * 
 * Neither the name of Sun Microsystems, Inc. or the names of contributors may 
 * be used to endorse or promote products derived from this software without 
 * specific prior written permission.
 * 
 * This software is provided "AS IS," without a warranty of any kind. ALL 
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
 * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
 * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
 * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST 
 * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, 
 * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY 
 * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, 
 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 * 
 * You acknowledge that this software is not designed, licensed or intended
 * for use in the design, construction, operation or maintenance of any
 * nuclear facility.
 */
/*
 * @(#)Font2DTest.java  1.28 05/11/17
 */
import static java.awt.RenderingHints.KEY_ANTIALIASING;
import static java.awt.RenderingHints.KEY_FRACTIONALMETRICS;
import static java.awt.RenderingHints.KEY_TEXT_ANTIALIASING;
import static java.awt.RenderingHints.KEY_TEXT_LCD_CONTRAST;
import static java.awt.RenderingHints.VALUE_ANTIALIAS_OFF;
import static java.awt.RenderingHints.VALUE_ANTIALIAS_ON;
import static java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_DEFAULT;
import static java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_OFF;
import static java.awt.RenderingHints.VALUE_FRACTIONALMETRICS_ON;
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT;
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_GASP;
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR;
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB;
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR;
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_VRGB;
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_OFF;
import static java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.ruponentAdapter;
import java.awt.event.ruponentEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterJob;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.text.AttributedString;
import java.util.BitSet;
import java.util.EnumSet;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.imageio.ImageIO;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JWindow;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
 * Font2DTest.java
 * 
 * @version
 * @(#)Font2DTest.java 1.2 00/08/22
 * @author Shinsuke Fukuda
 * @author Ankit Patel [Conversion to Swing - 01/07/30]
 */
// / Main Font2DTest Class
public final class Font2DTest extends JPanel implements ActionListener, ItemListener,
    ChangeListener {
  // / JFrame that will contain Font2DTest
  private final JFrame parent;
  // / FontPanel class that will contain all graphical output
  private final FontPanel fp;
  // / RangeMenu class that contains info about the unicode ranges
  private final RangeMenu rm;
  // / Other menus to set parameters for text drawing
  private final ChoiceV2 fontMenu;
  private final JTextField sizeField;
  private final ChoiceV2 styleMenu;
  private final ChoiceV2 textMenu;
  private int currentTextChoice = 0;
  private final ChoiceV2 transformMenu;
  private final ChoiceV2 transformMenuG2;
  private final ChoiceV2 methodsMenu;
  private final JComboBox antiAliasMenu;
  private final JComboBox fracMetricsMenu;
  private final JSlider contrastSlider;
  // / CheckboxMenuItems
  private CheckboxMenuItemV2 displayGridCBMI;
  private CheckboxMenuItemV2 force16ColsCBMI;
  private CheckboxMenuItemV2 showFontInfoCBMI;
  // / JDialog boxes
  private JDialog userTextDialog;
  private JTextArea userTextArea;
  private JDialog printDialog;
  private JDialog fontInfoDialog;
  private LabelV2 fontInfos[] = new LabelV2[2];
  private JFileChooser filePromptDialog = null;
  private ButtonGroup printCBGroup;
  private JRadioButton printModeCBs[] = new JRadioButton[3];
  // / Status bar
  private final LabelV2 statusBar;
  private int fontStyles[] = { Font.PLAIN, Font.BOLD, Font.ITALIC, Font.BOLD | Font.ITALIC };
  // / Text filename
  private String tFileName;
  // Enabled or disabled status of canDisplay check
  private static boolean canDisplayCheck = true;
  // / Initialize GUI variables and its layouts
  public Font2DTest(JFrame f, boolean isApplet) {
    parent = f;
    rm = new RangeMenu(this, parent);
    fp = new FontPanel(this, parent);
    statusBar = new LabelV2("");
    fontMenu = new ChoiceV2(this, canDisplayCheck);
    sizeField = new JTextField("12", 3);
    sizeField.addActionListener(this);
    styleMenu = new ChoiceV2(this);
    textMenu = new ChoiceV2(); // listener added later
    transformMenu = new ChoiceV2(this);
    transformMenuG2 = new ChoiceV2(this);
    methodsMenu = new ChoiceV2(this);
    antiAliasMenu = new JComboBox(EnumSet.allOf(FontPanel.AAValues.class).toArray());
    antiAliasMenu.addActionListener(this);
    fracMetricsMenu = new JComboBox(EnumSet.allOf(FontPanel.FMValues.class).toArray());
    fracMetricsMenu.addActionListener(this);
    contrastSlider = new JSlider(JSlider.HORIZONTAL, 100, 250, FontPanel.getDefaultLCDContrast()
        .intValue());
    contrastSlider.setEnabled(false);
    contrastSlider.setMajorTickSpacing(20);
    contrastSlider.setMinorTickSpacing(10);
    contrastSlider.setPaintTicks(true);
    contrastSlider.setPaintLabels(true);
    contrastSlider.addChangeListener(this);
    setupPanel();
    setupMenu(isApplet);
    setupDialog(isApplet);
    if (canDisplayCheck) {
      fireRangeChanged();
    }
  }
  // / Set up the main interface panel
  private void setupPanel() {
    GridBagLayout gbl = new GridBagLayout();
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.weightx = 1;
    gbc.insets = new Insets(2, 0, 2, 2);
    this.setLayout(gbl);
    addLabeledComponentToGBL("Font: ", fontMenu, gbl, gbc, this);
    addLabeledComponentToGBL("Size: ", sizeField, gbl, gbc, this);
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    addLabeledComponentToGBL("Font Transform:", transformMenu, gbl, gbc, this);
    gbc.gridwidth = 1;
    addLabeledComponentToGBL("Range: ", rm, gbl, gbc, this);
    addLabeledComponentToGBL("Style: ", styleMenu, gbl, gbc, this);
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    addLabeledComponentToGBL("Graphics Transform: ", transformMenuG2, gbl, gbc, this);
    gbc.gridwidth = 1;
    gbc.anchor = GridBagConstraints.WEST;
    addLabeledComponentToGBL("Method: ", methodsMenu, gbl, gbc, this);
    addLabeledComponentToGBL("", null, gbl, gbc, this);
    gbc.anchor = GridBagConstraints.EAST;
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    addLabeledComponentToGBL("Text to use:", textMenu, gbl, gbc, this);
    gbc.weightx = 1;
    gbc.gridwidth = 1;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.anchor = GridBagConstraints.WEST;
    addLabeledComponentToGBL("LCD contrast: ", contrastSlider, gbl, gbc, this);
    gbc.gridwidth = 1;
    gbc.fill = GridBagConstraints.NONE;
    addLabeledComponentToGBL("Antialiasing: ", antiAliasMenu, gbl, gbc, this);
    gbc.anchor = GridBagConstraints.EAST;
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    addLabeledComponentToGBL("Fractional metrics: ", fracMetricsMenu, gbl, gbc, this);
    gbc.weightx = 1;
    gbc.weighty = 1;
    gbc.anchor = GridBagConstraints.WEST;
    gbc.insets = new Insets(2, 0, 0, 2);
    gbc.fill = GridBagConstraints.BOTH;
    gbl.setConstraints(fp, gbc);
    this.add(fp);
    gbc.weighty = 0;
    gbc.insets = new Insets(0, 2, 0, 0);
    gbl.setConstraints(statusBar, gbc);
    this.add(statusBar);
  }
  // / Adds a component to a container with a label to its left in GridBagLayout
  private void addLabeledComponentToGBL(String name, JComponent c, GridBagLayout gbl,
      GridBagConstraints gbc, Container target) {
    LabelV2 l = new LabelV2(name);
    GridBagConstraints gbcLabel = (GridBagConstraints) gbc.clone();
    gbcLabel.insets = new Insets(2, 2, 2, 0);
    gbcLabel.gridwidth = 1;
    gbcLabel.weightx = 0;
    if (c == null)
      c = new JLabel("");
    gbl.setConstraints(l, gbcLabel);
    target.add(l);
    gbl.setConstraints(c, gbc);
    target.add(c);
  }
  // / Sets up menu entries
  private void setupMenu(boolean isApplet) {
    JMenu fileMenu = new JMenu("File");
    JMenu optionMenu = new JMenu("Option");
    fileMenu.add(new MenuItemV2("Save Selected Options...", this));
    fileMenu.add(new MenuItemV2("Load Options...", this));
    fileMenu.addSeparator();
    fileMenu.add(new MenuItemV2("Save as PNG...", this));
    fileMenu.add(new MenuItemV2("Load PNG File to Compare...", this));
    fileMenu.add(new MenuItemV2("Page Setup...", this));
    fileMenu.add(new MenuItemV2("Print...", this));
    fileMenu.addSeparator();
    if (!isApplet)
      fileMenu.add(new MenuItemV2("Exit", this));
    else
      fileMenu.add(new MenuItemV2("Close", this));
    displayGridCBMI = new CheckboxMenuItemV2("Display Grid", true, this);
    force16ColsCBMI = new CheckboxMenuItemV2("Force 16 Columns", false, this);
    showFontInfoCBMI = new CheckboxMenuItemV2("Display Font Info", false, this);
    optionMenu.add(displayGridCBMI);
    optionMenu.add(force16ColsCBMI);
    optionMenu.add(showFontInfoCBMI);
    JMenuBar mb = parent.getJMenuBar();
    if (mb == null)
      mb = new JMenuBar();
    mb.add(fileMenu);
    mb.add(optionMenu);
    parent.setJMenuBar(mb);
    String fontList[] = GraphicsEnvironment.getLocalGraphicsEnvironment()
        .getAvailableFontFamilyNames();
    for (int i = 0; i < fontList.length; i++)
      fontMenu.addItem(fontList[i]);
    fontMenu.setSelectedItem("Dialog");
    styleMenu.addItem("Plain");
    styleMenu.addItem("Bold");
    styleMenu.addItem("Italic");
    styleMenu.addItem("Bold Italic");
    transformMenu.addItem("None");
    transformMenu.addItem("Scale");
    transformMenu.addItem("Shear");
    transformMenu.addItem("Rotate");
    transformMenuG2.addItem("None");
    transformMenuG2.addItem("Scale");
    transformMenuG2.addItem("Shear");
    transformMenuG2.addItem("Rotate");
    methodsMenu.addItem("drawString");
    methodsMenu.addItem("drawChars");
    methodsMenu.addItem("drawBytes");
    methodsMenu.addItem("drawGlyphVector");
    methodsMenu.addItem("TextLayout.draw");
    methodsMenu.addItem("GlyphVector.getOutline + draw");
    methodsMenu.addItem("TextLayout.getOutline + draw");
    textMenu.addItem("Unicode Range");
    textMenu.addItem("All Glyphs");
    textMenu.addItem("User Text");
    textMenu.addItem("Text File");
    textMenu.addActionListener(this); // listener added later so unneeded events
                                      // not thrown
  }
  // / Sets up the all dialogs used in Font2DTest...
  private void setupDialog(boolean isApplet) {
    if (!isApplet)
      filePromptDialog = new JFileChooser();
    else
      filePromptDialog = null;
    // / Prepare user text dialog...
    userTextDialog = new JDialog(parent, "User Text", false);
    JPanel dialogTopPanel = new JPanel();
    JPanel dialogBottomPanel = new JPanel();
    LabelV2 message1 = new LabelV2("Enter text below and then press update");
    LabelV2 message2 = new LabelV2("(Unicode char can be denoted by \\uXXXX)");
    LabelV2 message3 = new LabelV2("(Supplementary chars can be denoted by \\UXXXXXX)");
    userTextArea = new JTextArea("Java2D!");
    ButtonV2 bUpdate = new ButtonV2("Update", this);
    userTextArea.setFont(new Font("dialog", Font.PLAIN, 12));
    dialogTopPanel.setLayout(new GridLayout(3, 1));
    dialogTopPanel.add(message1);
    dialogTopPanel.add(message2);
    dialogTopPanel.add(message3);
    dialogBottomPanel.add(bUpdate);
    // ABP
    JScrollPane userTextAreaSP = new JScrollPane(userTextArea);
    userTextAreaSP.setPreferredSize(new Dimension(300, 100));
    userTextDialog.getContentPane().setLayout(new BorderLayout());
    userTextDialog.getContentPane().add("North", dialogTopPanel);
    userTextDialog.getContentPane().add("Center", userTextAreaSP);
    userTextDialog.getContentPane().add("South", dialogBottomPanel);
    userTextDialog.pack();
    userTextDialog.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        userTextDialog.hide();
      }
    });
    // / Prepare printing dialog...
    printCBGroup = new ButtonGroup();
    printModeCBs[fp.ONE_PAGE] = new JRadioButton(
        "Print one page from currently displayed character/line", true);
    printModeCBs[fp.CUR_RANGE] = new JRadioButton(
        "Print all characters in currently selected range", false);
    printModeCBs[fp.ALL_TEXT] = new JRadioButton("Print all lines of text", false);
    LabelV2 l = new LabelV2(
        "Note: Page range in native \"Print\" dialog will not affect the result");
    JPanel buttonPanel = new JPanel();
    printModeCBs[fp.ALL_TEXT].setEnabled(false);
    buttonPanel.add(new ButtonV2("Print", this));
    buttonPanel.add(new ButtonV2("Cancel", this));
    printDialog = new JDialog(parent, "Print...", true);
    printDialog.setResizable(false);
    printDialog.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        printDialog.hide();
      }
    });
    printDialog.getContentPane().setLayout(new GridLayout(printModeCBs.length + 2, 1));
    printDialog.getContentPane().add(l);
    for (int i = 0; i < printModeCBs.length; i++) {
      printCBGroup.add(printModeCBs[i]);
      printDialog.getContentPane().add(printModeCBs[i]);
    }
    printDialog.getContentPane().add(buttonPanel);
    printDialog.pack();
    // / Prepare font information dialog...
    fontInfoDialog = new JDialog(parent, "Font info", false);
    fontInfoDialog.setResizable(false);
    fontInfoDialog.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        fontInfoDialog.hide();
        showFontInfoCBMI.setState(false);
      }
    });
    JPanel fontInfoPanel = new JPanel();
    fontInfoPanel.setLayout(new GridLayout(fontInfos.length, 1));
    for (int i = 0; i < fontInfos.length; i++) {
      fontInfos[i] = new LabelV2("");
      fontInfoPanel.add(fontInfos[i]);
    }
    fontInfoDialog.getContentPane().add(fontInfoPanel);
    // / Move the location of the dialog...
    userTextDialog.setLocation(200, 300);
    fontInfoDialog.setLocation(0, 400);
  }
  // / RangeMenu object signals using this function
  // / when Unicode range has been changed and text needs to be redrawn
  public void fireRangeChanged() {
    int range[] = rm.getSelectedRange();
    fp.setTextToDraw(fp.RANGE_TEXT, range, null, null);
    if (canDisplayCheck) {
      setupFontList(range[0], range[1]);
    }
    if (showFontInfoCBMI.getState())
      fireUpdateFontInfo();
  }
  // / Changes the message on the status bar
  public void fireChangeStatus(String message, boolean error) {
    // / If this is not ran as an applet, use own status bar,
    // / Otherwise, use the appletviewer/browser"s status bar
    statusBar.setText(message);
    if (error)
      fp.showingError = true;
    else
      fp.showingError = false;
  }
  // / Updates the information about the selected font
  public void fireUpdateFontInfo() {
    if (showFontInfoCBMI.getState()) {
      String infos[] = fp.getFontInfo();
      for (int i = 0; i < fontInfos.length; i++)
        fontInfos[i].setText(infos[i]);
      fontInfoDialog.pack();
    }
  }
  private void setupFontList(int rangeStart, int rangeEnd) {
    int listCount = fontMenu.getItemCount();
    int size = 16;
    try {
      size = Float.valueOf(sizeField.getText()).intValue();
    } catch (Exception e) {
      System.out.println("Invalid font size in the size textField. Using default value of 16");
    }
    int style = fontStyles[styleMenu.getSelectedIndex()];
    Font f;
    for (int i = 0; i < listCount; i++) {
      String fontName = (String) fontMenu.getItemAt(i);
      f = new Font(fontName, style, size);
      if ((rm.getSelectedIndex() != RangeMenu.SURROGATES_AREA_INDEX)
          && canDisplayRange(f, rangeStart, rangeEnd)) {
        fontMenu.setBit(i, true);
      } else {
        fontMenu.setBit(i, false);
      }
    }
    fontMenu.repaint();
  }
  protected boolean canDisplayRange(Font font, int rangeStart, int rangeEnd) {
    for (int i = rangeStart; i < rangeEnd; i++) {
      if (font.canDisplay(i)) {
        return true;
      }
    }
    return false;
  }
  // / Displays a file load/save dialog and returns the specified file
  private String promptFile(boolean isSave, String initFileName) {
    int retVal;
    String str;
    // / ABP
    if (filePromptDialog == null)
      return null;
    if (isSave) {
      filePromptDialog.setDialogType(JFileChooser.SAVE_DIALOG);
      filePromptDialog.setDialogTitle("Save...");
      str = "Save";
    } else {
      filePromptDialog.setDialogType(JFileChooser.OPEN_DIALOG);
      filePromptDialog.setDialogTitle("Load...");
      str = "Load";
    }
    if (initFileName != null)
      filePromptDialog.setSelectedFile(new File(initFileName));
    retVal = filePromptDialog.showDialog(this, str);
    if (retVal == JFileChooser.APPROVE_OPTION) {
      File file = filePromptDialog.getSelectedFile();
      String fileName = file.getAbsolutePath();
      if (fileName != null) {
        return fileName;
      }
    }
    return null;
  }
  // / Converts user text into arrays of String, delimited at newline character
  // / Also replaces any valid escape sequence with appropriate unicode
  // character
  // / Support \\UXXXXXX notation for surrogates
  private String[] parseUserText(String orig) {
    int length = orig.length();
    StringTokenizer perLine = new StringTokenizer(orig, "\n");
    String textLines[] = new String[perLine.countTokens()];
    int lineNumber = 0;
    while (perLine.hasMoreElements()) {
      StringBuffer converted = new StringBuffer();
      String oneLine = perLine.nextToken();
      int lineLength = oneLine.length();
      int prevEscapeEnd = 0;
      int nextEscape = -1;
      do {
        int nextBMPEscape = oneLine.indexOf("\\u", prevEscapeEnd);
        int nextSupEscape = oneLine.indexOf("\\U", prevEscapeEnd);
        nextEscape = (nextBMPEscape < 0) ? ((nextSupEscape < 0) ? -1 : nextSupEscape)
            : ((nextSupEscape < 0) ? nextBMPEscape : Math.min(nextBMPEscape, nextSupEscape));
        if (nextEscape != -1) {
          if (prevEscapeEnd < nextEscape)
            converted.append(oneLine.substring(prevEscapeEnd, nextEscape));
          prevEscapeEnd = nextEscape + (nextEscape == nextBMPEscape ? 6 : 8);
          try {
            String hex = oneLine.substring(nextEscape + 2, prevEscapeEnd);
            if (nextEscape == nextBMPEscape) {
              converted.append((char) Integer.parseInt(hex, 16));
            } else {
              converted.append(new String(Character.toChars(Integer.parseInt(hex, 16))));
            }
          } catch (Exception e) {
            int copyLimit = Math.min(lineLength, prevEscapeEnd);
            converted.append(oneLine.substring(nextEscape, copyLimit));
          }
        }
      } while (nextEscape != -1);
      if (prevEscapeEnd < lineLength)
        converted.append(oneLine.substring(prevEscapeEnd, lineLength));
      textLines[lineNumber++] = converted.toString();
    }
    return textLines;
  }
  // / Reads the text from specified file, detecting UTF-16 encoding
  // / Then breaks the text into String array, delimited at every line break
  private void readTextFile(String fileName) {
    try {
      String fileText, textLines[];
      BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fileName));
      int numBytes = bis.available();
      if (numBytes == 0) {
        throw new Exception("Text file " + fileName + " is empty");
      }
      byte byteData[] = new byte[numBytes];
      bis.read(byteData, 0, numBytes);
      bis.close();
      // / If byte mark is found, then use UTF-16 encoding to convert bytes...
      if (numBytes >= 2
          && ((byteData[0] == (byte) 0xFF && byteData[1] == (byte) 0xFE) || (byteData[0] == (byte) 0xFE && byteData[1] == (byte) 0xFF)))
        fileText = new String(byteData, "UTF-16");
      // / Otherwise, use system default encoding
      else
        fileText = new String(byteData);
      int length = fileText.length();
      StringTokenizer perLine = new StringTokenizer(fileText, "\n");
      // / Determine "Return Char" used in this file
      // / This simply finds first occurrence of CR, CR+LF or LF...
      for (int i = 0; i < length; i++) {
        char iTh = fileText.charAt(i);
        if (iTh == "\r") {
          if (i < length - 1 && fileText.charAt(i + 1) == "\n")
            perLine = new StringTokenizer(fileText, "\r\n");
          else
            perLine = new StringTokenizer(fileText, "\r");
          break;
        } else if (iTh == "\n")
          // / Use the one already created
          break;
      }
      int lineNumber = 0, numLines = perLine.countTokens();
      textLines = new String[numLines];
      while (perLine.hasMoreElements()) {
        String oneLine = perLine.nextToken();
        if (oneLine == null)
          // / To make LineBreakMeasurer to return a valid TextLayout
          // / on an empty line, simply feed it a space char...
          oneLine = " ";
        textLines[lineNumber++] = oneLine;
      }
      fp.setTextToDraw(fp.FILE_TEXT, null, null, textLines);
      rm.setEnabled(false);
      methodsMenu.setEnabled(false);
    } catch (Exception ex) {
      fireChangeStatus("ERROR: Failed to Read Text File; See Stack Trace", true);
      ex.printStackTrace();
    }
  }
  // / Returns a String storing current configuration
  private void writeCurrentOptions(String fileName) {
    try {
      String curOptions = fp.getCurrentOptions();
      BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fileName));
      // / Prepend title and the option that is only obtainable here
      int range[] = rm.getSelectedRange();
      String completeOptions = ("Font2DTest Option File\n" + displayGridCBMI.getState() + "\n"
          + force16ColsCBMI.getState() + "\n" + showFontInfoCBMI.getState() + "\n"
          + rm.getSelectedItem() + "\n" + range[0] + "\n" + range[1] + "\n" + curOptions + tFileName);
      byte toBeWritten[] = completeOptions.getBytes("UTF-16");
      bos.write(toBeWritten, 0, toBeWritten.length);
      bos.close();
    } catch (Exception ex) {
      fireChangeStatus("ERROR: Failed to Save Options File; See Stack Trace", true);
      ex.printStackTrace();
    }
  }
  // / Updates GUI visibility/status after some parameters have changed
  private void updateGUI() {
    int selectedText = textMenu.getSelectedIndex();
    // / Set the visibility of User Text dialog
    if (selectedText == fp.USER_TEXT)
      userTextDialog.show();
    else
      userTextDialog.hide();
    // / Change the visibility/status/availability of Print JDialog buttons
    printModeCBs[fp.ONE_PAGE].setSelected(true);
    if (selectedText == fp.FILE_TEXT || selectedText == fp.USER_TEXT) {
      // / ABP
      // / update methodsMenu to show that TextLayout.draw is being used
      // / when we are in FILE_TEXT mode
      if (selectedText == fp.FILE_TEXT)
        methodsMenu.setSelectedItem("TextLayout.draw");
      methodsMenu.setEnabled(selectedText == fp.USER_TEXT);
      printModeCBs[fp.CUR_RANGE].setEnabled(false);
      printModeCBs[fp.ALL_TEXT].setEnabled(true);
    } else {
      // / ABP
      // / update methodsMenu to show that drawGlyph is being used
      // / when we are in ALL_GLYPHS mode
      if (selectedText == fp.ALL_GLYPHS)
        methodsMenu.setSelectedItem("drawGlyphVector");
      methodsMenu.setEnabled(selectedText == fp.RANGE_TEXT);
      printModeCBs[fp.CUR_RANGE].setEnabled(true);
      printModeCBs[fp.ALL_TEXT].setEnabled(false);
    }
    // / Modify RangeMenu and fontInfo label availabilty
    if (selectedText == fp.RANGE_TEXT) {
      fontInfos[1].setVisible(true);
      rm.setEnabled(true);
    } else {
      fontInfos[1].setVisible(false);
      rm.setEnabled(false);
    }
  }
  // / Loads saved options and applies them
  private void loadOptions(String fileName) {
    try {
      BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fileName));
      int numBytes = bis.available();
      byte byteData[] = new byte[numBytes];
      bis.read(byteData, 0, numBytes);
      bis.close();
      if (numBytes < 2 || (byteData[0] != (byte) 0xFE || byteData[1] != (byte) 0xFF))
        throw new Exception("Not a Font2DTest options file");
      String options = new String(byteData, "UTF-16");
      StringTokenizer perLine = new StringTokenizer(options, "\n");
      String title = perLine.nextToken();
      if (!title.equals("Font2DTest Option File"))
        throw new Exception("Not a Font2DTest options file");
      // / Parse all options
      boolean displayGridOpt = Boolean.parseBoolean(perLine.nextToken());
      boolean force16ColsOpt = Boolean.parseBoolean(perLine.nextToken());
      boolean showFontInfoOpt = Boolean.parseBoolean(perLine.nextToken());
      String rangeNameOpt = perLine.nextToken();
      int rangeStartOpt = Integer.parseInt(perLine.nextToken());
      int rangeEndOpt = Integer.parseInt(perLine.nextToken());
      String fontNameOpt = perLine.nextToken();
      float fontSizeOpt = Float.parseFloat(perLine.nextToken());
      int fontStyleOpt = Integer.parseInt(perLine.nextToken());
      int fontTransformOpt = Integer.parseInt(perLine.nextToken());
      int g2TransformOpt = Integer.parseInt(perLine.nextToken());
      int textToUseOpt = Integer.parseInt(perLine.nextToken());
      int drawMethodOpt = Integer.parseInt(perLine.nextToken());
      int antialiasOpt = Integer.parseInt(perLine.nextToken());
      int fractionalOpt = Integer.parseInt(perLine.nextToken());
      int lcdContrast = Integer.parseInt(perLine.nextToken());
      String userTextOpt[] = { "Java2D!" }, dialogEntry = "Java2D!";
      if (textToUseOpt == fp.USER_TEXT) {
        int numLines = perLine.countTokens(), lineNumber = 0;
        if (numLines != 0) {
          userTextOpt = new String[numLines];
          dialogEntry = "";
          for (; perLine.hasMoreElements(); lineNumber++) {
            userTextOpt[lineNumber] = perLine.nextToken();
            dialogEntry += userTextOpt[lineNumber] + "\n";
          }
        }
      }
      // / Reset GUIs
      displayGridCBMI.setState(displayGridOpt);
      force16ColsCBMI.setState(force16ColsOpt);
      showFontInfoCBMI.setState(showFontInfoOpt);
      rm.setSelectedRange(rangeNameOpt, rangeStartOpt, rangeEndOpt);
      fontMenu.setSelectedItem(fontNameOpt);
      sizeField.setText(String.valueOf(fontSizeOpt));
      styleMenu.setSelectedIndex(fontStyleOpt);
      transformMenu.setSelectedIndex(fontTransformOpt);
      transformMenuG2.setSelectedIndex(g2TransformOpt);
      textMenu.setSelectedIndex(textToUseOpt);
      methodsMenu.setSelectedIndex(drawMethodOpt);
      antiAliasMenu.setSelectedIndex(antialiasOpt);
      fracMetricsMenu.setSelectedIndex(fractionalOpt);
      contrastSlider.setValue(lcdContrast);
      userTextArea.setText(dialogEntry);
      updateGUI();
      if (textToUseOpt == fp.FILE_TEXT) {
        tFileName = perLine.nextToken();
        readTextFile(tFileName);
      }
      // / Reset option variables and repaint
      fp.loadOptions(displayGridOpt, force16ColsOpt, rangeStartOpt, rangeEndOpt, fontNameOpt,
          fontSizeOpt, fontStyleOpt, fontTransformOpt, g2TransformOpt, textToUseOpt, drawMethodOpt,
          antialiasOpt, fractionalOpt, lcdContrast, userTextOpt);
      if (showFontInfoOpt) {
        fireUpdateFontInfo();
        fontInfoDialog.show();
      } else
        fontInfoDialog.hide();
    } catch (Exception ex) {
      fireChangeStatus("ERROR: Failed to Load Options File; See Stack Trace", true);
      ex.printStackTrace();
    }
  }
  // / Loads a previously saved image
  private void loadComparisonPNG(String fileName) {
    try {
      BufferedImage image = javax.imageio.ImageIO.read(new File(fileName));
      JFrame f = new JFrame("Comparison PNG");
      ImagePanel ip = new ImagePanel(image);
      f.setResizable(false);
      f.getContentPane().add(ip);
      f.addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
          ((JFrame) e.getSource()).dispose();
        }
      });
      f.pack();
      f.show();
    } catch (Exception ex) {
      fireChangeStatus("ERROR: Failed to Load PNG File; See Stack Trace", true);
      ex.printStackTrace();
    }
  }
  // / Interface functions...
  // / ActionListener interface function
  // / Responds to JMenuItem, JTextField and JButton actions
  public void actionPerformed(ActionEvent e) {
    Object source = e.getSource();
    if (source instanceof JMenuItem) {
      JMenuItem mi = (JMenuItem) source;
      String itemName = mi.getText();
      if (itemName.equals("Save Selected Options...")) {
        String fileName = promptFile(true, "options.txt");
        if (fileName != null)
          writeCurrentOptions(fileName);
      } else if (itemName.equals("Load Options...")) {
        String fileName = promptFile(false, "options.txt");
        if (fileName != null)
          loadOptions(fileName);
      } else if (itemName.equals("Save as PNG...")) {
        String fileName = promptFile(true, fontMenu.getSelectedItem() + ".png");
        if (fileName != null)
          fp.doSavePNG(fileName);
      } else if (itemName.equals("Load PNG File to Compare...")) {
        String fileName = promptFile(false, null);
        if (fileName != null)
          loadComparisonPNG(fileName);
      } else if (itemName.equals("Page Setup..."))
        fp.doPageSetup();
      else if (itemName.equals("Print..."))
        printDialog.show();
      else if (itemName.equals("Close"))
        parent.dispose();
      else if (itemName.equals("Exit"))
        System.exit(0);
    }
    else if (source instanceof JTextField) {
      JTextField tf = (JTextField) source;
      float sz = 12f;
      try {
        sz = Float.parseFloat(sizeField.getText());
        if (sz < 1f || sz > 120f) {
          sz = 12f;
          sizeField.setText("12");
        }
      } catch (Exception se) {
        sizeField.setText("12");
      }
      if (tf == sizeField)
        fp.setFontParams(fontMenu.getSelectedItem(), sz, styleMenu.getSelectedIndex(),
            transformMenu.getSelectedIndex());
    }
    else if (source instanceof JButton) {
      String itemName = ((JButton) source).getText();
      // / Print dialog buttons...
      if (itemName.equals("Print")) {
        for (int i = 0; i < printModeCBs.length; i++)
          if (printModeCBs[i].isSelected()) {
            printDialog.hide();
            fp.doPrint(i);
          }
      } else if (itemName.equals("Cancel"))
        printDialog.hide();
      // / Update button from Usert Text JDialog...
      else if (itemName.equals("Update"))
        fp.setTextToDraw(fp.USER_TEXT, null, parseUserText(userTextArea.getText()), null);
    } else if (source instanceof JComboBox) {
      JComboBox c = (JComboBox) source;
      // / RangeMenu handles actions by itself and then calls fireRangeChanged,
      // / so it is not listed or handled here
      if (c == fontMenu || c == styleMenu || c == transformMenu) {
        float sz = 12f;
        try {
          sz = Float.parseFloat(sizeField.getText());
          if (sz < 1f || sz > 120f) {
            sz = 12f;
            sizeField.setText("12");
          }
        } catch (Exception se) {
          sizeField.setText("12");
        }
        fp.setFontParams(fontMenu.getSelectedItem(), sz, styleMenu.getSelectedIndex(),
            transformMenu.getSelectedIndex());
      } else if (c == methodsMenu)
        fp.setDrawMethod(methodsMenu.getSelectedIndex());
      else if (c == textMenu) {
        if (canDisplayCheck) {
          fireRangeChanged();
        }
        int selected = textMenu.getSelectedIndex();
        if (selected == fp.RANGE_TEXT)
          fp.setTextToDraw(fp.RANGE_TEXT, rm.getSelectedRange(), null, null);
        else if (selected == fp.USER_TEXT)
          fp.setTextToDraw(fp.USER_TEXT, null, parseUserText(userTextArea.getText()), null);
        else if (selected == fp.FILE_TEXT) {
          String fileName = promptFile(false, null);
          if (fileName != null) {
            tFileName = fileName;
            readTextFile(fileName);
          } else {
            // / User cancelled selection; reset to previous choice
            c.setSelectedIndex(currentTextChoice);
            return;
          }
        } else if (selected == fp.ALL_GLYPHS)
          fp.setTextToDraw(fp.ALL_GLYPHS, null, null, null);
        updateGUI();
        currentTextChoice = selected;
      } else if (c == transformMenuG2) {
        fp.setTransformG2(transformMenuG2.getSelectedIndex());
      } else if (c == antiAliasMenu || c == fracMetricsMenu) {
        if (c == antiAliasMenu) {
          boolean enabled = FontPanel.AAValues.isLCDMode(antiAliasMenu.getSelectedItem());
          contrastSlider.setEnabled(enabled);
        }
        fp.setRenderingHints(antiAliasMenu.getSelectedItem(), fracMetricsMenu.getSelectedItem(),
            contrastSlider.getValue());
      }
    }
  }
  public void stateChanged(ChangeEvent e) {
    Object source = e.getSource();
    if (source instanceof JSlider) {
      fp.setRenderingHints(antiAliasMenu.getSelectedItem(), fracMetricsMenu.getSelectedItem(),
          contrastSlider.getValue());
    }
  }
  // / ItemListener interface function
  // / Responds to JCheckBoxMenuItem, JComboBox and JCheckBox actions
  public void itemStateChanged(ItemEvent e) {
    Object source = e.getSource();
    if (source instanceof JCheckBoxMenuItem) {
      JCheckBoxMenuItem cbmi = (JCheckBoxMenuItem) source;
      if (cbmi == displayGridCBMI)
        fp.setGridDisplay(displayGridCBMI.getState());
      else if (cbmi == force16ColsCBMI)
        fp.setForce16Columns(force16ColsCBMI.getState());
      else if (cbmi == showFontInfoCBMI) {
        if (showFontInfoCBMI.getState()) {
          fireUpdateFontInfo();
          fontInfoDialog.show();
        } else
          fontInfoDialog.hide();
      }
    }
  }
  private static void printUsage() {
    String usage = "Usage: java -jar Font2DTest.jar [options]\n" + "\nwhere options include:\n"
        + "    -dcdc | -disablecandisplaycheck disable canDisplay check for font\n"
        + "    -?    | -help                   print this help message\n" + "\nExample :\n"
        + "     To disable canDisplay check on font for ranges\n"
        + "     java -jar Font2DTest.jar -dcdc";
    System.out.println(usage);
    System.exit(0);
  }
  // / Main function
  public static void main(String argv[]) {
    if (argv.length > 0) {
      if (argv[0].equalsIgnoreCase("-disablecandisplaycheck") || argv[0].equalsIgnoreCase("-dcdc")) {
        canDisplayCheck = false;
      } else {
        printUsage();
      }
    }
    UIManager.put("swing.boldMetal", Boolean.FALSE);
    final JFrame f = new JFrame("Font2DTest");
    final Font2DTest f2dt = new Font2DTest(f, false);
    f.addWindowListener(new WindowAdapter() {
      public void windowOpening(WindowEvent e) {
        f2dt.repaint();
      }
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    f.getContentPane().add(f2dt);
    f.pack();
    f.show();
  }
  // / Inner class definitions...
  // / Class to display just an image file
  // / Used to show the comparison PNG image
  private final class ImagePanel extends JPanel {
    private final BufferedImage bi;
    public ImagePanel(BufferedImage image) {
      bi = image;
    }
    public Dimension getPreferredSize() {
      return new Dimension(bi.getWidth(), bi.getHeight());
    }
    public void paintComponent(Graphics g) {
      g.drawImage(bi, 0, 0, this);
    }
  }
  // / Classes made to avoid repetitive calls... (being lazy)
  private final class ButtonV2 extends JButton {
    public ButtonV2(String name, ActionListener al) {
      super(name);
      this.addActionListener(al);
    }
  }
  private final class ChoiceV2 extends JComboBox {
    private BitSet bitSet = null;
    public ChoiceV2() {
      ;
    }
    public ChoiceV2(ActionListener al) {
      super();
      this.addActionListener(al);
    }
    public ChoiceV2(ActionListener al, boolean fontChoice) {
      this(al);
      if (fontChoice) {
        // Register this component in ToolTipManager
        setToolTipText("");
        bitSet = new BitSet();
        setRenderer(new ChoiceV2Renderer(this));
      }
    }
    public String getToolTipText() {
      int index = this.getSelectedIndex();
      String fontName = (String) this.getSelectedItem();
      if (fontName != null && (textMenu.getSelectedIndex() == fp.RANGE_TEXT)) {
        if (getBit(index)) {
          return "Font \"" + fontName + "\" can display some characters in \""
              + rm.getSelectedItem() + "\" range";
        } else {
          return "Font \"" + fontName + "\" cannot display any characters in \""
              + rm.getSelectedItem() + "\" range";
        }
      }
      return super.getToolTipText();
    }
    public void setBit(int bitIndex, boolean value) {
      bitSet.set(bitIndex, value);
    }
    public boolean getBit(int bitIndex) {
      return bitSet.get(bitIndex);
    }
  }
  private final class ChoiceV2Renderer extends DefaultListCellRenderer {
    private ImageIcon yesImage, blankImage;
    private ChoiceV2 choice = null;
    public ChoiceV2Renderer(ChoiceV2 choice) {
      try {
        yesImage = new ImageIcon(getClass().getResource("yes.gif"));
        blankImage = new ImageIcon(getClass().getResource("blank.gif"));
      } catch (Exception exception) {
        System.out.println("Exception : " + exception);
      }
      this.choice = choice;
    }
    public Component getListCellRendererComponent(JList list, Object value, int index,
        boolean isSelected, boolean cellHasFocus) {
      if (textMenu.getSelectedIndex() == fp.RANGE_TEXT) {
        super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        // For JComboBox if index is -1, its rendering the selected index.
        if (index == -1) {
          index = choice.getSelectedIndex();
        }
        if (choice.getBit(index)) {
          setIcon(yesImage);
        } else {
          setIcon(blankImage);
        }
      } else {
        super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        setIcon(blankImage);
      }
      return this;
    }
  }
  private final class LabelV2 extends JLabel {
    public LabelV2(String name) {
      super(name);
    }
  }
  private final class MenuItemV2 extends JMenuItem {
    public MenuItemV2(String name, ActionListener al) {
      super(name);
      this.addActionListener(al);
    }
  }
  private final class CheckboxMenuItemV2 extends JCheckBoxMenuItem {
    public CheckboxMenuItemV2(String name, boolean b, ItemListener il) {
      super(name, b);
      this.addItemListener(il);
    }
  }
}
/*
 * @(#)FontPanel.java 1.20 05/11/17
 * 
 * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * -Redistribution of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 
 * -Redistribution in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * 
 * Neither the name of Sun Microsystems, Inc. or the names of contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.
 * 
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
 * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS
 * LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A
 * RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 * IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT
 * OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
 * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS
 * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 * 
 * You acknowledge that this software is not designed, licensed or intended for
 * use in the design, construction, operation or maintenance of any nuclear
 * facility.
 */
/*
 * @(#)FontPanel.java 1.20 05/11/17
 */
/**
 * FontPanel.java
 * 
 * @version
 * @(#)FontPanel.java 1.1 00/08/22
 * @author Shinsuke Fukuda
 * @author Ankit Patel [Conversion to Swing - 01/07/30]
 */
// / This panel is combination of the text drawing area of Font2DTest
// / and the custom controlled scroll bar
final class FontPanel extends JPanel implements AdjustmentListener {
  // / Drawing Option Constants
  private final String STYLES[] = { "plain", "bold", "italic", "bold italic" };
  private final int NONE = 0;
  private final int SCALE = 1;
  private final int SHEAR = 2;
  private final int ROTATE = 3;
  private final String TRANSFORMS[] = { "with no transforms", "with scaling", "with Shearing",
      "with rotation" };
  private final int DRAW_STRING = 0;
  private final int DRAW_CHARS = 1;
  private final int DRAW_BYTES = 2;
  private final int DRAW_GLYPHV = 3;
  private final int TL_DRAW = 4;
  private final int GV_OUTLINE = 5;
  private final int TL_OUTLINE = 6;
  private final String METHODS[] = { "drawString", "drawChars", "drawBytes", "drawGlyphVector",
      "TextLayout.draw", "GlyphVector.getOutline", "TextLayout.getOutline" };
  public final int RANGE_TEXT = 0;
  public final int ALL_GLYPHS = 1;
  public final int USER_TEXT = 2;
  public final int FILE_TEXT = 3;
  private final String MS_OPENING[] = { " Unicode ", " Glyph Code ", " lines ", " lines " };
  private final String MS_CLOSING[] = { "", "", " of User Text ",
      " of LineBreakMeasurer-reformatted Text " };
  // / General Graphics Variable
  private final JScrollBar verticalBar;
  private final FontCanvas fc;
  private boolean updateBackBuffer = true;
  private boolean updateFontMetrics = true;
  private boolean updateFont = true;
  private boolean force16Cols = false;
  public boolean showingError = false;
  private int g2Transform = NONE; // / ABP
  // / Printing constants and variables
  public final int ONE_PAGE = 0;
  public final int CUR_RANGE = 1;
  public final int ALL_TEXT = 2;
  private int printMode = ONE_PAGE;
  private PageFormat page = null;
  private PrinterJob printer = null;
  // / Text drawing variables
  private String fontName = "Dialog";
  private float fontSize = 12;
  private int fontStyle = Font.PLAIN;
  private int fontTransform = NONE;
  private Font testFont = null;
  private Object antiAliasType = VALUE_TEXT_ANTIALIAS_DEFAULT;
  private Object fractionalMetricsType = VALUE_FRACTIONALMETRICS_DEFAULT;
  private Object lcdContrast = getDefaultLCDContrast();
  private int drawMethod = DRAW_STRING;
  private int textToUse = RANGE_TEXT;
  private String userText[] = null;
  private String fileText[] = null;
  private int drawRange[] = { 0x0000, 0x007f };
  private String fontInfos[] = new String[2];
  private boolean showGrid = true;
  // / Parent Font2DTest panel
  private final Font2DTest f2dt;
  private final JFrame parent;
  public FontPanel(Font2DTest demo, JFrame f) {
    f2dt = demo;
    parent = f;
    verticalBar = new JScrollBar(JScrollBar.VERTICAL);
    fc = new FontCanvas();
    this.setLayout(new BorderLayout());
    this.add("Center", fc);
    this.add("East", verticalBar);
    verticalBar.addAdjustmentListener(this);
    this.addComponentListener(new ComponentAdapter() {
      public void componentResized(ComponentEvent e) {
        updateBackBuffer = true;
        updateFontMetrics = true;
      }
    });
    // / Initialize font and its infos
    testFont = new Font(fontName, fontStyle, (int) fontSize);
    if ((float) ((int) fontSize) != fontSize) {
      testFont = testFont.deriveFont(fontSize);
    }
    updateFontInfo();
  }
  public Dimension getPreferredSize() {
    return new Dimension(600, 200);
  }
  // / Functions called by the main programs to set the various parameters
  public void setTransformG2(int transform) {
    g2Transform = transform;
    updateBackBuffer = true;
    updateFontMetrics = true;
    fc.repaint();
  }
  // / convenience fcn to create AffineTransform of appropriate type
  private AffineTransform getAffineTransform(int transform) {
    // / ABP
    AffineTransform at = new AffineTransform();
    switch (transform) {
    case SCALE:
      at.setToScale(1.5f, 1.5f);
      break;
    case ROTATE:
      at.setToRotation(Math.PI / 6);
      break;
    case SHEAR:
      at.setToShear(0.4f, 0);
      break;
    case NONE:
      break;
    default:
      // System.err.println( "Illegal G2 Transform Arg: " + transform);
      break;
    }
    return at;
  }
  public void setFontParams(Object obj, float size, int style, int transform) {
    setFontParams((String) obj, size, style, transform);
  }
  public void setFontParams(String name, float size, int style, int transform) {
    boolean fontModified = false;
    if (!name.equals(fontName) || style != fontStyle)
      fontModified = true;
    fontName = name;
    fontSize = size;
    fontStyle = style;
    fontTransform = transform;
    // / Recreate the font as specified
    testFont = new Font(fontName, fontStyle, (int) fontSize);
    if ((float) ((int) fontSize) != fontSize) {
      testFont = testFont.deriveFont(fontSize);
    }
    if (fontTransform != NONE) {
      AffineTransform at = getAffineTransform(fontTransform);
      testFont = testFont.deriveFont(at);
    }
    updateBackBuffer = true;
    updateFontMetrics = true;
    fc.repaint();
    if (fontModified) {
      // / Tell main panel to update the font info
      updateFontInfo();
      f2dt.fireUpdateFontInfo();
    }
  }
  public void setRenderingHints(Object aa, Object fm, Object contrast) {
    antiAliasType = ((AAValues) aa).getHint();
    fractionalMetricsType = ((FMValues) fm).getHint();
    lcdContrast = contrast;
    updateBackBuffer = true;
    updateFontMetrics = true;
    fc.repaint();
  }
  public void setDrawMethod(int i) {
    drawMethod = i;
    updateBackBuffer = true;
    fc.repaint();
  }
  public void setTextToDraw(int i, int range[], String textSet[], String fileData[]) {
    textToUse = i;
    if (textToUse == RANGE_TEXT)
      drawRange = range;
    else if (textToUse == ALL_GLYPHS)
      drawMethod = DRAW_GLYPHV;
    else if (textToUse == USER_TEXT)
      userText = textSet;
    else if (textToUse == FILE_TEXT) {
      fileText = fileData;
      drawMethod = TL_DRAW;
    }
    updateBackBuffer = true;
    updateFontMetrics = true;
    fc.repaint();
    updateFontInfo();
  }
  public void setGridDisplay(boolean b) {
    showGrid = b;
    updateBackBuffer = true;
    fc.repaint();
  }
  public void setForce16Columns(boolean b) {
    force16Cols = b;
    updateBackBuffer = true;
    updateFontMetrics = true;
    fc.repaint();
  }
  // / Prints out the text display area
  public void doPrint(int i) {
    if (printer == null) {
      printer = PrinterJob.getPrinterJob();
      page = printer.defaultPage();
    }
    printMode = i;
    printer.setPrintable(fc, page);
    if (printer.printDialog()) {
      try {
        printer.print();
      } catch (Exception e) {
        f2dt.fireChangeStatus("ERROR: Printing Failed; See Stack Trace", true);
      }
    }
  }
  // / Displays the page setup dialog and updates PageFormat info
  public void doPageSetup() {
    if (printer == null) {
      printer = PrinterJob.getPrinterJob();
      page = printer.defaultPage();
    }
    page = printer.pageDialog(page);
  }
  // / Obtains the information about selected font
  private void updateFontInfo() {
    int numGlyphs = 0, numCharsInRange = drawRange[1] - drawRange[0] + 1;
    fontInfos[0] = "Font Face Name: " + testFont.getFontName();
    fontInfos[1] = "Glyphs in This Range: ";
    if (textToUse == RANGE_TEXT) {
      for (int i = drawRange[0]; i < drawRange[1]; i++)
        if (testFont.canDisplay(i))
          numGlyphs++;
      fontInfos[1] = fontInfos[1] + numGlyphs + " / " + numCharsInRange;
    } else
      fontInfos[1] = null;
  }
  // / Accessor for the font information
  public String[] getFontInfo() {
    return fontInfos;
  }
  // / Collects the currectly set options and returns them as string
  public String getCurrentOptions() {
    // / Create a new String to store the options
    // / The array will contain all 8 setting (font name, size...) and
    // / character range or user text data used (no file text data)
    int userTextSize = 0;
    String options;
    options = (fontName + "\n" + fontSize + "\n" + fontStyle + "\n" + fontTransform + "\n"
        + g2Transform + "\n" + textToUse + "\n" + drawMethod + "\n"
        + AAValues.getHintVal(antiAliasType) + "\n" + FMValues.getHintVal(fractionalMetricsType)
        + "\n" + lcdContrast + "\n");
    if (textToUse == USER_TEXT)
      for (int i = 0; i < userText.length; i++)
        options += (userText[i] + "\n");
    return options;
  }
  // / Reload all options and refreshes the canvas
  public void loadOptions(boolean grid, boolean force16, int start, int end, String name,
      float size, int style, int transform, int g2transform, int text, int method, int aa, int fm,
      int contrast, String user[]) {
    int range[] = { start, end };
    // / Since repaint call has a low priority, these functions will finish
    // / before the actual repainting is done
    setGridDisplay(grid);
    setForce16Columns(force16);
    // previous call to readTextFile has already set the text to draw
    if (textToUse != FILE_TEXT) {
      setTextToDraw(text, range, user, null);
    }
    setFontParams(name, size, style, transform);
    setTransformG2(g2transform); // ABP
    setDrawMethod(method);
    setRenderingHints(AAValues.getValue(aa), FMValues.getValue(fm), new Integer(contrast));
  }
  // / Writes the current screen to PNG file
  public void doSavePNG(String fileName) {
    fc.writePNG(fileName);
  }
  // / When scrolled using the scroll bar, update the backbuffer
  public void adjustmentValueChanged(AdjustmentEvent e) {
    updateBackBuffer = true;
    fc.repaint();
  }
  public void paintComponent(Graphics g) {
    // Windows does not repaint correctly, after
    // a zoom. Thus, we need to force the canvas
    // to repaint, but only once. After the first repaint,
    // everything stabilizes. [ABP]
    fc.repaint();
  }
  // / Inner class definition...
  // / Inner panel that holds the actual drawing area and its routines
  private class FontCanvas extends JPanel implements MouseListener, MouseMotionListener, Printable {
    // / Number of characters that will fit across and down this canvas
    private int numCharAcross, numCharDown;
    // / First and last character/line that will be drawn
    // / Limit is the end of range/text where no more draw will be done
    private int drawStart, drawEnd, drawLimit;
    // / FontMetrics variables
    // / Here, gridWidth is equivalent to maxAdvance (slightly bigger though)
    // / and gridHeight is equivalent to lineHeight
    private int maxAscent, maxDescent, gridWidth = 0, gridHeight = 0;
    // / Offset from the top left edge of the canvas where the draw will start
    private int canvasInset_X = 5, canvasInset_Y = 5;
    // / Offscreen buffer of this canvas
    private BufferedImage backBuffer = null;
    // / LineBreak"ed TextLayout vector
    private Vector lineBreakTLs = null;
    // / Whether the current draw command requested is for printing
    private boolean isPrinting = false;
    // / Other printing infos
    private int lastPage, printPageNumber, currentlyShownChar = 0;
    private final int PR_OFFSET = 10;
    private final int PR_TITLE_LINEHEIGHT = 30;
    // / Information about zooming (used with range text draw)
    private final JWindow zoomWindow;
    private BufferedImage zoomImage = null;
    private int mouseOverCharX = -1, mouseOverCharY = -1;
    private int currMouseOverChar = -1, prevZoomChar = -1;
    private float ZOOM = 2.0f;
    private boolean nowZooming = false;
    private boolean firstTime = true;
    // ABP
    // / Status bar message backup
    private String backupStatusString = null;
    // / Error constants
    private final String ERRORS[] = {
        "ERROR: drawBytes cannot handle characters beyond 0x00FF. Select different range or draw methods.",
        "ERROR: Cannot fit text with the current font size. Resize the window or use smaller font size.",
        "ERROR: Cannot print with the current font size. Use smaller font size.", };
    private final int DRAW_BYTES_ERROR = 0;
    private final int CANT_FIT_DRAW = 1;
    private final int CANT_FIT_PRINT = 2;
    // / Other variables
    private final Cursor blankCursor;
    public FontCanvas() {
      this.addMouseListener(this);
      this.addMouseMotionListener(this);
      this.setForeground(Color.black);
      this.setBackground(Color.white);
      // / Creates an invisble pointer by giving it bogus image
      // / Possibly find a workaround for this...
      Toolkit tk = Toolkit.getDefaultToolkit();
      byte bogus[] = { (byte) 0 };
      blankCursor = tk.createCustomCursor(tk.createImage(bogus), new Point(0, 0), "");
      zoomWindow = new JWindow(parent) {
        public void paint(Graphics g) {
          g.drawImage(zoomImage, 0, 0, zoomWindow);
        }
      };
      zoomWindow.setCursor(blankCursor);
      zoomWindow.pack();
    }
    public boolean firstTime() {
      return firstTime;
    }
    public void refresh() {
      firstTime = false;
      updateBackBuffer = true;
      repaint();
    }
    // / Sets the font, hints, according to the set parameters
    private void setParams(Graphics2D g2) {
      g2.setFont(testFont);
      g2.setRenderingHint(KEY_TEXT_ANTIALIASING, antiAliasType);
      g2.setRenderingHint(KEY_FRACTIONALMETRICS, fractionalMetricsType);
      g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST, lcdContrast);
      /*
       * I am preserving a somewhat dubious behaviour of this program. Outline
       * text would be drawn anti-aliased by setting the graphics anti-aliasing
       * hint if the text anti-aliasing hint was set. The dubious element here
       * is that people simply using this program may think this is built-in
       * behaviour but its not - at least not when the app explictly draws
       * outline text. This becomes more dubious in cases such as "GASP" where
       * the size at which text is AA"ed is not something you can easily
       * calculate, so mimicing that behaviour isn"t going to be easy. So I
       * precisely preserve the behaviour : this is done only if the AA value is
       * "ON". Its not applied in the other cases.
       */
      if (antiAliasType == VALUE_TEXT_ANTIALIAS_ON
          && (drawMethod == TL_OUTLINE || drawMethod == GV_OUTLINE)) {
        g2.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON);
      } else {
        g2.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_OFF);
      }
    }
    // / Draws the grid (Used for unicode/glyph range drawing)
    private void drawGrid(Graphics2D g2) {
      int totalGridWidth = numCharAcross * gridWidth;
      int totalGridHeight = numCharDown * gridHeight;
      g2.setColor(Color.black);
      for (int i = 0; i < numCharDown + 1; i++)
        g2.drawLine(canvasInset_X, i * gridHeight + canvasInset_Y, canvasInset_X + totalGridWidth,
            i * gridHeight + canvasInset_Y);
      for (int i = 0; i < numCharAcross + 1; i++)
        g2.drawLine(i * gridWidth + canvasInset_X, canvasInset_Y, i * gridWidth + canvasInset_X,
            canvasInset_Y + totalGridHeight);
    }
    // / Draws one character at time onto the canvas according to
    // / the method requested (Used for RANGE_TEXT and ALL_GLYPHS)
    public void modeSpecificDrawChar(Graphics2D g2, int charCode, int baseX, int baseY) {
      GlyphVector gv;
      int oneGlyph[] = { charCode };
      char charArray[] = Character.toChars(charCode);
      FontRenderContext frc = g2.getFontRenderContext();
      AffineTransform oldTX = g2.getTransform();
      // / Create GlyphVector to measure the exact visual advance
      // / Using that number, adjust the position of the character drawn
      if (textToUse == ALL_GLYPHS)
        gv = testFont.createGlyphVector(frc, oneGlyph);
      else
        gv = testFont.createGlyphVector(frc, charArray);
      Rectangle2D r2d2 = gv.getPixelBounds(frc, 0, 0);
      int shiftedX = baseX;
      // getPixelBounds returns a result in device space.
      // we need to convert back to user space to be able to
      // calculate the shift as baseX is in user space.
      try {
        double pt[] = new double[4];
        pt[0] = r2d2.getX();
        pt[1] = r2d2.getY();
        pt[2] = r2d2.getX() + r2d2.getWidth();
        pt[3] = r2d2.getY() + r2d2.getHeight();
        oldTX.inverseTransform(pt, 0, pt, 0, 2);
        shiftedX = baseX - (int) (pt[2] / 2 + pt[0]);
      } catch (NoninvertibleTransformException e) {
      }
      // / ABP - keep track of old tform, restore it later
      g2.translate(shiftedX, baseY);
      g2.transform(getAffineTransform(g2Transform));
      if (textToUse == ALL_GLYPHS)
        g2.drawGlyphVector(gv, 0f, 0f);
      else {
        if (testFont.canDisplay(charCode))
          g2.setColor(Color.black);
        else {
          g2.setColor(Color.lightGray);
        }
        switch (drawMethod) {
        case DRAW_STRING:
          g2.drawString(new String(charArray), 0, 0);
          break;
        case DRAW_CHARS:
          g2.drawChars(charArray, 0, 1, 0, 0);
          break;
        case DRAW_BYTES:
          if (charCode > 0xff)
            throw new CannotDrawException(DRAW_BYTES_ERROR);
          byte oneByte[] = { (byte) charCode };
          g2.drawBytes(oneByte, 0, 1, 0, 0);
          break;
        case DRAW_GLYPHV:
          g2.drawGlyphVector(gv, 0f, 0f);
          break;
        case TL_DRAW:
          TextLayout tl = new TextLayout(new String(charArray), testFont, frc);
          tl.draw(g2, 0f, 0f);
          break;
        case GV_OUTLINE:
          r2d2 = gv.getVisualBounds();
          shiftedX = baseX - (int) (r2d2.getWidth() / 2 + r2d2.getX());
          g2.draw(gv.getOutline(0f, 0f));
          break;
        case TL_OUTLINE:
          r2d2 = gv.getVisualBounds();
          shiftedX = baseX - (int) (r2d2.getWidth() / 2 + r2d2.getX());
          TextLayout tlo = new TextLayout(new String(charArray), testFont, g2
              .getFontRenderContext());
          g2.draw(tlo.getOutline(null));
        }
      }
      // / ABP - restore old tform
      g2.setTransform(oldTX);
    }
    // Java2D!\\U01d586\\U01d587\\U01d588
    // / Draws one line of text at given position
    private void modeSpecificDrawLine(Graphics2D g2, String line, int baseX, int baseY) {
      // / ABP - keep track of old tform, restore it later
      AffineTransform oldTx = null;
      oldTx = g2.getTransform();
      g2.translate(baseX, baseY);
      g2.transform(getAffineTransform(g2Transform));
      switch (drawMethod) {
      case DRAW_STRING:
        g2.drawString(line, 0, 0);
        break;
      case DRAW_CHARS:
        g2.drawChars(line.toCharArray(), 0, line.length(), 0, 0);
        break;
      case DRAW_BYTES:
        try {
          byte lineBytes[] = line.getBytes("ISO-8859-1");
          g2.drawBytes(lineBytes, 0, lineBytes.length, 0, 0);
        } catch (Exception e) {
          e.printStackTrace();
        }
        break;
      case DRAW_GLYPHV:
        GlyphVector gv = testFont.createGlyphVector(g2.getFontRenderContext(), line);
        g2.drawGlyphVector(gv, (float) 0, (float) 0);
        break;
      case TL_DRAW:
        TextLayout tl = new TextLayout(line, testFont, g2.getFontRenderContext());
        tl.draw(g2, (float) 0, (float) 0);
        break;
      case GV_OUTLINE:
        GlyphVector gvo = testFont.createGlyphVector(g2.getFontRenderContext(), line);
        g2.draw(gvo.getOutline((float) 0, (float) 0));
        break;
      case TL_OUTLINE:
        TextLayout tlo = new TextLayout(line, testFont, g2.getFontRenderContext());
        AffineTransform at = new AffineTransform();
        g2.draw(tlo.getOutline(at));
      }
      // / ABP - restore old tform
      g2.setTransform(oldTx);
    }
    // / Draws one line of text at given position
    private void tlDrawLine(Graphics2D g2, TextLayout tl, float baseX, float baseY) {
      // / ABP - keep track of old tform, restore it later
      AffineTransform oldTx = null;
      oldTx = g2.getTransform();
      g2.translate(baseX, baseY);
      g2.transform(getAffineTransform(g2Transform));
      tl.draw(g2, (float) 0, (float) 0);
      // / ABP - restore old tform
      g2.setTransform(oldTx);
    }
    // / If textToUse is set to range drawing, then convert
    // / int to hex string and prepends 0s to make it length 4
    // / Otherwise line number was fed; simply return number + 1 converted to
    // String
    // / (This is because first line is 1, not 0)
    private String modeSpecificNumStr(int i) {
      if (textToUse == USER_TEXT || textToUse == FILE_TEXT)
        return String.valueOf(i + 1);
      StringBuffer s = new StringBuffer(Integer.toHexString(i));
      while (s.length() < 4)
        s.insert(0, "0");
      return s.toString().toUpperCase();
    }
    // / Resets the scrollbar to display correct range of text currently on
    // screen
    // / (This scrollbar is not part of a "ScrollPane". It merely simulates its
    // effect by
    // / indicating the necessary area to be drawn within the panel.
    // / By doing this, it prevents creating gigantic panel when large text
    // range,
    // / i.e. CJK Ideographs, is requested)
    private void resetScrollbar(int oldValue) {
      int totalNumRows = 1, numCharToDisplay;
      if (textToUse == RANGE_TEXT || textToUse == ALL_GLYPHS) {
        if (textToUse == RANGE_TEXT)
          numCharToDisplay = drawRange[1] - drawRange[0];
        else
          // / textToUse == ALL_GLYPHS
          numCharToDisplay = testFont.getNumGlyphs();
        totalNumRows = numCharToDisplay / numCharAcross;
        if (numCharToDisplay % numCharAcross != 0)
          totalNumRows++;
        if (oldValue / numCharAcross > totalNumRows)
          oldValue = 0;
        verticalBar.setValues(oldValue / numCharAcross, numCharDown, 0, totalNumRows);
      } else {
        if (textToUse == USER_TEXT)
          totalNumRows = userText.length;
        else
          // / textToUse == FILE_TEXT;
          totalNumRows = lineBreakTLs.size();
        verticalBar.setValues(oldValue, numCharDown, 0, totalNumRows);
      }
      if (totalNumRows <= numCharDown && drawStart == 0) {
        verticalBar.setEnabled(false);
      } else {
        verticalBar.setEnabled(true);
      }
    }
    // / Calculates the font"s metrics that will be used for draw
    private void calcFontMetrics(Graphics2D g2d, int w, int h) {
      FontMetrics fm;
      Graphics2D g2 = (Graphics2D) g2d.create();
      // / ABP
      if (g2Transform != NONE && textToUse != FILE_TEXT) {
        g2.setFont(g2.getFont().deriveFont(getAffineTransform(g2Transform)));
        fm = g2.getFontMetrics();
      } else {
        fm = g2.getFontMetrics();
      }
      maxAscent = fm.getMaxAscent();
      maxDescent = fm.getMaxDescent();
      if (maxAscent == 0)
        maxAscent = 10;
      if (maxDescent == 0)
        maxDescent = 5;
      if (textToUse == RANGE_TEXT || textToUse == ALL_GLYPHS) {
        // / Give slight extra room for each character
        maxAscent += 3;
        maxDescent += 3;
        gridWidth = fm.getMaxAdvance() + 6;
        gridHeight = maxAscent + maxDescent;
        if (force16Cols)
          numCharAcross = 16;
        else
          numCharAcross = (w - 10) / gridWidth;
        numCharDown = (h - 10) / gridHeight;
        canvasInset_X = (w - numCharAcross * gridWidth) / 2;
        canvasInset_Y = (h - numCharDown * gridHeight) / 2;
        if (numCharDown == 0 || numCharAcross == 0)
          throw new CannotDrawException(isPrinting ? CANT_FIT_PRINT : CANT_FIT_DRAW);
        if (!isPrinting)
          resetScrollbar(verticalBar.getValue() * numCharAcross);
      } else {
        maxDescent += fm.getLeading();
        canvasInset_X = 5;
        canvasInset_Y = 5;
        // / gridWidth and numCharAcross will not be used in this mode...
        gridHeight = maxAscent + maxDescent;
        numCharDown = (h - canvasInset_Y * 2) / gridHeight;
        if (numCharDown == 0)
          throw new CannotDrawException(isPrinting ? CANT_FIT_PRINT : CANT_FIT_DRAW);
        // / If this is text loaded from file, prepares the LineBreak"ed
        // / text layout at this point
        if (textToUse == FILE_TEXT) {
          if (!isPrinting)
            f2dt.fireChangeStatus("LineBreaking Text... Please Wait", false);
          lineBreakTLs = new Vector();
          for (int i = 0; i < fileText.length; i++) {
            AttributedString as = new AttributedString(fileText[i], g2.getFont().getAttributes());
            LineBreakMeasurer lbm = new LineBreakMeasurer(as.getIterator(), g2
                .getFontRenderContext());
            while (lbm.getPosition() < fileText[i].length())
              lineBreakTLs.add(lbm.nextLayout((float) w));
          }
        }
        if (!isPrinting)
          resetScrollbar(verticalBar.getValue());
      }
    }
    // / Calculates the amount of text that will be displayed on screen
    private void calcTextRange() {
      String displaying = null;
      if (textToUse == RANGE_TEXT || textToUse == ALL_GLYPHS) {
        if (isPrinting)
          if (printMode == ONE_PAGE)
            drawStart = currentlyShownChar;
          else
            // / printMode == CUR_RANGE
            drawStart = numCharAcross * numCharDown * printPageNumber;
        else
          drawStart = verticalBar.getValue() * numCharAcross;
        if (textToUse == RANGE_TEXT) {
          drawStart += drawRange[0];
          drawLimit = drawRange[1];
        } else
          drawLimit = testFont.getNumGlyphs();
        drawEnd = drawStart + numCharAcross * numCharDown - 1;
        if (drawEnd >= drawLimit)
          drawEnd = drawLimit;
      } else {
        if (isPrinting)
          if (printMode == ONE_PAGE)
            drawStart = currentlyShownChar;
          else
            // / printMode == ALL_TEXT
            drawStart = numCharDown * printPageNumber;
        else {
          drawStart = verticalBar.getValue();
        }
        drawEnd = drawStart + numCharDown - 1;
        if (textToUse == USER_TEXT)
          drawLimit = userText.length - 1;
        else
          drawLimit = lineBreakTLs.size() - 1;
        if (drawEnd >= drawLimit)
          drawEnd = drawLimit;
      }
      // ABP
      if (drawStart > drawEnd) {
        drawStart = 0;
        verticalBar.setValue(drawStart);
      }
      // / Change the status bar if not printing...
      if (!isPrinting) {
        backupStatusString = ("Displaying" + MS_OPENING[textToUse] + modeSpecificNumStr(drawStart)
            + " to " + modeSpecificNumStr(drawEnd) + MS_CLOSING[textToUse]);
        f2dt.fireChangeStatus(backupStatusString, false);
      }
    }
    // / Draws text according to the parameters set by Font2DTest GUI
    private void drawText(Graphics g, int w, int h) {
      Graphics2D g2;
      // / Create back buffer when not printing, and its Graphics2D
      // / Then set drawing parameters for that Graphics2D object
      if (isPrinting)
        g2 = (Graphics2D) g;
      else {
        backBuffer = (BufferedImage) this.createImage(w, h);
        g2 = backBuffer.createGraphics();
        g2.setColor(Color.white);
        g2.fillRect(0, 0, w, h);
        g2.setColor(Color.black);
      }
      // / sets font, RenderingHints.
      setParams(g2);
      // / If flag is set, recalculate fontMetrics and reset the scrollbar
      if (updateFontMetrics || isPrinting) {
        // / NOTE: re-calculates in case G2 transform
        // / is something other than NONE
        calcFontMetrics(g2, w, h);
        updateFontMetrics = false;
      }
      // / Calculate the amount of text that can be drawn...
      calcTextRange();
      // / Draw according to the set "Text to Use" mode
      if (textToUse == RANGE_TEXT || textToUse == ALL_GLYPHS) {
        int charToDraw = drawStart;
        if (showGrid)
          drawGrid(g2);
        if (!isPrinting)
          g.drawImage(backBuffer, 0, 0, this);
        for (int i = 0; i < numCharDown && charToDraw <= drawEnd; i++) {
          for (int j = 0; j < numCharAcross && charToDraw <= drawEnd; j++, charToDraw++) {
            int gridLocX = j * gridWidth + canvasInset_X;
            int gridLocY = i * gridHeight + canvasInset_Y;
            modeSpecificDrawChar(g2, charToDraw, gridLocX + gridWidth / 2, gridLocY + maxAscent);
            // if ( !isPrinting ) {
            // g.setClip( gridLocX, gridLocY, gridWidth + 1, gridHeight + 1 );
            // g.drawImage( backBuffer, 0, 0, this );
            // }
          }
        }
      } else if (textToUse == USER_TEXT) {
        g2.drawRect(0, 0, w - 1, h - 1);
        if (!isPrinting)
          g.drawImage(backBuffer, 0, 0, this);
        for (int i = drawStart; i <= drawEnd; i++) {
          int lineStartX = canvasInset_Y;
          int lineStartY = (i - drawStart) * gridHeight + maxAscent;
          modeSpecificDrawLine(g2, userText[i], lineStartX, lineStartY);
        }
      } else {
        float xPos, yPos = (float) canvasInset_Y;
        g2.drawRect(0, 0, w - 1, h - 1);
        if (!isPrinting)
          g.drawImage(backBuffer, 0, 0, this);
        for (int i = drawStart; i <= drawEnd; i++) {
          TextLayout oneLine = (TextLayout) lineBreakTLs.elementAt(i);
          xPos = oneLine.isLeftToRight() ? canvasInset_X
              : ((float) w - oneLine.getAdvance() - canvasInset_X);
          float fmData[] = { 0, oneLine.getAscent(), 0, oneLine.getDescent(), 0,
              oneLine.getLeading() };
          if (g2Transform != NONE) {
            AffineTransform at = getAffineTransform(g2Transform);
            at.transform(fmData, 0, fmData, 0, 3);
          }
          // yPos += oneLine.getAscent();
          yPos += fmData[1]; // ascent
          // oneLine.draw( g2, xPos, yPos );
          tlDrawLine(g2, oneLine, xPos, yPos);
          // yPos += oneLine.getDescent() + oneLine.getLeading();
          yPos += fmData[3] + fmData[5]; // descent + leading
        }
      }
      if (!isPrinting)
        g.drawImage(backBuffer, 0, 0, this);
      g2.dispose();
    }
    // / Component paintComponent function...
    // / Draws/Refreshes canvas according to flag(s) set by other functions
    public void paintComponent(Graphics g) {
      if (updateBackBuffer) {
        Dimension d = this.getSize();
        isPrinting = false;
        try {
          drawText(g, d.width, d.height);
        } catch (CannotDrawException e) {
          f2dt.fireChangeStatus(ERRORS[e.id], true);
          super.paintComponent(g);
          return;
        }
      } else {
        // / Screen refresh
        g.drawImage(backBuffer, 0, 0, this);
      }
      showingError = false;
      updateBackBuffer = false;
    }
    // / Printable interface function
    // / Component print function...
    public int print(Graphics g, PageFormat pf, int pageIndex) {
      if (pageIndex == 0) {
        // / Reset the last page index to max...
        lastPage = Integer.MAX_VALUE;
        currentlyShownChar = verticalBar.getValue() * numCharAcross;
      }
      if (printMode == ONE_PAGE) {
        if (pageIndex > 0)
          return NO_SUCH_PAGE;
      } else {
        if (pageIndex > lastPage)
          return NO_SUCH_PAGE;
      }
      int pageWidth = (int) pf.getImageableWidth();
      int pageHeight = (int) pf.getImageableHeight();
      // / Back up metrics and other drawing info before printing modifies it
      int backupDrawStart = drawStart, backupDrawEnd = drawEnd;
      int backupNumCharAcross = numCharAcross, backupNumCharDown = numCharDown;
      Vector backupLineBreakTLs = null;
      if (textToUse == FILE_TEXT)
        backupLineBreakTLs = (Vector) lineBreakTLs.clone();
      printPageNumber = pageIndex;
      isPrinting = true;
      // / Push the actual draw area 60 down to allow info to be printed
      g.translate((int) pf.getImageableX(), (int) pf.getImageableY() + 60);
      try {
        drawText(g, pageWidth, pageHeight - 60);
      } catch (CannotDrawException e) {
        f2dt.fireChangeStatus(ERRORS[e.id], true);
        return NO_SUCH_PAGE;
      }
      // / Draw information about what is being printed
      String hints = (" with antialias " + antiAliasType + "and" + " fractional metrics "
          + fractionalMetricsType + " and lcd contrast = " + lcdContrast);
      String infoLine1 = ("Printing" + MS_OPENING[textToUse] + modeSpecificNumStr(drawStart)
          + " to " + modeSpecificNumStr(drawEnd) + MS_CLOSING[textToUse]);
      String infoLine2 = ("With " + fontName + " " + STYLES[fontStyle] + " at " + fontSize
          + " point size " + TRANSFORMS[fontTransform]);
      String infoLine3 = "Using " + METHODS[drawMethod] + hints;
      String infoLine4 = "Page: " + (pageIndex + 1);
      g.setFont(new Font("dialog", Font.PLAIN, 12));
      g.setColor(Color.black);
      g.translate(0, -60);
      g.drawString(infoLine1, 15, 10);
      g.drawString(infoLine2, 15, 22);
      g.drawString(infoLine3, 15, 34);
      g.drawString(infoLine4, 15, 46);
      if (drawEnd == drawLimit)
        // / This indicates that the draw will be completed with this page
        lastPage = pageIndex;
      // / Restore the changed values back...
      // / This is important for JScrollBar settings and LineBreak"ed TLs
      drawStart = backupDrawStart;
      drawEnd = backupDrawEnd;
      numCharAcross = backupNumCharAcross;
      numCharDown = backupNumCharDown;
      if (textToUse == FILE_TEXT)
        lineBreakTLs = backupLineBreakTLs;
      return PAGE_EXISTS;
    }
    // / Ouputs the current canvas into a given PNG file
    public void writePNG(String fileName) {
      try {
        ImageIO.write(backBuffer, "png", new java.io.File(fileName));
      } catch (Exception e) {
        f2dt.fireChangeStatus("ERROR: Failed to Save PNG image; See stack trace", true);
        e.printStackTrace();
      }
    }
    // / Figures out whether a character at the pointer location is valid
    // / And if so, updates mouse location informations, as well as
    // / the information on the status bar
    private boolean checkMouseLoc(MouseEvent e) {
      if (gridWidth != 0 && gridHeight != 0)
        if (textToUse == RANGE_TEXT || textToUse == ALL_GLYPHS) {
          int charLocX = (e.getX() - canvasInset_X) / gridWidth;
          int charLocY = (e.getY() - canvasInset_Y) / gridHeight;
          // / Check to make sure the mouse click location is within drawn area
          if (charLocX >= 0 && charLocY >= 0 && charLocX < numCharAcross && charLocY < numCharDown) {
            int mouseOverChar = charLocX + (verticalBar.getValue() + charLocY) * numCharAcross;
            if (textToUse == RANGE_TEXT)
              mouseOverChar += drawRange[0];
            if (mouseOverChar > drawEnd)
              return false;
            mouseOverCharX = charLocX;
            mouseOverCharY = charLocY;
            currMouseOverChar = mouseOverChar;
            // / Update status bar
            f2dt.fireChangeStatus("Pointing to" + MS_OPENING[textToUse]
                + modeSpecificNumStr(mouseOverChar), false);
            return true;
          }
        }
      return false;
    }
    // / Shows (updates) the character zoom window
    public void showZoomed() {
      GlyphVector gv;
      Font backup = testFont;
      Point canvasLoc = this.getLocationOnScreen();
      // / Calculate the zoom area"s location and size...
      int dialogOffsetX = (int) (gridWidth * (ZOOM - 1) / 2);
      int dialogOffsetY = (int) (gridHeight * (ZOOM - 1) / 2);
      int zoomAreaX = mouseOverCharX * gridWidth + canvasInset_X - dialogOffsetX;
      int zoomAreaY = mouseOverCharY * gridHeight + canvasInset_Y - dialogOffsetY;
      int zoomAreaWidth = (int) (gridWidth * ZOOM);
      int zoomAreaHeight = (int) (gridHeight * ZOOM);
      // / Position and set size of zoom window as needed
      zoomWindow.setLocation(canvasLoc.x + zoomAreaX, canvasLoc.y + zoomAreaY);
      if (!nowZooming) {
        if (zoomWindow.getWarningString() != null)
          // / If this is not opened as a "secure" window,
          // / it has a banner below the zoom dialog which makes it look really
          // BAD
          // / So enlarge it by a bit
          zoomWindow.setSize(zoomAreaWidth + 1, zoomAreaHeight + 20);
        else
          zoomWindow.setSize(zoomAreaWidth + 1, zoomAreaHeight + 1);
      }
      // / Prepare zoomed image
      zoomImage = (BufferedImage) zoomWindow.createImage(zoomAreaWidth + 1, zoomAreaHeight + 1);
      Graphics2D g2 = (Graphics2D) zoomImage.getGraphics();
      testFont = testFont.deriveFont(fontSize * ZOOM);
      setParams(g2);
      g2.setColor(Color.white);
      g2.fillRect(0, 0, zoomAreaWidth, zoomAreaHeight);
      g2.setColor(Color.black);
      g2.drawRect(0, 0, zoomAreaWidth, zoomAreaHeight);
      modeSpecificDrawChar(g2, currMouseOverChar, zoomAreaWidth / 2, (int) (maxAscent * ZOOM));
      g2.dispose();
      if (!nowZooming)
        zoomWindow.show();
      // / This is sort of redundant... since there is a paint function
      // / inside zoomWindow definition that does the drawImage.
      // / (I should be able to call just repaint() here)
      // / However, for some reason, that paint function fails to respond
      // / from second time and on; So I have to force the paint here...
      zoomWindow.getGraphics().drawImage(zoomImage, 0, 0, this);
      nowZooming = true;
      prevZoomChar = currMouseOverChar;
      testFont = backup;
      // Windows does not repaint correctly, after
      // a zoom. Thus, we need to force the canvas
      // to repaint, but only once. After the first repaint,
      // everything stabilizes. [ABP]
      if (firstTime()) {
        refresh();
      }
    }
    // / Listener Functions
    // / MouseListener interface function
    // / Zooms a character when mouse is pressed above it
    public void mousePressed(MouseEvent e) {
      if (!showingError) {
        if (checkMouseLoc(e)) {
          showZoomed();
          this.setCursor(blankCursor);
        }
      }
    }
    // / MouseListener interface function
    // / Redraws the area that was drawn over by zoomed character
    public void mouseReleased(MouseEvent e) {
      if (textToUse == RANGE_TEXT || textToUse == ALL_GLYPHS) {
        if (nowZooming)
          zoomWindow.hide();
        nowZooming = false;
      }
      this.setCursor(Cursor.getDefaultCursor());
    }
    // / MouseListener interface function
    // / Resets the status bar to display range instead of a specific character
    public void mouseExited(MouseEvent e) {
      if (!showingError && !nowZooming)
        f2dt.fireChangeStatus(backupStatusString, false);
    }
    // / MouseMotionListener interface function
    // / Adjusts the status bar message when mouse moves over a character
    public void mouseMoved(MouseEvent e) {
      if (!showingError) {
        if (!checkMouseLoc(e))
          f2dt.fireChangeStatus(backupStatusString, false);
      }
    }
    // / MouseMotionListener interface function
    // / Scrolls the zoomed character when mouse is dragged
    public void mouseDragged(MouseEvent e) {
      if (!showingError)
        if (nowZooming) {
          if (checkMouseLoc(e) && currMouseOverChar != prevZoomChar)
            showZoomed();
        }
    }
    // / Empty function to comply with interface requirement
    public void mouseClicked(MouseEvent e) {
    }
    public void mouseEntered(MouseEvent e) {
    }
  }
  private final class CannotDrawException extends RuntimeException {
    // / Error ID
    public final int id;
    public CannotDrawException(int i) {
      id = i;
    }
  }
  enum FMValues {
    FMDEFAULT("DEFAULT", VALUE_FRACTIONALMETRICS_DEFAULT), FMOFF("OFF", VALUE_FRACTIONALMETRICS_OFF), FMON(
        "ON", VALUE_FRACTIONALMETRICS_ON);
    private String name;
    private Object hint;
    private static FMValues[] valArray;
    FMValues(String s, Object o) {
      name = s;
      hint = o;
    }
    public String toString() {
      return name;
    }
    public Object getHint() {
      return hint;
    }
    public static Object getValue(int ordinal) {
      if (valArray == null) {
        valArray = (FMValues[]) EnumSet.allOf(FMValues.class).toArray(new FMValues[0]);
      }
      for (int i = 0; i < valArray.length; i++) {
        if (valArray[i].ordinal() == ordinal) {
          return valArray[i];
        }
      }
      return valArray[0];
    }
    private static FMValues[] getArray() {
      if (valArray == null) {
        valArray = (FMValues[]) EnumSet.allOf(FMValues.class).toArray(new FMValues[0]);
      }
      return valArray;
    }
    public static int getHintVal(Object hint) {
      getArray();
      for (int i = 0; i < valArray.length; i++) {
        if (valArray[i].getHint() == hint) {
          return i;
        }
      }
      return 0;
    }
  }
  enum AAValues {
    AADEFAULT("DEFAULT", VALUE_TEXT_ANTIALIAS_DEFAULT), AAOFF("OFF", VALUE_TEXT_ANTIALIAS_OFF), AAON(
        "ON", VALUE_TEXT_ANTIALIAS_ON), AAGASP("GASP", VALUE_TEXT_ANTIALIAS_GASP), AALCDHRGB(
        "LCD_HRGB", VALUE_TEXT_ANTIALIAS_LCD_HRGB), AALCDHBGR("LCD_HBGR",
        VALUE_TEXT_ANTIALIAS_LCD_HBGR), AALCDVRGB("LCD_VRGB", VALUE_TEXT_ANTIALIAS_LCD_VRGB), AALCDVBGR(
        "LCD_VBGR", VALUE_TEXT_ANTIALIAS_LCD_VBGR);
    private String name;
    private Object hint;
    private static AAValues[] valArray;
    AAValues(String s, Object o) {
      name = s;
      hint = o;
    }
    public String toString() {
      return name;
    }
    public Object getHint() {
      return hint;
    }
    public static boolean isLCDMode(Object o) {
      return (o instanceof AAValues && ((AAValues) o).ordinal() >= AALCDHRGB.ordinal());
    }
    public static Object getValue(int ordinal) {
      if (valArray == null) {
        valArray = (AAValues[]) EnumSet.allOf(AAValues.class).toArray(new AAValues[0]);
      }
      for (int i = 0; i < valArray.length; i++) {
        if (valArray[i].ordinal() == ordinal) {
          return valArray[i];
        }
      }
      return valArray[0];
    }
    private static AAValues[] getArray() {
      if (valArray == null) {
        Object[] oa = EnumSet.allOf(AAValues.class).toArray(new AAValues[0]);
        valArray = (AAValues[]) (EnumSet.allOf(AAValues.class).toArray(new AAValues[0]));
      }
      return valArray;
    }
    public static int getHintVal(Object hint) {
      getArray();
      for (int i = 0; i < valArray.length; i++) {
        if (valArray[i].getHint() == hint) {
          return i;
        }
      }
      return 0;
    }
  }
  private static Integer defaultContrast;
  static Integer getDefaultLCDContrast() {
    if (defaultContrast == null) {
      GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment()
          .getDefaultScreenDevice().getDefaultConfiguration();
      Graphics2D g2d = (Graphics2D) (gc.createCompatibleImage(1, 1).getGraphics());
      defaultContrast = (Integer) g2d.getRenderingHint(RenderingHints.KEY_TEXT_LCD_CONTRAST);
    }
    return defaultContrast;
  }
}
/*
 * @(#)RangeMenu.java 1.18 05/11/17
 * 
 * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * -Redistribution of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * 
 * -Redistribution in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * 
 * Neither the name of Sun Microsystems, Inc. or the names of contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.
 * 
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
 * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS
 * LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A
 * RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 * IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT
 * OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
 * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS
 * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 * 
 * You acknowledge that this software is not designed, licensed or intended for
 * use in the design, construction, operation or maintenance of any nuclear
 * facility.
 */
/*
 * @(#)RangeMenu.java 1.18 05/11/17
 */
/**
 * RangeMenu.java
 * 
 * @version
 * @(#)RangeMenu.java 1.1 00/08/22
 * @author Shinsuke Fukuda
 * @author Ankit Patel [Conversion to Swing - 01/07/30]
 */
// / Custom made choice menu that holds data for unicode range
final class RangeMenu extends JComboBox implements ActionListener {
  // / Painfully extracted from java.lang.Character.UnicodeBlock. Arrrgh!
  // / Unicode 3.0 data.
  private final int[][] UNICODE_RANGES = { { 0x000000, 0x00007f }, // /
                                                                    // BASIC_LATIN
      { 0x000080, 0x0000ff }, // / LATIN_1_SUPPLEMENT
      { 0x000100, 0x00017f }, // / LATIN_EXTENDED_A
      { 0x000180, 0x00024f }, // / LATIN_EXTENDED_B
      { 0x000250, 0x0002af }, // / IPA_EXTENSIONS
      { 0x0002b0, 0x0002ff }, // / SPACING_MODIFIER_LETTERS
      { 0x000300, 0x00036f }, // / COMBINING_DIACRITICAL_MARKS
      { 0x000370, 0x0003ff }, // / GREEK
      { 0x000400, 0x0004ff }, // / CYRILLIC
      { 0x000500, 0x00052f }, // / CYRILLIC_SUPPLEMENTARY
      { 0x000530, 0x00058f }, // / ARMENIAN
      { 0x000590, 0x0005ff }, // / HEBREW
      { 0x000600, 0x0006ff }, // / ARABIC
      { 0x000700, 0x00074f }, // / SYRIAC
      { 0x000780, 0x0007bf }, // / THAANA
      { 0x000900, 0x00097f }, // / DEVANAGARI
      { 0x000980, 0x0009ff }, // / BENGALI
      { 0x000a00, 0x000a7f }, // / GURMUKHI
      { 0x000a80, 0x000aff }, // / GUJARATI
      { 0x000b00, 0x000b7f }, // / ORIYA
      { 0x000b80, 0x000bff }, // / TAMIL
      { 0x000c00, 0x000c7f }, // / TELUGU
      { 0x000c80, 0x000cff }, // / KANNADA
      { 0x000d00, 0x000d7f }, // / MALAYALAM
      { 0x000d80, 0x000dff }, // / SINHALA
      { 0x000e00, 0x000e7f }, // / THAI
      { 0x000e80, 0x000eff }, // / LAO
      { 0x000f00, 0x000fff }, // / TIBETAN
      { 0x001000, 0x00109f }, // / MYANMAR
      { 0x0010a0, 0x0010ff }, // / GEORGIAN
      { 0x001100, 0x0011ff }, // / HANGUL_JAMO
      { 0x001200, 0x00137f }, // / ETHIOPIC
      { 0x0013a0, 0x0013ff }, // / CHEROKEE
      { 0x001400, 0x00167f }, // / UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS
      { 0x001680, 0x00169f }, // / OGHAM
      { 0x0016a0, 0x0016ff }, // / RUNIC
      { 0x001700, 0x00171f }, // / TAGALOG
      { 0x001720, 0x00173f }, // / HANUNOO
      { 0x001740, 0x00175f }, // / BUHID
      { 0x001760, 0x00177f }, // / TAGBANWA
      { 0x001780, 0x0017ff }, // / KHMER
      { 0x001800, 0x0018af }, // / MONGOLIAN
      { 0x001900, 0x00194f }, // / LIMBU
      { 0x001950, 0x00197f }, // / TAI_LE
      { 0x0019e0, 0x0019ff }, // / KHMER_SYMBOLS
      { 0x001d00, 0x001d7f }, // / PHONETIC_EXTENSIONS
      { 0x001e00, 0x001eff }, // / LATIN_EXTENDED_ADDITIONAL
      { 0x001f00, 0x001fff }, // / GREEK_EXTENDED
      { 0x002000, 0x00206f }, // / GENERAL_PUNCTUATION
      { 0x002070, 0x00209f }, // / SUPERSCRIPTS_AND_SUBSCRIPTS
      { 0x0020a0, 0x0020cf }, // / CURRENCY_SYMBOLS
      { 0x0020d0, 0x0020ff }, // / COMBINING_MARKS_FOR_SYMBOLS
      { 0x002100, 0x00214f }, // / LETTERLIKE_SYMBOLS
      { 0x002150, 0x00218f }, // / NUMBER_FORMS
      { 0x002190, 0x0021ff }, // / ARROWS
      { 0x002200, 0x0022ff }, // / MATHEMATICAL_OPERATORS
      { 0x002300, 0x0023ff }, // / MISCELLANEOUS_TECHNICAL
      { 0x002400, 0x00243f }, // / CONTROL_PICTURES
      { 0x002440, 0x00245f }, // / OPTICAL_CHARACTER_RECOGNITION
      { 0x002460, 0x0024ff }, // / ENCLOSED_ALPHANUMERICS
      { 0x002500, 0x00257f }, // / BOX_DRAWING
      { 0x002580, 0x00259f }, // / BLOCK_ELEMENTS
      { 0x0025a0, 0x0025ff }, // / GEOMETRIC_SHAPES
      { 0x002600, 0x0026ff }, // / MISCELLANEOUS_SYMBOLS
      { 0x002700, 0x0027bf }, // / DINGBATS
      { 0x0027c0, 0x0027ef }, // / MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A
      { 0x0027f0, 0x0027ff }, // / SUPPLEMENTAL_ARROWS_A
      { 0x002800, 0x0028ff }, // / BRAILLE_PATTERNS
      { 0x002900, 0x00297f }, // / SUPPLEMENTAL_ARROWS_B
      { 0x002980, 0x0029ff }, // / MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B
      { 0x002a00, 0x002aff }, // / SUPPLEMENTAL_MATHEMATICAL_OPERATORS
      { 0x002b00, 0x002bff }, // / MISCELLANEOUS_SYMBOLS_AND_ARROWS
      { 0x002e80, 0x002eff }, // / CJK_RADICALS_SUPPLEMENT
      { 0x002f00, 0x002fdf }, // / KANGXI_RADICALS
      { 0x002ff0, 0x002fff }, // / IDEOGRAPHIC_DESCRIPTION_CHARACTERS
      { 0x003000, 0x00303f }, // / CJK_SYMBOLS_AND_PUNCTUATION
      { 0x003040, 0x00309f }, // / HIRAGANA
      { 0x0030a0, 0x0030ff }, // / KATAKANA
      { 0x003100, 0x00312f }, // / BOPOMOFO
      { 0x003130, 0x00318f }, // / HANGUL_COMPATIBILITY_JAMO
      { 0x003190, 0x00319f }, // / KANBUN
      { 0x0031a0, 0x0031bf }, // / BOPOMOFO_EXTENDED
      { 0x0031f0, 0x0031ff }, // / KATAKANA_PHONETIC_EXTENSIONS
      { 0x003200, 0x0032ff }, // / ENCLOSED_CJK_LETTERS_AND_MONTHS
      { 0x003300, 0x0033ff }, // / CJK_COMPATIBILITY
      { 0x003400, 0x004dbf }, // / CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
      { 0x004dc0, 0x004dff }, // / YIJING_HEXAGRAM_SYMBOLS
      { 0x004e00, 0x009fff }, // / CJK_UNIFIED_IDEOGRAPHS
      { 0x00a000, 0x00a48f }, // / YI_SYLLABLES
      { 0x00a490, 0x00a4cf }, // / YI_RADICALS
      { 0x00ac00, 0x00d7af }, // / HANGUL_SYLLABLES
      { 0x00d800, 0x00dfff }, // / SURROGATES_AREA
      { 0x00e000, 0x00f8ff }, // / PRIVATE_USE_AREA
      { 0x00f900, 0x00faff }, // / CJK_COMPATIBILITY_IDEOGRAPHS
      { 0x00fb00, 0x00fb4f }, // / ALPHABETIC_PRESENTATION_FORMS
      { 0x00fb50, 0x00fdff }, // / ARABIC_PRESENTATION_FORMS_A
      { 0x00fe00, 0x00fe0f }, // / VARIATION_SELECTORS
      { 0x00fe20, 0x00fe2f }, // / COMBINING_HALF_MARKS
      { 0x00fe30, 0x00fe4f }, // / CJK_COMPATIBILITY_FORMS
      { 0x00fe50, 0x00fe6f }, // / SMALL_FORM_VARIANTS
      { 0x00fe70, 0x00feff }, // / ARABIC_PRESENTATION_FORMS_B
      { 0x00ff00, 0x00ffef }, // / HALFWIDTH_AND_FULLWIDTH_FORMS
      { 0x00fff0, 0x00ffff }, // / SPECIALS
      { 0x010000, 0x01007f }, // / LINEAR_B_SYLLABARY
      { 0x010080, 0x0100ff }, // / LINEAR_B_IDEOGRAMS
      { 0x010100, 0x01013f }, // / AEGEAN_NUMBERS
      { 0x010300, 0x01032f }, // / OLD_ITALIC
      { 0x010330, 0x01034f }, // / GOTHIC
      { 0x010380, 0x01039f }, // / UGARITIC
      { 0x010400, 0x01044f }, // / DESERET
      { 0x010450, 0x01047f }, // / SHAVIAN
      { 0x010480, 0x0104af }, // / OSMANYA
      { 0x010800, 0x01083f }, // / CYPRIOT_SYLLABARY
      { 0x01d000, 0x01d0ff }, // / BYZANTINE_MUSICAL_SYMBOLS
      { 0x01d100, 0x01d1ff }, // / MUSICAL_SYMBOLS
      { 0x01d300, 0x01d35f }, // / TAI_XUAN_JING_SYMBOLS
      { 0x01d400, 0x01d7ff }, // / MATHEMATICAL_ALPHANUMERIC_SYMBOLS
      { 0x020000, 0x02a6df }, // / CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
      { 0x02f800, 0x02fa1f }, // / CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT
      { 0x0e0000, 0x0e007f }, // / TAGS
      { 0x0e0100, 0x0e01ef }, // / VARIATION_SELECTORS_SUPPLEMENT
      { 0x0f0000, 0x0fffff }, // / SUPPLEMENTARY_PRIVATE_USE_AREA_A
      { 0x100000, 0x10ffff }, // / SUPPLEMENTARY_PRIVATE_USE_AREA_B
      { 0x000000, 0x00007f }, // / OTHER [USER DEFINED RANGE]
  };
  private final String[] UNICODE_RANGE_NAMES = { "Basic Latin", "Latin-1 Supplement",
      "Latin Extended-A", "Latin Extended-B", "IPA Extensions", "Spacing Modifier Letters",
      "Combining Diacritical Marks", "Greek", "Cyrillic", "Cyrillic Supplement", "Armenian",
      "Hebrew", "Arabic", "Syriac", "Thaana", "Devanagari", "Bengali", "Gurmukhi", "Gujarati",
      "Oriya", "Tamil", "Telugu", "Kannada", "Malayalam", "Sinhala", "Thai", "Lao", "Tibetan",
      "Myanmar", "Georgian", "Hangul Jamo", "Ethiopic", "Cherokee",
      "Unified Canadian Aboriginal Syllabics", "Ogham", "Runic", "Tagalog", "Hanunoo", "Buhid",
      "Tagbanwa", "Khmer", "Mongolian", "Limbu", "Tai Le", "Khmer Symbols", "Phonetic Extensions",
      "Latin Extended Additional", "Greek Extended", "General Punctuation",
      "Superscripts and Subscripts", "Currency Symbols", "Combining Marks for Symbols",
      "Letterlike Symbols", "Number Forms", "Arrows", "Mathematical Operators",
      "Miscellaneous Technical", "Control Pictures", "Optical Character Recognition",
      "Enclosed Alphanumerics", "Box Drawing", "Block Elements", "Geometric Shapes",
      "Miscellaneous Symbols", "Dingbats", "Miscellaneous Mathematical Symbols-A",
      "Supplemental Arrows-A", "Braille Patterns", "Supplemental Arrows-B",
      "Miscellaneous Mathematical Symbols-B", "Supplemental Mathematical Operators",
      "Miscellaneous Symbols and Arrows", "CJK Radicals Supplement", "Kangxi Radicals",
      "Ideographic Description Characters", "CJK Symbols and Punctuation", "Hiragana", "Katakana",
      "Bopomofo", "Hangul Compatibility Jamo", "Kanbun", "Bopomofo Extended",
      "Katakana Phonetic Extensions", "Enclosed CJK Letters and Months", "CJK Compatibility",
      "CJK Unified Ideographs Extension A", "Yijing Hexagram Symbols", "CJK Unified Ideographs",
      "Yi Syllables", "Yi Radicals", "Hangul Syllables", "Surrogates Area", // High
                                                                            // Surrogates,
                                                                            // High
                                                                            // Private
                                                                            // Use
                                                                            // Surrogates,
                                                                            // Low
                                                                            // Surrogates
      "Private Use Area", "CJK Compatibility Ideographs", "Alphabetic Presentation Forms",
      "Arabic Presentation Forms-A", "Variation Selectors", "Combining Half Marks",
      "CJK Compatibility Forms", "Small Form Variants", "Arabic Presentation Forms-B",
      "Halfwidth and Fullwidth Forms", "Specials", "Linear B Syllabary", "Linear B Ideograms",
      "Aegean Numbers", "Old Italic", "Gothic", "Ugaritic", "Deseret", "Shavian", "Osmanya",
      "Cypriot Syllabary", "Byzantine Musical Symbols", "Musical Symbols", "Tai Xuan Jing Symbols",
      "Mathematical Alphanumeric Symbols", "CJK Unified Ideographs Extension B",
      "CJK Compatibility Ideographs Supplement", "Tags", "Variation Selectors Supplement",
      "Supplementary Private Use Area-A", "Supplementary Private Use Area-B", "Custom...", };
  private boolean useCustomRange = false;
  private int[] customRange = { 0x0000, 0x007f };
  // / Custom range dialog variables
  private final JDialog customRangeDialog;
  private final JTextField customRangeStart = new JTextField("0000", 4);
  private final JTextField customRangeEnd = new JTextField("007F", 4);
  private final int CUSTOM_RANGE_INDEX = UNICODE_RANGE_NAMES.length - 1;
  // / Parent Font2DTest Object holder
  private final Font2DTest parent;
  public static final int SURROGATES_AREA_INDEX = 91;
  public RangeMenu(Font2DTest demo, JFrame f) {
    super();
    parent = demo;
    for (int i = 0; i < UNICODE_RANGE_NAMES.length; i++)
      addItem(UNICODE_RANGE_NAMES[i]);
    setSelectedIndex(0);
    addActionListener(this);
    // / Set up custom range dialog...
    customRangeDialog = new JDialog(f, "Custom Unicode Range", true);
    customRangeDialog.setResizable(false);
    JPanel dialogTop = new JPanel();
    JPanel dialogBottom = new JPanel();
    JButton okButton = new JButton("OK");
    JLabel from = new JLabel("From:");
    JLabel to = new JLabel("To:");
    Font labelFont = new Font("dialog", Font.BOLD, 12);
    from.setFont(labelFont);
    to.setFont(labelFont);
    okButton.setFont(labelFont);
    dialogTop.add(from);
    dialogTop.add(customRangeStart);
    dialogTop.add(to);
    dialogTop.add(customRangeEnd);
    dialogBottom.add(okButton);
    okButton.addActionListener(this);
    customRangeDialog.getContentPane().setLayout(new BorderLayout());
    customRangeDialog.getContentPane().add("North", dialogTop);
    customRangeDialog.getContentPane().add("South", dialogBottom);
    customRangeDialog.pack();
  }
  // / Return the range that is currently selected
  public int[] getSelectedRange() {
    if (useCustomRange) {
      int startIndex, endIndex;
      String startText, endText;
      String empty = "";
      try {
        startText = customRangeStart.getText().trim();
        endText = customRangeEnd.getText().trim();
        if (startText.equals(empty) && !endText.equals(empty)) {
          endIndex = Integer.parseInt(endText, 16);
          startIndex = endIndex - 7 * 25;
        } else if (!startText.equals(empty) && endText.equals(empty)) {
          startIndex = Integer.parseInt(startText, 16);
          endIndex = startIndex + 7 * 25;
        } else {
          startIndex = Integer.parseInt(customRangeStart.getText(), 16);
          endIndex = Integer.parseInt(customRangeEnd.getText(), 16);
        }
      } catch (Exception e) {
        // / Error in parsing the hex number ---
        // / Reset the range to what it was before and return that
        customRangeStart.setText(Integer.toString(customRange[0], 16));
        customRangeEnd.setText(Integer.toString(customRange[1], 16));
        return customRange;
      }
      if (startIndex < 0)
        startIndex = 0;
      if (endIndex > 0xffff)
        endIndex = 0xffff;
      if (startIndex > endIndex)
        startIndex = endIndex;
      customRange[0] = startIndex;
      customRange[1] = endIndex;
      return customRange;
    } else
      return UNICODE_RANGES[getSelectedIndex()];
  }
  // / Function used by loadOptions in Font2DTest main panel
  // / to reset setting and range selection
  public void setSelectedRange(String name, int start, int end) {
    setSelectedItem(name);
    customRange[0] = start;
    customRange[1] = end;
    parent.fireRangeChanged();
  }
  // / ActionListener interface function
  // / ABP
  // / moved JComboBox event code into this fcn from
  // / itemStateChanged() method. Part of change to Swing.
  public void actionPerformed(ActionEvent e) {
    Object source = e.getSource();
    if (source instanceof JComboBox) {
      String rangeName = (String) ((JComboBox) source).getSelectedItem();
      if (rangeName.equals("Custom...")) {
        useCustomRange = true;
        customRangeDialog.setLocationRelativeTo(parent);
        customRangeDialog.show();
      } else {
        useCustomRange = false;
      }
      parent.fireRangeChanged();
    } else if (source instanceof JButton) {
      // / Since it is only "OK" button that sends any action here...
      customRangeDialog.hide();
    }
  }
}