0N/A/*
2362N/A * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
0N/A *
0N/A * Redistribution and use in source and binary forms, with or without
0N/A * modification, are permitted provided that the following conditions
0N/A * are met:
0N/A *
0N/A * - Redistributions of source code must retain the above copyright
0N/A * notice, this list of conditions and the following disclaimer.
0N/A *
0N/A * - Redistributions in binary form must reproduce the above copyright
0N/A * notice, this list of conditions and the following disclaimer in the
0N/A * documentation and/or other materials provided with the distribution.
0N/A *
2362N/A * - Neither the name of Oracle nor the names of its
0N/A * contributors may be used to endorse or promote products derived
0N/A * from this software without specific prior written permission.
0N/A *
0N/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
0N/A * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
0N/A * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
0N/A * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
0N/A * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0N/A * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0N/A * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
0N/A * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
0N/A * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
0N/A * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0N/A * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0N/A */
0N/A
4378N/A/*
4378N/A * This source code is provided to illustrate the usage of a given feature
4378N/A * or technique and has been deliberately simplified. Additional steps
4378N/A * required for a production-quality application, such as security checks,
4378N/A * input validation and proper error handling, might not be present in
4378N/A * this sample code.
4378N/A */
4378N/A
4378N/A
0N/A
0N/Aimport java.awt.Color;
0N/Aimport java.awt.Component;
0N/Aimport java.awt.BorderLayout;
0N/Aimport java.awt.CheckboxGroup;
0N/Aimport java.awt.Container;
0N/Aimport java.awt.Dimension;
0N/Aimport java.awt.Font;
0N/Aimport java.awt.Graphics;
0N/Aimport java.awt.Graphics2D;
0N/Aimport java.awt.GraphicsEnvironment;
0N/Aimport java.awt.GridBagConstraints;
0N/Aimport java.awt.GridBagLayout;
0N/Aimport java.awt.GridLayout;
0N/Aimport java.awt.Insets;
0N/Aimport java.awt.RenderingHints;
0N/Aimport java.awt.Toolkit;
0N/Aimport java.awt.event.ActionEvent;
0N/Aimport java.awt.event.ActionListener;
0N/Aimport java.awt.event.ItemEvent;
0N/Aimport java.awt.event.ItemListener;
0N/Aimport java.awt.event.WindowAdapter;
0N/Aimport java.awt.event.WindowEvent;
0N/Aimport java.awt.image.BufferedImage;
0N/Aimport java.io.BufferedInputStream;
0N/Aimport java.io.BufferedOutputStream;
0N/Aimport java.io.File;
0N/Aimport java.io.FileInputStream;
0N/Aimport java.io.FileOutputStream;
0N/Aimport java.util.EnumSet;
0N/Aimport java.util.StringTokenizer;
0N/Aimport java.util.BitSet;
0N/Aimport javax.swing.*;
0N/Aimport javax.swing.event.*;
0N/A
0N/A/**
0N/A * Font2DTest.java
0N/A *
0N/A * @author Shinsuke Fukuda
0N/A * @author Ankit Patel [Conversion to Swing - 01/07/30]
0N/A */
0N/A
0N/A/// Main Font2DTest Class
0N/A
0N/Apublic final class Font2DTest extends JPanel
0N/A implements ActionListener, ItemListener, ChangeListener {
0N/A
0N/A /// JFrame that will contain Font2DTest
0N/A private final JFrame parent;
0N/A /// FontPanel class that will contain all graphical output
0N/A private final FontPanel fp;
0N/A /// RangeMenu class that contains info about the unicode ranges
0N/A private final RangeMenu rm;
0N/A
0N/A /// Other menus to set parameters for text drawing
0N/A private final ChoiceV2 fontMenu;
0N/A private final JTextField sizeField;
0N/A private final ChoiceV2 styleMenu;
0N/A private final ChoiceV2 textMenu;
0N/A private int currentTextChoice = 0;
0N/A private final ChoiceV2 transformMenu;
0N/A private final ChoiceV2 transformMenuG2;
0N/A private final ChoiceV2 methodsMenu;
0N/A private final JComboBox antiAliasMenu;
0N/A private final JComboBox fracMetricsMenu;
0N/A
0N/A private final JSlider contrastSlider;
0N/A
0N/A /// CheckboxMenuItems
0N/A private CheckboxMenuItemV2 displayGridCBMI;
0N/A private CheckboxMenuItemV2 force16ColsCBMI;
0N/A private CheckboxMenuItemV2 showFontInfoCBMI;
0N/A
0N/A /// JDialog boxes
0N/A private JDialog userTextDialog;
0N/A private JTextArea userTextArea;
0N/A private JDialog printDialog;
0N/A private JDialog fontInfoDialog;
0N/A private LabelV2 fontInfos[] = new LabelV2[2];
0N/A private JFileChooser filePromptDialog = null;
0N/A
0N/A private ButtonGroup printCBGroup;
0N/A private JRadioButton printModeCBs[] = new JRadioButton[3];
0N/A
0N/A /// Status bar
0N/A private final LabelV2 statusBar;
0N/A
0N/A private int fontStyles [] = {Font.PLAIN, Font.BOLD, Font.ITALIC, Font.BOLD | Font.ITALIC};
0N/A
0N/A /// Text filename
0N/A private String tFileName;
0N/A
0N/A // Enabled or disabled status of canDisplay check
0N/A private static boolean canDisplayCheck = true;
0N/A
0N/A /// Initialize GUI variables and its layouts
0N/A public Font2DTest( JFrame f, boolean isApplet ) {
0N/A parent = f;
0N/A
0N/A rm = new RangeMenu( this, parent );
0N/A fp = new FontPanel( this, parent );
0N/A statusBar = new LabelV2("");
0N/A
0N/A fontMenu = new ChoiceV2( this, canDisplayCheck );
0N/A sizeField = new JTextField( "12", 3 );
0N/A sizeField.addActionListener( this );
0N/A styleMenu = new ChoiceV2( this );
0N/A textMenu = new ChoiceV2( ); // listener added later
0N/A transformMenu = new ChoiceV2( this );
0N/A transformMenuG2 = new ChoiceV2( this );
0N/A methodsMenu = new ChoiceV2( this );
0N/A
0N/A antiAliasMenu =
0N/A new JComboBox(EnumSet.allOf(FontPanel.AAValues.class).toArray());
0N/A antiAliasMenu.addActionListener(this);
0N/A fracMetricsMenu =
0N/A new JComboBox(EnumSet.allOf(FontPanel.FMValues.class).toArray());
0N/A fracMetricsMenu.addActionListener(this);
0N/A
0N/A contrastSlider = new JSlider(JSlider.HORIZONTAL, 100, 250,
0N/A FontPanel.getDefaultLCDContrast().intValue());
0N/A contrastSlider.setEnabled(false);
0N/A contrastSlider.setMajorTickSpacing(20);
0N/A contrastSlider.setMinorTickSpacing(10);
0N/A contrastSlider.setPaintTicks(true);
0N/A contrastSlider.setPaintLabels(true);
0N/A contrastSlider.addChangeListener(this);
0N/A setupPanel();
0N/A setupMenu( isApplet );
0N/A setupDialog( isApplet );
0N/A
0N/A if(canDisplayCheck) {
0N/A fireRangeChanged();
0N/A }
0N/A }
0N/A
0N/A /// Set up the main interface panel
0N/A private void setupPanel() {
0N/A GridBagLayout gbl = new GridBagLayout();
0N/A GridBagConstraints gbc = new GridBagConstraints();
0N/A gbc.fill = GridBagConstraints.HORIZONTAL;
0N/A gbc.weightx = 1;
0N/A gbc.insets = new Insets( 2, 0, 2, 2 );
0N/A this.setLayout( gbl );
0N/A
0N/A addLabeledComponentToGBL( "Font: ", fontMenu, gbl, gbc, this );
0N/A addLabeledComponentToGBL( "Size: ", sizeField, gbl, gbc, this );
0N/A gbc.gridwidth = GridBagConstraints.REMAINDER;
0N/A addLabeledComponentToGBL( "Font Transform:",
0N/A transformMenu, gbl, gbc, this );
0N/A gbc.gridwidth = 1;
0N/A
0N/A addLabeledComponentToGBL( "Range: ", rm, gbl, gbc, this );
0N/A addLabeledComponentToGBL( "Style: ", styleMenu, gbl, gbc, this );
0N/A gbc.gridwidth = GridBagConstraints.REMAINDER;
0N/A addLabeledComponentToGBL( "Graphics Transform: ",
0N/A transformMenuG2, gbl, gbc, this );
0N/A gbc.gridwidth = 1;
0N/A
0N/A gbc.anchor = GridBagConstraints.WEST;
0N/A addLabeledComponentToGBL( "Method: ", methodsMenu, gbl, gbc, this );
0N/A addLabeledComponentToGBL("", null, gbl, gbc, this);
0N/A gbc.anchor = GridBagConstraints.EAST;
0N/A gbc.gridwidth = GridBagConstraints.REMAINDER;
0N/A addLabeledComponentToGBL( "Text to use:", textMenu, gbl, gbc, this );
0N/A
0N/A gbc.weightx=1;
0N/A gbc.gridwidth = 1;
0N/A gbc.fill = GridBagConstraints.HORIZONTAL;
0N/A gbc.anchor = GridBagConstraints.WEST;
0N/A addLabeledComponentToGBL("LCD contrast: ",
0N/A contrastSlider, gbl, gbc, this);
0N/A
0N/A gbc.gridwidth = 1;
0N/A gbc.fill = GridBagConstraints.NONE;
0N/A addLabeledComponentToGBL("Antialiasing: ",
0N/A antiAliasMenu, gbl, gbc, this);
0N/A
0N/A gbc.anchor = GridBagConstraints.EAST;
0N/A gbc.gridwidth = GridBagConstraints.REMAINDER;
0N/A addLabeledComponentToGBL("Fractional metrics: ",
0N/A fracMetricsMenu, gbl, gbc, this);
0N/A
0N/A gbc.weightx = 1;
0N/A gbc.weighty = 1;
0N/A gbc.anchor = GridBagConstraints.WEST;
0N/A gbc.insets = new Insets( 2, 0, 0, 2 );
0N/A gbc.fill = GridBagConstraints.BOTH;
0N/A gbl.setConstraints( fp, gbc );
0N/A this.add( fp );
0N/A
0N/A gbc.weighty = 0;
0N/A gbc.insets = new Insets( 0, 2, 0, 0 );
0N/A gbl.setConstraints( statusBar, gbc );
0N/A this.add( statusBar );
0N/A }
0N/A
0N/A /// Adds a component to a container with a label to its left in GridBagLayout
0N/A private void addLabeledComponentToGBL( String name,
0N/A JComponent c,
0N/A GridBagLayout gbl,
0N/A GridBagConstraints gbc,
0N/A Container target ) {
0N/A LabelV2 l = new LabelV2( name );
0N/A GridBagConstraints gbcLabel = (GridBagConstraints) gbc.clone();
0N/A gbcLabel.insets = new Insets( 2, 2, 2, 0 );
0N/A gbcLabel.gridwidth = 1;
0N/A gbcLabel.weightx = 0;
0N/A
0N/A if ( c == null )
0N/A c = new JLabel( "" );
0N/A
0N/A gbl.setConstraints( l, gbcLabel );
0N/A target.add( l );
0N/A gbl.setConstraints( c, gbc );
0N/A target.add( c );
0N/A }
0N/A
0N/A /// Sets up menu entries
0N/A private void setupMenu( boolean isApplet ) {
0N/A JMenu fileMenu = new JMenu( "File" );
0N/A JMenu optionMenu = new JMenu( "Option" );
0N/A
0N/A fileMenu.add( new MenuItemV2( "Save Selected Options...", this ));
0N/A fileMenu.add( new MenuItemV2( "Load Options...", this ));
0N/A fileMenu.addSeparator();
0N/A fileMenu.add( new MenuItemV2( "Save as PNG...", this ));
0N/A fileMenu.add( new MenuItemV2( "Load PNG File to Compare...", this ));
0N/A fileMenu.add( new MenuItemV2( "Page Setup...", this ));
0N/A fileMenu.add( new MenuItemV2( "Print...", this ));
0N/A fileMenu.addSeparator();
0N/A if ( !isApplet )
0N/A fileMenu.add( new MenuItemV2( "Exit", this ));
0N/A else
0N/A fileMenu.add( new MenuItemV2( "Close", this ));
0N/A
0N/A displayGridCBMI = new CheckboxMenuItemV2( "Display Grid", true, this );
0N/A force16ColsCBMI = new CheckboxMenuItemV2( "Force 16 Columns", false, this );
0N/A showFontInfoCBMI = new CheckboxMenuItemV2( "Display Font Info", false, this );
0N/A optionMenu.add( displayGridCBMI );
0N/A optionMenu.add( force16ColsCBMI );
0N/A optionMenu.add( showFontInfoCBMI );
0N/A
0N/A JMenuBar mb = parent.getJMenuBar();
0N/A if ( mb == null )
0N/A mb = new JMenuBar();
0N/A mb.add( fileMenu );
0N/A mb.add( optionMenu );
0N/A
0N/A parent.setJMenuBar( mb );
0N/A
0N/A String fontList[] =
0N/A GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
0N/A
0N/A for ( int i = 0; i < fontList.length; i++ )
0N/A fontMenu.addItem( fontList[i] );
0N/A fontMenu.setSelectedItem( "Dialog" );
0N/A
0N/A styleMenu.addItem( "Plain" );
0N/A styleMenu.addItem( "Bold" );
0N/A styleMenu.addItem( "Italic" );
0N/A styleMenu.addItem( "Bold Italic" );
0N/A
0N/A transformMenu.addItem( "None" );
0N/A transformMenu.addItem( "Scale" );
0N/A transformMenu.addItem( "Shear" );
0N/A transformMenu.addItem( "Rotate" );
0N/A
0N/A transformMenuG2.addItem( "None" );
0N/A transformMenuG2.addItem( "Scale" );
0N/A transformMenuG2.addItem( "Shear" );
0N/A transformMenuG2.addItem( "Rotate" );
0N/A
0N/A methodsMenu.addItem( "drawString" );
0N/A methodsMenu.addItem( "drawChars" );
0N/A methodsMenu.addItem( "drawBytes" );
0N/A methodsMenu.addItem( "drawGlyphVector" );
0N/A methodsMenu.addItem( "TextLayout.draw" );
0N/A methodsMenu.addItem( "GlyphVector.getOutline + draw" );
0N/A methodsMenu.addItem( "TextLayout.getOutline + draw" );
0N/A
0N/A textMenu.addItem( "Unicode Range" );
0N/A textMenu.addItem( "All Glyphs" );
0N/A textMenu.addItem( "User Text" );
0N/A textMenu.addItem( "Text File" );
0N/A textMenu.addActionListener ( this ); // listener added later so unneeded events not thrown
0N/A }
0N/A
0N/A /// Sets up the all dialogs used in Font2DTest...
0N/A private void setupDialog( boolean isApplet ) {
0N/A if (!isApplet)
0N/A filePromptDialog = new JFileChooser( );
0N/A else
0N/A filePromptDialog = null;
0N/A
0N/A /// Prepare user text dialog...
0N/A userTextDialog = new JDialog( parent, "User Text", false );
0N/A JPanel dialogTopPanel = new JPanel();
0N/A JPanel dialogBottomPanel = new JPanel();
0N/A LabelV2 message1 = new LabelV2( "Enter text below and then press update" );
0N/A LabelV2 message2 = new LabelV2( "(Unicode char can be denoted by \\uXXXX)" );
0N/A LabelV2 message3 = new LabelV2( "(Supplementary chars can be denoted by \\UXXXXXX)" );
0N/A userTextArea = new JTextArea( "Font2DTest!" );
0N/A ButtonV2 bUpdate = new ButtonV2( "Update", this );
0N/A userTextArea.setFont( new Font( "dialog", Font.PLAIN, 12 ));
0N/A dialogTopPanel.setLayout( new GridLayout( 3, 1 ));
0N/A dialogTopPanel.add( message1 );
0N/A dialogTopPanel.add( message2 );
0N/A dialogTopPanel.add( message3 );
0N/A dialogBottomPanel.add( bUpdate );
0N/A //ABP
0N/A JScrollPane userTextAreaSP = new JScrollPane(userTextArea);
0N/A userTextAreaSP.setPreferredSize(new Dimension(300, 100));
0N/A
0N/A userTextDialog.getContentPane().setLayout( new BorderLayout() );
0N/A userTextDialog.getContentPane().add( "North", dialogTopPanel );
0N/A userTextDialog.getContentPane().add( "Center", userTextAreaSP );
0N/A userTextDialog.getContentPane().add( "South", dialogBottomPanel );
0N/A userTextDialog.pack();
0N/A userTextDialog.addWindowListener( new WindowAdapter() {
0N/A public void windowClosing( WindowEvent e ) {
0N/A userTextDialog.hide();
0N/A }
0N/A });
0N/A
0N/A /// Prepare printing dialog...
0N/A printCBGroup = new ButtonGroup();
0N/A printModeCBs[ fp.ONE_PAGE ] =
0N/A new JRadioButton( "Print one page from currently displayed character/line",
0N/A true );
0N/A printModeCBs[ fp.CUR_RANGE ] =
0N/A new JRadioButton( "Print all characters in currently selected range",
0N/A false );
0N/A printModeCBs[ fp.ALL_TEXT ] =
0N/A new JRadioButton( "Print all lines of text",
0N/A false );
0N/A LabelV2 l =
0N/A new LabelV2( "Note: Page range in native \"Print\" dialog will not affect the result" );
0N/A JPanel buttonPanel = new JPanel();
0N/A printModeCBs[ fp.ALL_TEXT ].setEnabled( false );
0N/A buttonPanel.add( new ButtonV2( "Print", this ));
0N/A buttonPanel.add( new ButtonV2( "Cancel", this ));
0N/A
0N/A printDialog = new JDialog( parent, "Print...", true );
0N/A printDialog.setResizable( false );
0N/A printDialog.addWindowListener( new WindowAdapter() {
0N/A public void windowClosing( WindowEvent e ) {
0N/A printDialog.hide();
0N/A }
0N/A });
0N/A printDialog.getContentPane().setLayout( new GridLayout( printModeCBs.length + 2, 1 ));
0N/A printDialog.getContentPane().add( l );
0N/A for ( int i = 0; i < printModeCBs.length; i++ ) {
0N/A printCBGroup.add( printModeCBs[i] );
0N/A printDialog.getContentPane().add( printModeCBs[i] );
0N/A }
0N/A printDialog.getContentPane().add( buttonPanel );
0N/A printDialog.pack();
0N/A
0N/A /// Prepare font information dialog...
0N/A fontInfoDialog = new JDialog( parent, "Font info", false );
0N/A fontInfoDialog.setResizable( false );
0N/A fontInfoDialog.addWindowListener( new WindowAdapter() {
0N/A public void windowClosing( WindowEvent e ) {
0N/A fontInfoDialog.hide();
0N/A showFontInfoCBMI.setState( false );
0N/A }
0N/A });
0N/A JPanel fontInfoPanel = new JPanel();
0N/A fontInfoPanel.setLayout( new GridLayout( fontInfos.length, 1 ));
0N/A for ( int i = 0; i < fontInfos.length; i++ ) {
0N/A fontInfos[i] = new LabelV2("");
0N/A fontInfoPanel.add( fontInfos[i] );
0N/A }
0N/A fontInfoDialog.getContentPane().add( fontInfoPanel );
0N/A
0N/A /// Move the location of the dialog...
0N/A userTextDialog.setLocation( 200, 300 );
0N/A fontInfoDialog.setLocation( 0, 400 );
0N/A }
0N/A
0N/A /// RangeMenu object signals using this function
0N/A /// when Unicode range has been changed and text needs to be redrawn
0N/A public void fireRangeChanged() {
0N/A int range[] = rm.getSelectedRange();
0N/A fp.setTextToDraw( fp.RANGE_TEXT, range, null, null );
0N/A if(canDisplayCheck) {
0N/A setupFontList(range[0], range[1]);
0N/A }
0N/A if ( showFontInfoCBMI.getState() )
0N/A fireUpdateFontInfo();
0N/A }
0N/A
0N/A /// Changes the message on the status bar
0N/A public void fireChangeStatus( String message, boolean error ) {
0N/A /// If this is not ran as an applet, use own status bar,
0N/A /// Otherwise, use the appletviewer/browser's status bar
0N/A statusBar.setText( message );
0N/A if ( error )
0N/A fp.showingError = true;
0N/A else
0N/A fp.showingError = false;
0N/A }
0N/A
0N/A /// Updates the information about the selected font
0N/A public void fireUpdateFontInfo() {
0N/A if ( showFontInfoCBMI.getState() ) {
0N/A String infos[] = fp.getFontInfo();
0N/A for ( int i = 0; i < fontInfos.length; i++ )
0N/A fontInfos[i].setText( infos[i] );
0N/A fontInfoDialog.pack();
0N/A }
0N/A }
0N/A
0N/A private void setupFontList(int rangeStart, int rangeEnd) {
0N/A
0N/A int listCount = fontMenu.getItemCount();
0N/A int size = 16;
0N/A
0N/A try {
0N/A size = Float.valueOf(sizeField.getText()).intValue();
0N/A }
0N/A catch ( Exception e ) {
0N/A System.out.println("Invalid font size in the size textField. Using default value of 16");
0N/A }
0N/A
0N/A int style = fontStyles[styleMenu.getSelectedIndex()];
0N/A Font f;
0N/A for (int i = 0; i < listCount; i++) {
0N/A String fontName = (String)fontMenu.getItemAt(i);
0N/A f = new Font(fontName, style, size);
0N/A if ((rm.getSelectedIndex() != RangeMenu.SURROGATES_AREA_INDEX) &&
0N/A canDisplayRange(f, rangeStart, rangeEnd)) {
0N/A fontMenu.setBit(i, true);
0N/A }
0N/A else {
0N/A fontMenu.setBit(i, false);
0N/A }
0N/A }
0N/A
0N/A fontMenu.repaint();
0N/A }
0N/A
0N/A protected boolean canDisplayRange(Font font, int rangeStart, int rangeEnd) {
0N/A for (int i = rangeStart; i < rangeEnd; i++) {
0N/A if (font.canDisplay(i)) {
0N/A return true;
0N/A }
0N/A }
0N/A return false;
0N/A }
0N/A
0N/A /// Displays a file load/save dialog and returns the specified file
0N/A private String promptFile( boolean isSave, String initFileName ) {
0N/A int retVal;
0N/A String str;
0N/A
0N/A /// ABP
0N/A if ( filePromptDialog == null)
0N/A return null;
0N/A
0N/A if ( isSave ) {
0N/A filePromptDialog.setDialogType( JFileChooser.SAVE_DIALOG );
0N/A filePromptDialog.setDialogTitle( "Save..." );
0N/A str = "Save";
0N/A
0N/A
0N/A }
0N/A else {
0N/A filePromptDialog.setDialogType( JFileChooser.OPEN_DIALOG );
0N/A filePromptDialog.setDialogTitle( "Load..." );
0N/A str = "Load";
0N/A }
0N/A
0N/A if (initFileName != null)
0N/A filePromptDialog.setSelectedFile( new File( initFileName ) );
0N/A retVal = filePromptDialog.showDialog( this, str );
0N/A
0N/A if ( retVal == JFileChooser.APPROVE_OPTION ) {
0N/A File file = filePromptDialog.getSelectedFile();
0N/A String fileName = file.getAbsolutePath();
0N/A if ( fileName != null ) {
0N/A return fileName;
0N/A }
0N/A }
0N/A
0N/A return null;
0N/A }
0N/A
0N/A /// Converts user text into arrays of String, delimited at newline character
0N/A /// Also replaces any valid escape sequence with appropriate unicode character
0N/A /// Support \\UXXXXXX notation for surrogates
0N/A private String[] parseUserText( String orig ) {
0N/A int length = orig.length();
0N/A StringTokenizer perLine = new StringTokenizer( orig, "\n" );
0N/A String textLines[] = new String[ perLine.countTokens() ];
0N/A int lineNumber = 0;
0N/A
0N/A while ( perLine.hasMoreElements() ) {
0N/A StringBuffer converted = new StringBuffer();
0N/A String oneLine = perLine.nextToken();
0N/A int lineLength = oneLine.length();
0N/A int prevEscapeEnd = 0;
0N/A int nextEscape = -1;
0N/A do {
0N/A int nextBMPEscape = oneLine.indexOf( "\\u", prevEscapeEnd );
0N/A int nextSupEscape = oneLine.indexOf( "\\U", prevEscapeEnd );
0N/A nextEscape = (nextBMPEscape < 0)
0N/A ? ((nextSupEscape < 0)
0N/A ? -1
0N/A : nextSupEscape)
0N/A : ((nextSupEscape < 0)
0N/A ? nextBMPEscape
0N/A : Math.min(nextBMPEscape, nextSupEscape));
0N/A
0N/A if ( nextEscape != -1 ) {
0N/A if ( prevEscapeEnd < nextEscape )
0N/A converted.append( oneLine.substring( prevEscapeEnd, nextEscape ));
0N/A
0N/A prevEscapeEnd = nextEscape + (nextEscape == nextBMPEscape ? 6 : 8);
0N/A try {
0N/A String hex = oneLine.substring( nextEscape + 2, prevEscapeEnd );
0N/A if (nextEscape == nextBMPEscape) {
0N/A converted.append( (char) Integer.parseInt( hex, 16 ));
0N/A } else {
0N/A converted.append( new String( Character.toChars( Integer.parseInt( hex, 16 ))));
0N/A }
0N/A }
0N/A catch ( Exception e ) {
0N/A int copyLimit = Math.min(lineLength, prevEscapeEnd);
0N/A converted.append( oneLine.substring( nextEscape, copyLimit ));
0N/A }
0N/A }
0N/A } while (nextEscape != -1);
0N/A if ( prevEscapeEnd < lineLength )
0N/A converted.append( oneLine.substring( prevEscapeEnd, lineLength ));
0N/A textLines[ lineNumber++ ] = converted.toString();
0N/A }
0N/A return textLines;
0N/A }
0N/A
0N/A /// Reads the text from specified file, detecting UTF-16 encoding
0N/A /// Then breaks the text into String array, delimited at every line break
0N/A private void readTextFile( String fileName ) {
0N/A try {
0N/A String fileText, textLines[];
0N/A BufferedInputStream bis =
0N/A new BufferedInputStream( new FileInputStream( fileName ));
0N/A int numBytes = bis.available();
0N/A if (numBytes == 0) {
0N/A throw new Exception("Text file " + fileName + " is empty");
0N/A }
0N/A byte byteData[] = new byte[ numBytes ];
0N/A bis.read( byteData, 0, numBytes );
0N/A bis.close();
0N/A
0N/A /// If byte mark is found, then use UTF-16 encoding to convert bytes...
0N/A if (numBytes >= 2 &&
0N/A (( byteData[0] == (byte) 0xFF && byteData[1] == (byte) 0xFE ) ||
0N/A ( byteData[0] == (byte) 0xFE && byteData[1] == (byte) 0xFF )))
0N/A fileText = new String( byteData, "UTF-16" );
0N/A /// Otherwise, use system default encoding
0N/A else
0N/A fileText = new String( byteData );
0N/A
0N/A int length = fileText.length();
0N/A StringTokenizer perLine = new StringTokenizer( fileText, "\n" );
0N/A /// Determine "Return Char" used in this file
0N/A /// This simply finds first occurrence of CR, CR+LF or LF...
0N/A for ( int i = 0; i < length; i++ ) {
0N/A char iTh = fileText.charAt( i );
0N/A if ( iTh == '\r' ) {
0N/A if ( i < length - 1 && fileText.charAt( i + 1 ) == '\n' )
0N/A perLine = new StringTokenizer( fileText, "\r\n" );
0N/A else
0N/A perLine = new StringTokenizer( fileText, "\r" );
0N/A break;
0N/A }
0N/A else if ( iTh == '\n' )
0N/A /// Use the one already created
0N/A break;
0N/A }
0N/A int lineNumber = 0, numLines = perLine.countTokens();
0N/A textLines = new String[ numLines ];
0N/A
0N/A while ( perLine.hasMoreElements() ) {
0N/A String oneLine = perLine.nextToken();
0N/A if ( oneLine == null )
0N/A /// To make LineBreakMeasurer to return a valid TextLayout
0N/A /// on an empty line, simply feed it a space char...
0N/A oneLine = " ";
0N/A textLines[ lineNumber++ ] = oneLine;
0N/A }
0N/A fp.setTextToDraw( fp.FILE_TEXT, null, null, textLines );
0N/A rm.setEnabled( false );
0N/A methodsMenu.setEnabled( false );
0N/A }
0N/A catch ( Exception ex ) {
0N/A fireChangeStatus( "ERROR: Failed to Read Text File; See Stack Trace", true );
0N/A ex.printStackTrace();
0N/A }
0N/A }
0N/A
0N/A /// Returns a String storing current configuration
0N/A private void writeCurrentOptions( String fileName ) {
0N/A try {
0N/A String curOptions = fp.getCurrentOptions();
0N/A BufferedOutputStream bos =
0N/A new BufferedOutputStream( new FileOutputStream( fileName ));
0N/A /// Prepend title and the option that is only obtainable here
0N/A int range[] = rm.getSelectedRange();
0N/A String completeOptions =
0N/A ( "Font2DTest Option File\n" +
0N/A displayGridCBMI.getState() + "\n" +
0N/A force16ColsCBMI.getState() + "\n" +
0N/A showFontInfoCBMI.getState() + "\n" +
0N/A rm.getSelectedItem() + "\n" +
0N/A range[0] + "\n" + range[1] + "\n" + curOptions + tFileName);
0N/A byte toBeWritten[] = completeOptions.getBytes( "UTF-16" );
0N/A bos.write( toBeWritten, 0, toBeWritten.length );
0N/A bos.close();
0N/A }
0N/A catch ( Exception ex ) {
0N/A fireChangeStatus( "ERROR: Failed to Save Options File; See Stack Trace", true );
0N/A ex.printStackTrace();
0N/A }
0N/A }
0N/A
0N/A /// Updates GUI visibility/status after some parameters have changed
0N/A private void updateGUI() {
0N/A int selectedText = textMenu.getSelectedIndex();
0N/A
0N/A /// Set the visibility of User Text dialog
0N/A if ( selectedText == fp.USER_TEXT )
0N/A userTextDialog.show();
0N/A else
0N/A userTextDialog.hide();
0N/A /// Change the visibility/status/availability of Print JDialog buttons
0N/A printModeCBs[ fp.ONE_PAGE ].setSelected( true );
0N/A if ( selectedText == fp.FILE_TEXT || selectedText == fp.USER_TEXT ) {
0N/A /// ABP
0N/A /// update methodsMenu to show that TextLayout.draw is being used
0N/A /// when we are in FILE_TEXT mode
0N/A if ( selectedText == fp.FILE_TEXT )
0N/A methodsMenu.setSelectedItem("TextLayout.draw");
0N/A methodsMenu.setEnabled( selectedText == fp.USER_TEXT );
0N/A printModeCBs[ fp.CUR_RANGE ].setEnabled( false );
0N/A printModeCBs[ fp.ALL_TEXT ].setEnabled( true );
0N/A }
0N/A else {
0N/A /// ABP
0N/A /// update methodsMenu to show that drawGlyph is being used
0N/A /// when we are in ALL_GLYPHS mode
0N/A if ( selectedText == fp.ALL_GLYPHS )
0N/A methodsMenu.setSelectedItem("drawGlyphVector");
0N/A methodsMenu.setEnabled( selectedText == fp.RANGE_TEXT );
0N/A printModeCBs[ fp.CUR_RANGE ].setEnabled( true );
0N/A printModeCBs[ fp.ALL_TEXT ].setEnabled( false );
0N/A }
0N/A /// Modify RangeMenu and fontInfo label availabilty
0N/A if ( selectedText == fp.RANGE_TEXT ) {
0N/A fontInfos[1].setVisible( true );
0N/A rm.setEnabled( true );
0N/A }
0N/A else {
0N/A fontInfos[1].setVisible( false );
0N/A rm.setEnabled( false );
0N/A }
0N/A }
0N/A
0N/A /// Loads saved options and applies them
0N/A private void loadOptions( String fileName ) {
0N/A try {
0N/A BufferedInputStream bis =
0N/A new BufferedInputStream( new FileInputStream( fileName ));
0N/A int numBytes = bis.available();
0N/A byte byteData[] = new byte[ numBytes ];
0N/A bis.read( byteData, 0, numBytes );
0N/A bis.close();
0N/A if ( numBytes < 2 ||
0N/A (byteData[0] != (byte) 0xFE || byteData[1] != (byte) 0xFF) )
0N/A throw new Exception( "Not a Font2DTest options file" );
0N/A
0N/A String options = new String( byteData, "UTF-16" );
0N/A StringTokenizer perLine = new StringTokenizer( options, "\n" );
0N/A String title = perLine.nextToken();
0N/A if ( !title.equals( "Font2DTest Option File" ))
0N/A throw new Exception( "Not a Font2DTest options file" );
0N/A
0N/A /// Parse all options
0N/A boolean displayGridOpt = Boolean.parseBoolean( perLine.nextToken() );
0N/A boolean force16ColsOpt = Boolean.parseBoolean( perLine.nextToken() );
0N/A boolean showFontInfoOpt = Boolean.parseBoolean( perLine.nextToken() );
0N/A String rangeNameOpt = perLine.nextToken();
0N/A int rangeStartOpt = Integer.parseInt( perLine.nextToken() );
0N/A int rangeEndOpt = Integer.parseInt( perLine.nextToken() );
0N/A String fontNameOpt = perLine.nextToken();
0N/A float fontSizeOpt = Float.parseFloat( perLine.nextToken() );
0N/A int fontStyleOpt = Integer.parseInt( perLine.nextToken() );
0N/A int fontTransformOpt = Integer.parseInt( perLine.nextToken() );
0N/A int g2TransformOpt = Integer.parseInt( perLine.nextToken() );
0N/A int textToUseOpt = Integer.parseInt( perLine.nextToken() );
0N/A int drawMethodOpt = Integer.parseInt( perLine.nextToken() );
0N/A int antialiasOpt = Integer.parseInt(perLine.nextToken());
0N/A int fractionalOpt = Integer.parseInt(perLine.nextToken());
0N/A int lcdContrast = Integer.parseInt(perLine.nextToken());
0N/A String userTextOpt[] = { "Font2DTest!" };
0N/A String dialogEntry = "Font2DTest!";
0N/A if (textToUseOpt == fp.USER_TEXT ) {
0N/A int numLines = perLine.countTokens(), lineNumber = 0;
0N/A if ( numLines != 0 ) {
0N/A userTextOpt = new String[ numLines ];
0N/A dialogEntry = "";
0N/A for ( ; perLine.hasMoreElements(); lineNumber++ ) {
0N/A userTextOpt[ lineNumber ] = perLine.nextToken();
0N/A dialogEntry += userTextOpt[ lineNumber ] + "\n";
0N/A }
0N/A }
0N/A }
0N/A
0N/A /// Reset GUIs
0N/A displayGridCBMI.setState( displayGridOpt );
0N/A force16ColsCBMI.setState( force16ColsOpt );
0N/A showFontInfoCBMI.setState( showFontInfoOpt );
0N/A rm.setSelectedRange( rangeNameOpt, rangeStartOpt, rangeEndOpt );
0N/A fontMenu.setSelectedItem( fontNameOpt );
0N/A sizeField.setText( String.valueOf( fontSizeOpt ));
0N/A styleMenu.setSelectedIndex( fontStyleOpt );
0N/A transformMenu.setSelectedIndex( fontTransformOpt );
0N/A transformMenuG2.setSelectedIndex( g2TransformOpt );
0N/A textMenu.setSelectedIndex( textToUseOpt );
0N/A methodsMenu.setSelectedIndex( drawMethodOpt );
0N/A antiAliasMenu.setSelectedIndex( antialiasOpt );
0N/A fracMetricsMenu.setSelectedIndex( fractionalOpt );
0N/A contrastSlider.setValue(lcdContrast);
0N/A
0N/A userTextArea.setText( dialogEntry );
0N/A updateGUI();
0N/A
0N/A if ( textToUseOpt == fp.FILE_TEXT ) {
0N/A tFileName = perLine.nextToken();
0N/A readTextFile(tFileName );
0N/A }
0N/A
0N/A /// Reset option variables and repaint
0N/A fp.loadOptions( displayGridOpt, force16ColsOpt,
0N/A rangeStartOpt, rangeEndOpt,
0N/A fontNameOpt, fontSizeOpt,
0N/A fontStyleOpt, fontTransformOpt, g2TransformOpt,
0N/A textToUseOpt, drawMethodOpt,
0N/A antialiasOpt, fractionalOpt,
0N/A lcdContrast, userTextOpt );
0N/A if ( showFontInfoOpt ) {
0N/A fireUpdateFontInfo();
0N/A fontInfoDialog.show();
0N/A }
0N/A else
0N/A fontInfoDialog.hide();
0N/A }
0N/A catch ( Exception ex ) {
0N/A fireChangeStatus( "ERROR: Failed to Load Options File; See Stack Trace", true );
0N/A ex.printStackTrace();
0N/A }
0N/A }
0N/A
0N/A /// Loads a previously saved image
0N/A private void loadComparisonPNG( String fileName ) {
0N/A try {
0N/A BufferedImage image =
0N/A javax.imageio.ImageIO.read(new File(fileName));
0N/A JFrame f = new JFrame( "Comparison PNG" );
0N/A ImagePanel ip = new ImagePanel( image );
0N/A f.setResizable( false );
0N/A f.getContentPane().add( ip );
0N/A f.addWindowListener( new WindowAdapter() {
0N/A public void windowClosing( WindowEvent e ) {
0N/A ( (JFrame) e.getSource() ).dispose();
0N/A }
0N/A });
0N/A f.pack();
0N/A f.show();
0N/A }
0N/A catch ( Exception ex ) {
0N/A fireChangeStatus( "ERROR: Failed to Load PNG File; See Stack Trace", true );
0N/A ex.printStackTrace();
0N/A }
0N/A }
0N/A
0N/A /// Interface functions...
0N/A
0N/A /// ActionListener interface function
0N/A /// Responds to JMenuItem, JTextField and JButton actions
0N/A public void actionPerformed( ActionEvent e ) {
0N/A Object source = e.getSource();
0N/A
0N/A if ( source instanceof JMenuItem ) {
0N/A JMenuItem mi = (JMenuItem) source;
0N/A String itemName = mi.getText();
0N/A
0N/A if ( itemName.equals( "Save Selected Options..." )) {
0N/A String fileName = promptFile( true, "options.txt" );
0N/A if ( fileName != null )
0N/A writeCurrentOptions( fileName );
0N/A }
0N/A else if ( itemName.equals( "Load Options..." )) {
0N/A String fileName = promptFile( false, "options.txt" );
0N/A if ( fileName != null )
0N/A loadOptions( fileName );
0N/A }
0N/A else if ( itemName.equals( "Save as PNG..." )) {
0N/A String fileName = promptFile( true, fontMenu.getSelectedItem() + ".png" );
0N/A if ( fileName != null )
0N/A fp.doSavePNG( fileName );
0N/A }
0N/A else if ( itemName.equals( "Load PNG File to Compare..." )) {
0N/A String fileName = promptFile( false, null );
0N/A if ( fileName != null )
0N/A loadComparisonPNG( fileName );
0N/A }
0N/A else if ( itemName.equals( "Page Setup..." ))
0N/A fp.doPageSetup();
0N/A else if ( itemName.equals( "Print..." ))
0N/A printDialog.show();
0N/A else if ( itemName.equals( "Close" ))
0N/A parent.dispose();
0N/A else if ( itemName.equals( "Exit" ))
0N/A System.exit(0);
0N/A }
0N/A
0N/A else if ( source instanceof JTextField ) {
0N/A JTextField tf = (JTextField) source;
0N/A float sz = 12f;
0N/A try {
0N/A sz = Float.parseFloat(sizeField.getText());
0N/A if (sz < 1f || sz > 120f) {
0N/A sz = 12f;
0N/A sizeField.setText("12");
0N/A }
0N/A } catch (Exception se) {
0N/A sizeField.setText("12");
0N/A }
0N/A if ( tf == sizeField )
0N/A fp.setFontParams( fontMenu.getSelectedItem(),
0N/A sz,
0N/A styleMenu.getSelectedIndex(),
0N/A transformMenu.getSelectedIndex() );
0N/A }
0N/A
0N/A else if ( source instanceof JButton ) {
0N/A String itemName = ( (JButton) source ).getText();
0N/A /// Print dialog buttons...
0N/A if ( itemName.equals( "Print" )) {
0N/A for ( int i = 0; i < printModeCBs.length; i++ )
0N/A if ( printModeCBs[i].isSelected() ) {
0N/A printDialog.hide();
0N/A fp.doPrint( i );
0N/A }
0N/A }
0N/A else if ( itemName.equals( "Cancel" ))
0N/A printDialog.hide();
0N/A /// Update button from Usert Text JDialog...
0N/A else if ( itemName.equals( "Update" ))
0N/A fp.setTextToDraw( fp.USER_TEXT, null,
0N/A parseUserText( userTextArea.getText() ), null );
0N/A }
0N/A else if ( source instanceof JComboBox ) {
0N/A JComboBox c = (JComboBox) source;
0N/A
0N/A /// RangeMenu handles actions by itself and then calls fireRangeChanged,
0N/A /// so it is not listed or handled here
0N/A if ( c == fontMenu || c == styleMenu || c == transformMenu ) {
0N/A float sz = 12f;
0N/A try {
0N/A sz = Float.parseFloat(sizeField.getText());
0N/A if (sz < 1f || sz > 120f) {
0N/A sz = 12f;
0N/A sizeField.setText("12");
0N/A }
0N/A } catch (Exception se) {
0N/A sizeField.setText("12");
0N/A }
0N/A fp.setFontParams(fontMenu.getSelectedItem(),
0N/A sz,
0N/A styleMenu.getSelectedIndex(),
0N/A transformMenu.getSelectedIndex());
0N/A } else if ( c == methodsMenu )
0N/A fp.setDrawMethod( methodsMenu.getSelectedIndex() );
0N/A else if ( c == textMenu ) {
0N/A
0N/A if(canDisplayCheck) {
0N/A fireRangeChanged();
0N/A }
0N/A
0N/A int selected = textMenu.getSelectedIndex();
0N/A
0N/A if ( selected == fp.RANGE_TEXT )
0N/A fp.setTextToDraw( fp.RANGE_TEXT, rm.getSelectedRange(),
0N/A null, null );
0N/A else if ( selected == fp.USER_TEXT )
0N/A fp.setTextToDraw( fp.USER_TEXT, null,
0N/A parseUserText( userTextArea.getText() ), null );
0N/A else if ( selected == fp.FILE_TEXT ) {
0N/A String fileName = promptFile( false, null );
0N/A if ( fileName != null ) {
0N/A tFileName = fileName;
0N/A readTextFile( fileName );
0N/A } else {
0N/A /// User cancelled selection; reset to previous choice
0N/A c.setSelectedIndex( currentTextChoice );
0N/A return;
0N/A }
0N/A }
0N/A else if ( selected == fp.ALL_GLYPHS )
0N/A fp.setTextToDraw( fp.ALL_GLYPHS, null, null, null );
0N/A
0N/A updateGUI();
0N/A currentTextChoice = selected;
0N/A }
0N/A else if ( c == transformMenuG2 ) {
0N/A fp.setTransformG2( transformMenuG2.getSelectedIndex() );
0N/A }
0N/A else if (c == antiAliasMenu || c == fracMetricsMenu) {
0N/A if (c == antiAliasMenu) {
0N/A boolean enabled = FontPanel.AAValues.
0N/A isLCDMode(antiAliasMenu.getSelectedItem());
0N/A contrastSlider.setEnabled(enabled);
0N/A }
0N/A fp.setRenderingHints(antiAliasMenu.getSelectedItem(),
0N/A fracMetricsMenu.getSelectedItem(),
0N/A contrastSlider.getValue());
0N/A }
0N/A }
0N/A }
0N/A
0N/A public void stateChanged(ChangeEvent e) {
0N/A Object source = e.getSource();
0N/A if (source instanceof JSlider) {
0N/A fp.setRenderingHints(antiAliasMenu.getSelectedItem(),
0N/A fracMetricsMenu.getSelectedItem(),
0N/A contrastSlider.getValue());
0N/A }
0N/A }
0N/A
0N/A /// ItemListener interface function
0N/A /// Responds to JCheckBoxMenuItem, JComboBox and JCheckBox actions
0N/A public void itemStateChanged( ItemEvent e ) {
0N/A Object source = e.getSource();
0N/A
0N/A if ( source instanceof JCheckBoxMenuItem ) {
0N/A JCheckBoxMenuItem cbmi = (JCheckBoxMenuItem) source;
0N/A if ( cbmi == displayGridCBMI )
0N/A fp.setGridDisplay( displayGridCBMI.getState() );
0N/A else if ( cbmi == force16ColsCBMI )
0N/A fp.setForce16Columns( force16ColsCBMI.getState() );
0N/A else if ( cbmi == showFontInfoCBMI ) {
0N/A if ( showFontInfoCBMI.getState() ) {
0N/A fireUpdateFontInfo();
0N/A fontInfoDialog.show();
0N/A }
0N/A else
0N/A fontInfoDialog.hide();
0N/A }
0N/A }
0N/A }
0N/A
0N/A private static void printUsage() {
0N/A String usage = "Usage: java -jar Font2DTest.jar [options]\n" +
0N/A "\nwhere options include:\n" +
0N/A " -dcdc | -disablecandisplaycheck disable canDisplay check for font\n" +
0N/A " -? | -help print this help message\n" +
0N/A "\nExample :\n" +
0N/A " To disable canDisplay check on font for ranges\n" +
0N/A " java -jar Font2DTest.jar -dcdc";
0N/A System.out.println(usage);
0N/A System.exit(0);
0N/A }
0N/A
0N/A /// Main function
0N/A public static void main(String argv[]) {
0N/A
0N/A if(argv.length > 0) {
0N/A if(argv[0].equalsIgnoreCase("-disablecandisplaycheck") ||
0N/A argv[0].equalsIgnoreCase("-dcdc")) {
0N/A canDisplayCheck = false;
0N/A }
0N/A else {
0N/A printUsage();
0N/A }
0N/A }
0N/A
0N/A UIManager.put("swing.boldMetal", Boolean.FALSE);
0N/A final JFrame f = new JFrame( "Font2DTest" );
0N/A final Font2DTest f2dt = new Font2DTest( f, false );
0N/A f.addWindowListener( new WindowAdapter() {
0N/A public void windowOpening( WindowEvent e ) { f2dt.repaint(); }
0N/A public void windowClosing( WindowEvent e ) { System.exit(0); }
0N/A });
0N/A
0N/A f.getContentPane().add( f2dt );
0N/A f.pack();
0N/A f.show();
0N/A }
0N/A
0N/A /// Inner class definitions...
0N/A
0N/A /// Class to display just an image file
0N/A /// Used to show the comparison PNG image
0N/A private final class ImagePanel extends JPanel {
0N/A private final BufferedImage bi;
0N/A
0N/A public ImagePanel( BufferedImage image ) {
0N/A bi = image;
0N/A }
0N/A
0N/A public Dimension getPreferredSize() {
0N/A return new Dimension( bi.getWidth(), bi.getHeight() );
0N/A }
0N/A
0N/A public void paintComponent( Graphics g ) {
0N/A g.drawImage( bi, 0, 0, this );
0N/A }
0N/A }
0N/A
0N/A /// Classes made to avoid repetitive calls... (being lazy)
0N/A private final class ButtonV2 extends JButton {
0N/A public ButtonV2( String name, ActionListener al ) {
0N/A super( name );
0N/A this.addActionListener( al );
0N/A }
0N/A }
0N/A
0N/A private final class ChoiceV2 extends JComboBox {
0N/A
0N/A private BitSet bitSet = null;
0N/A
0N/A public ChoiceV2() {;}
0N/A
0N/A public ChoiceV2( ActionListener al ) {
0N/A super();
0N/A this.addActionListener( al );
0N/A }
0N/A
0N/A public ChoiceV2( ActionListener al, boolean fontChoice) {
0N/A this(al);
0N/A if(fontChoice) {
0N/A //Register this component in ToolTipManager
0N/A setToolTipText("");
0N/A bitSet = new BitSet();
0N/A setRenderer(new ChoiceV2Renderer(this));
0N/A }
0N/A }
0N/A
0N/A public String getToolTipText() {
0N/A int index = this.getSelectedIndex();
0N/A String fontName = (String) this.getSelectedItem();
0N/A if(fontName != null &&
0N/A (textMenu.getSelectedIndex() == fp.RANGE_TEXT)) {
0N/A if (getBit(index)) {
0N/A return "Font \"" + fontName + "\" can display some characters in \"" +
0N/A rm.getSelectedItem() + "\" range";
0N/A }
0N/A else {
0N/A return "Font \"" + fontName + "\" cannot display any characters in \"" +
0N/A rm.getSelectedItem() + "\" range";
0N/A }
0N/A }
0N/A return super.getToolTipText();
0N/A }
0N/A
0N/A public void setBit(int bitIndex, boolean value) {
0N/A bitSet.set(bitIndex, value);
0N/A }
0N/A
0N/A public boolean getBit(int bitIndex) {
0N/A return bitSet.get(bitIndex);
0N/A }
0N/A }
0N/A
0N/A private final class ChoiceV2Renderer extends DefaultListCellRenderer {
0N/A
0N/A private ImageIcon yesImage, blankImage;
0N/A private ChoiceV2 choice = null;
0N/A
0N/A public ChoiceV2Renderer(ChoiceV2 choice) {
0N/A BufferedImage yes =
0N/A new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);
0N/A Graphics2D g = yes.createGraphics();
0N/A g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
0N/A RenderingHints.VALUE_ANTIALIAS_ON);
0N/A g.setColor(Color.BLUE);
0N/A g.drawLine(0, 5, 3, 10);
0N/A g.drawLine(1, 5, 4, 10);
0N/A g.drawLine(3, 10, 10, 0);
0N/A g.drawLine(4, 9, 9, 0);
0N/A g.dispose();
0N/A BufferedImage blank =
0N/A new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);
0N/A yesImage = new ImageIcon(yes);
0N/A blankImage = new ImageIcon(blank);
0N/A this.choice = choice;
0N/A }
0N/A
0N/A public Component getListCellRendererComponent(JList list,
0N/A Object value,
0N/A int index,
0N/A boolean isSelected,
0N/A boolean cellHasFocus) {
0N/A
0N/A if(textMenu.getSelectedIndex() == fp.RANGE_TEXT) {
0N/A
0N/A super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
0N/A
0N/A //For JComboBox if index is -1, its rendering the selected index.
0N/A if(index == -1) {
0N/A index = choice.getSelectedIndex();
0N/A }
0N/A
0N/A if(choice.getBit(index)) {
0N/A setIcon(yesImage);
0N/A }
0N/A else {
0N/A setIcon(blankImage);
0N/A }
0N/A
0N/A } else {
0N/A super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
0N/A setIcon(blankImage);
0N/A }
0N/A
0N/A return this;
0N/A }
0N/A }
0N/A
0N/A private final class LabelV2 extends JLabel {
0N/A public LabelV2( String name ) {
0N/A super( name );
0N/A }
0N/A }
0N/A
0N/A private final class MenuItemV2 extends JMenuItem {
0N/A public MenuItemV2( String name, ActionListener al ) {
0N/A super( name );
0N/A this.addActionListener( al );
0N/A }
0N/A }
0N/A
0N/A private final class CheckboxMenuItemV2 extends JCheckBoxMenuItem {
0N/A public CheckboxMenuItemV2( String name, boolean b, ItemListener il ) {
0N/A super( name, b );
0N/A this.addItemListener( il );
0N/A }
0N/A }
0N/A}