< prev index next >

src/demo/share/jfc/Font2DTest/Font2DTest.java

Print this page




  50 import java.awt.Graphics2D;
  51 import java.awt.GraphicsEnvironment;
  52 import java.awt.GridBagConstraints;
  53 import java.awt.GridBagLayout;
  54 import java.awt.GridLayout;
  55 import java.awt.Insets;
  56 import java.awt.RenderingHints;
  57 import java.awt.Toolkit;
  58 import java.awt.event.ActionEvent;
  59 import java.awt.event.ActionListener;
  60 import java.awt.event.ItemEvent;
  61 import java.awt.event.ItemListener;
  62 import java.awt.event.WindowAdapter;
  63 import java.awt.event.WindowEvent;
  64 import java.awt.image.BufferedImage;
  65 import java.io.BufferedInputStream;
  66 import java.io.BufferedOutputStream;
  67 import java.io.File;
  68 import java.io.FileInputStream;
  69 import java.io.FileOutputStream;
  70 import java.util.EnumSet;
  71 import java.util.StringTokenizer;
  72 import java.util.BitSet;
  73 import javax.swing.*;
  74 import javax.swing.event.*;
  75 
  76 /**
  77  * Font2DTest.java
  78  *
  79  * @author Shinsuke Fukuda
  80  * @author Ankit Patel [Conversion to Swing - 01/07/30]
  81  */
  82 
  83 /// Main Font2DTest Class
  84 
  85 public final class Font2DTest extends JPanel
  86     implements ActionListener, ItemListener, ChangeListener {
  87 
  88     /// JFrame that will contain Font2DTest
  89     private final JFrame parent;
  90     /// FontPanel class that will contain all graphical output
  91     private final FontPanel fp;
  92     /// RangeMenu class that contains info about the unicode ranges
  93     private final RangeMenu rm;
  94 
  95     /// Other menus to set parameters for text drawing
  96     private final ChoiceV2 fontMenu;
  97     private final JTextField sizeField;
  98     private final ChoiceV2 styleMenu;
  99     private final ChoiceV2 textMenu;
 100     private int currentTextChoice = 0;
 101     private final ChoiceV2 transformMenu;
 102     private final ChoiceV2 transformMenuG2;
 103     private final ChoiceV2 methodsMenu;
 104     private final JComboBox antiAliasMenu;
 105     private final JComboBox fracMetricsMenu;
 106 
 107     private final JSlider contrastSlider;
 108 
 109     /// CheckboxMenuItems
 110     private CheckboxMenuItemV2 displayGridCBMI;
 111     private CheckboxMenuItemV2 force16ColsCBMI;
 112     private CheckboxMenuItemV2 showFontInfoCBMI;
 113 
 114     /// JDialog boxes
 115     private JDialog userTextDialog;
 116     private JTextArea userTextArea;
 117     private JDialog printDialog;
 118     private JDialog fontInfoDialog;
 119     private LabelV2[] fontInfos = new LabelV2[2];
 120     private JFileChooser filePromptDialog = null;
 121 
 122     private ButtonGroup printCBGroup;
 123     private JRadioButton[] printModeCBs = new JRadioButton[3];
 124 
 125     /// Status bar


 134     private static boolean canDisplayCheck = true;
 135 
 136     /// Initialize GUI variables and its layouts
 137     public Font2DTest( JFrame f, boolean isApplet ) {
 138         parent = f;
 139 
 140         rm = new RangeMenu( this, parent );
 141         fp = new FontPanel( this, parent );
 142         statusBar = new LabelV2("");
 143 
 144         fontMenu = new ChoiceV2( this, canDisplayCheck );
 145         sizeField = new JTextField( "12", 3 );
 146         sizeField.addActionListener( this );
 147         styleMenu = new ChoiceV2( this );
 148         textMenu = new ChoiceV2( ); // listener added later
 149         transformMenu = new ChoiceV2( this );
 150         transformMenuG2 = new ChoiceV2( this );
 151         methodsMenu = new ChoiceV2( this );
 152 
 153         antiAliasMenu =
 154             new JComboBox(EnumSet.allOf(FontPanel.AAValues.class).toArray());
 155         antiAliasMenu.addActionListener(this);
 156         fracMetricsMenu =
 157             new JComboBox(EnumSet.allOf(FontPanel.FMValues.class).toArray());
 158         fracMetricsMenu.addActionListener(this);
 159 
 160         contrastSlider = new JSlider(JSlider.HORIZONTAL, 100, 250,
 161                                  FontPanel.getDefaultLCDContrast().intValue());
 162         contrastSlider.setEnabled(false);
 163         contrastSlider.setMajorTickSpacing(20);
 164         contrastSlider.setMinorTickSpacing(10);
 165         contrastSlider.setPaintTicks(true);
 166         contrastSlider.setPaintLabels(true);
 167         contrastSlider.addChangeListener(this);
 168         setupPanel();
 169         setupMenu( isApplet );
 170         setupDialog( isApplet );
 171 
 172         if(canDisplayCheck) {
 173             fireRangeChanged();
 174         }
 175     }
 176 
 177     /// Set up the main interface panel


 342         LabelV2 message3 = new LabelV2( "(Supplementary chars can be denoted by \\UXXXXXX)" );
 343         userTextArea = new JTextArea( "Font2DTest!" );
 344         ButtonV2 bUpdate = new ButtonV2( "Update", this );
 345         userTextArea.setFont( new Font( "dialog", Font.PLAIN, 12 ));
 346         dialogTopPanel.setLayout( new GridLayout( 3, 1 ));
 347         dialogTopPanel.add( message1 );
 348         dialogTopPanel.add( message2 );
 349         dialogTopPanel.add( message3 );
 350         dialogBottomPanel.add( bUpdate );
 351         //ABP
 352         JScrollPane userTextAreaSP = new JScrollPane(userTextArea);
 353         userTextAreaSP.setPreferredSize(new Dimension(300, 100));
 354 
 355         userTextDialog.getContentPane().setLayout( new BorderLayout() );
 356         userTextDialog.getContentPane().add( "North", dialogTopPanel );
 357         userTextDialog.getContentPane().add( "Center", userTextAreaSP );
 358         userTextDialog.getContentPane().add( "South", dialogBottomPanel );
 359         userTextDialog.pack();
 360         userTextDialog.addWindowListener( new WindowAdapter() {
 361             public void windowClosing( WindowEvent e ) {
 362                 userTextDialog.hide();
 363             }
 364         });
 365 
 366         /// Prepare printing dialog...
 367         printCBGroup = new ButtonGroup();
 368         printModeCBs[ fp.ONE_PAGE ] =
 369           new JRadioButton( "Print one page from currently displayed character/line",
 370                          true );
 371         printModeCBs[ fp.CUR_RANGE ] =
 372           new JRadioButton( "Print all characters in currently selected range",
 373                          false );
 374         printModeCBs[ fp.ALL_TEXT ] =
 375           new JRadioButton( "Print all lines of text",
 376                          false );
 377         LabelV2 l =
 378           new LabelV2( "Note: Page range in native \"Print\" dialog will not affect the result" );
 379         JPanel buttonPanel = new JPanel();
 380         printModeCBs[ fp.ALL_TEXT ].setEnabled( false );
 381         buttonPanel.add( new ButtonV2( "Print", this ));
 382         buttonPanel.add( new ButtonV2( "Cancel", this ));
 383 
 384         printDialog = new JDialog( parent, "Print...", true );
 385         printDialog.setResizable( false );
 386         printDialog.addWindowListener( new WindowAdapter() {
 387             public void windowClosing( WindowEvent e ) {
 388                 printDialog.hide();
 389             }
 390         });
 391         printDialog.getContentPane().setLayout( new GridLayout( printModeCBs.length + 2, 1 ));
 392         printDialog.getContentPane().add( l );
 393         for ( int i = 0; i < printModeCBs.length; i++ ) {
 394             printCBGroup.add( printModeCBs[i] );
 395             printDialog.getContentPane().add( printModeCBs[i] );
 396         }
 397         printDialog.getContentPane().add( buttonPanel );
 398         printDialog.pack();
 399 
 400         /// Prepare font information dialog...
 401         fontInfoDialog = new JDialog( parent, "Font info", false );
 402         fontInfoDialog.setResizable( false );
 403         fontInfoDialog.addWindowListener( new WindowAdapter() {
 404             public void windowClosing( WindowEvent e ) {
 405                 fontInfoDialog.hide();
 406                 showFontInfoCBMI.setState( false );
 407             }
 408         });
 409         JPanel fontInfoPanel = new JPanel();
 410         fontInfoPanel.setLayout( new GridLayout( fontInfos.length, 1 ));
 411         for ( int i = 0; i < fontInfos.length; i++ ) {
 412             fontInfos[i] = new LabelV2("");
 413             fontInfoPanel.add( fontInfos[i] );
 414         }
 415         fontInfoDialog.getContentPane().add( fontInfoPanel );
 416 
 417         /// Move the location of the dialog...
 418         userTextDialog.setLocation( 200, 300 );
 419         fontInfoDialog.setLocation( 0, 400 );
 420     }
 421 
 422     /// RangeMenu object signals using this function
 423     /// when Unicode range has been changed and text needs to be redrawn
 424     public void fireRangeChanged() {
 425         int[] range = rm.getSelectedRange();


 450               fontInfos[i].setText( infos[i] );
 451             fontInfoDialog.pack();
 452         }
 453     }
 454 
 455     private void setupFontList(int rangeStart, int rangeEnd) {
 456 
 457         int listCount = fontMenu.getItemCount();
 458         int size = 16;
 459 
 460         try {
 461             size =  Float.valueOf(sizeField.getText()).intValue();
 462         }
 463         catch ( Exception e ) {
 464             System.out.println("Invalid font size in the size textField. Using default value of 16");
 465         }
 466 
 467         int style = fontStyles[styleMenu.getSelectedIndex()];
 468         Font f;
 469         for (int i = 0; i < listCount; i++) {
 470             String fontName = (String)fontMenu.getItemAt(i);
 471             f = new Font(fontName, style, size);
 472             if ((rm.getSelectedIndex() != RangeMenu.SURROGATES_AREA_INDEX) &&
 473                 canDisplayRange(f, rangeStart, rangeEnd)) {
 474                 fontMenu.setBit(i, true);
 475             }
 476             else {
 477                 fontMenu.setBit(i, false);
 478             }
 479         }
 480 
 481         fontMenu.repaint();
 482     }
 483 
 484     protected boolean canDisplayRange(Font font, int rangeStart, int rangeEnd) {
 485         for (int i = rangeStart; i < rangeEnd; i++) {
 486             if (font.canDisplay(i)) {
 487                 return true;
 488             }
 489         }
 490         return false;


 656                 force16ColsCBMI.getState() + "\n" +
 657                 showFontInfoCBMI.getState() + "\n" +
 658                 rm.getSelectedItem() + "\n" +
 659                 range[0] + "\n" + range[1] + "\n" + curOptions + tFileName);
 660             byte[] toBeWritten = completeOptions.getBytes( "UTF-16" );
 661             bos.write( toBeWritten, 0, toBeWritten.length );
 662             bos.close();
 663         }
 664         catch ( Exception ex ) {
 665             fireChangeStatus( "ERROR: Failed to Save Options File; See Stack Trace", true );
 666             ex.printStackTrace();
 667         }
 668     }
 669 
 670     /// Updates GUI visibility/status after some parameters have changed
 671     private void updateGUI() {
 672         int selectedText = textMenu.getSelectedIndex();
 673 
 674         /// Set the visibility of User Text dialog
 675         if ( selectedText == fp.USER_TEXT )
 676           userTextDialog.show();
 677         else
 678           userTextDialog.hide();
 679         /// Change the visibility/status/availability of Print JDialog buttons
 680         printModeCBs[ fp.ONE_PAGE ].setSelected( true );
 681         if ( selectedText == fp.FILE_TEXT || selectedText == fp.USER_TEXT ) {
 682             /// ABP
 683             /// update methodsMenu to show that TextLayout.draw is being used
 684             /// when we are in FILE_TEXT mode
 685             if ( selectedText == fp.FILE_TEXT )
 686                 methodsMenu.setSelectedItem("TextLayout.draw");
 687             methodsMenu.setEnabled( selectedText == fp.USER_TEXT );
 688             printModeCBs[ fp.CUR_RANGE ].setEnabled( false );
 689             printModeCBs[ fp.ALL_TEXT ].setEnabled( true );
 690         }
 691         else {
 692             /// ABP
 693             /// update methodsMenu to show that drawGlyph is being used
 694             /// when we are in ALL_GLYPHS mode
 695             if ( selectedText == fp.ALL_GLYPHS )
 696                 methodsMenu.setSelectedItem("drawGlyphVector");
 697             methodsMenu.setEnabled( selectedText == fp.RANGE_TEXT );
 698             printModeCBs[ fp.CUR_RANGE ].setEnabled( true );


 776             contrastSlider.setValue(lcdContrast);
 777 
 778             userTextArea.setText( dialogEntry );
 779             updateGUI();
 780 
 781             if ( textToUseOpt == fp.FILE_TEXT ) {
 782               tFileName = perLine.nextToken();
 783               readTextFile(tFileName );
 784             }
 785 
 786             /// Reset option variables and repaint
 787             fp.loadOptions( displayGridOpt, force16ColsOpt,
 788                             rangeStartOpt, rangeEndOpt,
 789                             fontNameOpt, fontSizeOpt,
 790                             fontStyleOpt, fontTransformOpt, g2TransformOpt,
 791                             textToUseOpt, drawMethodOpt,
 792                             antialiasOpt, fractionalOpt,
 793                             lcdContrast, userTextOpt );
 794             if ( showFontInfoOpt ) {
 795                 fireUpdateFontInfo();
 796                 fontInfoDialog.show();
 797             }
 798             else
 799               fontInfoDialog.hide();
 800         }
 801         catch ( Exception ex ) {
 802             fireChangeStatus( "ERROR: Failed to Load Options File; See Stack Trace", true );
 803             ex.printStackTrace();
 804         }
 805     }
 806 
 807     /// Loads a previously saved image
 808     private void loadComparisonPNG( String fileName ) {
 809         try {
 810             BufferedImage image =
 811                 javax.imageio.ImageIO.read(new File(fileName));
 812             JFrame f = new JFrame( "Comparison PNG" );
 813             ImagePanel ip = new ImagePanel( image );
 814             f.setResizable( false );
 815             f.getContentPane().add( ip );
 816             f.addWindowListener( new WindowAdapter() {
 817                 public void windowClosing( WindowEvent e ) {
 818                     ( (JFrame) e.getSource() ).dispose();
 819                 }
 820             });
 821             f.pack();
 822             f.show();
 823         }
 824         catch ( Exception ex ) {
 825             fireChangeStatus( "ERROR: Failed to Load PNG File; See Stack Trace", true );
 826             ex.printStackTrace();
 827         }
 828     }
 829 
 830     /// Interface functions...
 831 
 832     /// ActionListener interface function
 833     /// Responds to JMenuItem, JTextField and JButton actions
 834     public void actionPerformed( ActionEvent e ) {
 835         Object source = e.getSource();
 836 
 837         if ( source instanceof JMenuItem ) {
 838             JMenuItem mi = (JMenuItem) source;
 839             String itemName = mi.getText();
 840 
 841             if ( itemName.equals( "Save Selected Options..." )) {
 842                 String fileName = promptFile( true, "options.txt" );


 844                   writeCurrentOptions( fileName );
 845             }
 846             else if ( itemName.equals( "Load Options..." )) {
 847                 String fileName = promptFile( false, "options.txt" );
 848                 if ( fileName != null )
 849                   loadOptions( fileName );
 850             }
 851             else if ( itemName.equals( "Save as PNG..." )) {
 852                 String fileName = promptFile( true, fontMenu.getSelectedItem() + ".png" );
 853                 if ( fileName != null )
 854                   fp.doSavePNG( fileName );
 855             }
 856             else if ( itemName.equals( "Load PNG File to Compare..." )) {
 857                 String fileName = promptFile( false, null );
 858                 if ( fileName != null )
 859                   loadComparisonPNG( fileName );
 860             }
 861             else if ( itemName.equals( "Page Setup..." ))
 862               fp.doPageSetup();
 863             else if ( itemName.equals( "Print..." ))
 864               printDialog.show();
 865             else if ( itemName.equals( "Close" ))
 866               parent.dispose();
 867             else if ( itemName.equals( "Exit" ))
 868               System.exit(0);
 869         }
 870 
 871         else if ( source instanceof JTextField ) {
 872             JTextField tf = (JTextField) source;
 873             float sz = 12f;
 874             try {
 875                  sz = Float.parseFloat(sizeField.getText());
 876                  if (sz < 1f || sz > 120f) {
 877                       sz = 12f;
 878                       sizeField.setText("12");
 879                  }
 880             } catch (Exception se) {
 881                  sizeField.setText("12");
 882             }
 883             if ( tf == sizeField )
 884               fp.setFontParams( fontMenu.getSelectedItem(),
 885                                 sz,
 886                                 styleMenu.getSelectedIndex(),
 887                                 transformMenu.getSelectedIndex() );
 888         }
 889 
 890         else if ( source instanceof JButton ) {
 891             String itemName = ( (JButton) source ).getText();
 892             /// Print dialog buttons...
 893             if ( itemName.equals( "Print" )) {
 894                 for ( int i = 0; i < printModeCBs.length; i++ )
 895                   if ( printModeCBs[i].isSelected() ) {
 896                       printDialog.hide();
 897                       fp.doPrint( i );
 898                   }
 899             }
 900             else if ( itemName.equals( "Cancel" ))
 901               printDialog.hide();
 902             /// Update button from Usert Text JDialog...
 903             else if ( itemName.equals( "Update" ))
 904               fp.setTextToDraw( fp.USER_TEXT, null,
 905                                 parseUserText( userTextArea.getText() ), null );
 906         }
 907         else if ( source instanceof JComboBox ) {
 908             JComboBox c = (JComboBox) source;
 909 
 910             /// RangeMenu handles actions by itself and then calls fireRangeChanged,
 911             /// so it is not listed or handled here
 912             if ( c == fontMenu || c == styleMenu || c == transformMenu ) {
 913                 float sz = 12f;
 914                 try {
 915                     sz = Float.parseFloat(sizeField.getText());
 916                     if (sz < 1f || sz > 120f) {
 917                         sz = 12f;
 918                         sizeField.setText("12");
 919                     }
 920                 } catch (Exception se) {
 921                     sizeField.setText("12");
 922                 }
 923                 fp.setFontParams(fontMenu.getSelectedItem(),
 924                                  sz,
 925                                  styleMenu.getSelectedIndex(),
 926                                  transformMenu.getSelectedIndex());
 927             } else if ( c == methodsMenu )
 928               fp.setDrawMethod( methodsMenu.getSelectedIndex() );


 979              fp.setRenderingHints(antiAliasMenu.getSelectedItem(),
 980                                   fracMetricsMenu.getSelectedItem(),
 981                                   contrastSlider.getValue());
 982          }
 983     }
 984 
 985     /// ItemListener interface function
 986     /// Responds to JCheckBoxMenuItem, JComboBox and JCheckBox actions
 987     public void itemStateChanged( ItemEvent e ) {
 988         Object source = e.getSource();
 989 
 990         if ( source instanceof JCheckBoxMenuItem ) {
 991             JCheckBoxMenuItem cbmi = (JCheckBoxMenuItem) source;
 992             if ( cbmi == displayGridCBMI )
 993               fp.setGridDisplay( displayGridCBMI.getState() );
 994             else if ( cbmi == force16ColsCBMI )
 995               fp.setForce16Columns( force16ColsCBMI.getState() );
 996             else if ( cbmi == showFontInfoCBMI ) {
 997                 if ( showFontInfoCBMI.getState() ) {
 998                     fireUpdateFontInfo();
 999                     fontInfoDialog.show();
1000                 }
1001                 else
1002                   fontInfoDialog.hide();
1003             }
1004         }
1005     }
1006 
1007     private static void printUsage() {
1008         String usage = "Usage: java -jar Font2DTest.jar [options]\n" +
1009             "\nwhere options include:\n" +
1010             "    -dcdc | -disablecandisplaycheck disable canDisplay check for font\n" +
1011             "    -?    | -help                   print this help message\n" +
1012             "\nExample :\n" +
1013             "     To disable canDisplay check on font for ranges\n" +
1014             "     java -jar Font2DTest.jar -dcdc";
1015         System.out.println(usage);
1016         System.exit(0);
1017     }
1018 
1019     /// Main function
1020     public static void main(String[] argv) {
1021 
1022         if(argv.length > 0) {
1023             if(argv[0].equalsIgnoreCase("-disablecandisplaycheck") ||
1024                argv[0].equalsIgnoreCase("-dcdc")) {
1025                 canDisplayCheck = false;
1026             }
1027             else {
1028                 printUsage();
1029             }
1030         }
1031 
1032         UIManager.put("swing.boldMetal", Boolean.FALSE);
1033         final JFrame f = new JFrame( "Font2DTest" );
1034         final Font2DTest f2dt = new Font2DTest( f, false );
1035         f.addWindowListener( new WindowAdapter() {
1036             public void windowOpening( WindowEvent e ) { f2dt.repaint(); }
1037             public void windowClosing( WindowEvent e ) { System.exit(0); }
1038         });
1039 
1040         f.getContentPane().add( f2dt );
1041         f.pack();
1042         f.show();
1043     }
1044 
1045     /// Inner class definitions...
1046 
1047     /// Class to display just an image file
1048     /// Used to show the comparison PNG image
1049     private final class ImagePanel extends JPanel {
1050         private final BufferedImage bi;
1051 
1052         public ImagePanel( BufferedImage image ) {
1053             bi = image;
1054         }
1055 
1056         public Dimension getPreferredSize() {
1057             return new Dimension( bi.getWidth(), bi.getHeight() );
1058         }
1059 
1060         public void paintComponent( Graphics g ) {
1061             g.drawImage( bi, 0, 0, this );
1062         }
1063     }
1064 
1065     /// Classes made to avoid repetitive calls... (being lazy)
1066     private final class ButtonV2 extends JButton {
1067         public ButtonV2( String name, ActionListener al ) {
1068             super( name );
1069             this.addActionListener( al );
1070         }
1071     }
1072 
1073     private final class ChoiceV2 extends JComboBox {
1074 
1075         private BitSet bitSet = null;
1076 
1077         public ChoiceV2() {;}
1078 
1079         public ChoiceV2( ActionListener al ) {
1080             super();
1081             this.addActionListener( al );
1082         }
1083 
1084         public ChoiceV2( ActionListener al, boolean fontChoice) {
1085             this(al);
1086             if(fontChoice) {
1087                 //Register this component in ToolTipManager
1088                 setToolTipText("");
1089                 bitSet = new BitSet();
1090                 setRenderer(new ChoiceV2Renderer(this));
1091             }
1092         }
1093 


1124 
1125         public ChoiceV2Renderer(ChoiceV2 choice) {
1126             BufferedImage yes =
1127                 new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);
1128             Graphics2D g = yes.createGraphics();
1129             g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
1130                                RenderingHints.VALUE_ANTIALIAS_ON);
1131             g.setColor(Color.BLUE);
1132             g.drawLine(0, 5, 3, 10);
1133             g.drawLine(1, 5, 4, 10);
1134             g.drawLine(3, 10, 10, 0);
1135             g.drawLine(4, 9, 9, 0);
1136             g.dispose();
1137             BufferedImage blank =
1138                 new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);
1139             yesImage = new ImageIcon(yes);
1140             blankImage = new ImageIcon(blank);
1141             this.choice = choice;
1142         }
1143 
1144         public Component getListCellRendererComponent(JList list,
1145                                                       Object value,
1146                                                       int index,
1147                                                       boolean isSelected,
1148                                                       boolean cellHasFocus) {
1149 
1150             if(textMenu.getSelectedIndex() == fp.RANGE_TEXT) {
1151 
1152                 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1153 
1154                 //For JComboBox if index is -1, its rendering the selected index.
1155                 if(index == -1) {
1156                     index = choice.getSelectedIndex();
1157                 }
1158 
1159                 if(choice.getBit(index)) {
1160                     setIcon(yesImage);
1161                 }
1162                 else {
1163                     setIcon(blankImage);
1164                 }




  50 import java.awt.Graphics2D;
  51 import java.awt.GraphicsEnvironment;
  52 import java.awt.GridBagConstraints;
  53 import java.awt.GridBagLayout;
  54 import java.awt.GridLayout;
  55 import java.awt.Insets;
  56 import java.awt.RenderingHints;
  57 import java.awt.Toolkit;
  58 import java.awt.event.ActionEvent;
  59 import java.awt.event.ActionListener;
  60 import java.awt.event.ItemEvent;
  61 import java.awt.event.ItemListener;
  62 import java.awt.event.WindowAdapter;
  63 import java.awt.event.WindowEvent;
  64 import java.awt.image.BufferedImage;
  65 import java.io.BufferedInputStream;
  66 import java.io.BufferedOutputStream;
  67 import java.io.File;
  68 import java.io.FileInputStream;
  69 import java.io.FileOutputStream;

  70 import java.util.StringTokenizer;
  71 import java.util.BitSet;
  72 import javax.swing.*;
  73 import javax.swing.event.*;
  74 
  75 /**
  76  * Font2DTest.java
  77  *
  78  * @author Shinsuke Fukuda
  79  * @author Ankit Patel [Conversion to Swing - 01/07/30]
  80  */
  81 
  82 /// Main Font2DTest Class
  83 
  84 public final class Font2DTest extends JPanel
  85     implements ActionListener, ItemListener, ChangeListener {
  86 
  87     /// JFrame that will contain Font2DTest
  88     private final JFrame parent;
  89     /// FontPanel class that will contain all graphical output
  90     private final FontPanel fp;
  91     /// RangeMenu class that contains info about the unicode ranges
  92     private final RangeMenu rm;
  93 
  94     /// Other menus to set parameters for text drawing
  95     private final ChoiceV2 fontMenu;
  96     private final JTextField sizeField;
  97     private final ChoiceV2 styleMenu;
  98     private final ChoiceV2 textMenu;
  99     private int currentTextChoice = 0;
 100     private final ChoiceV2 transformMenu;
 101     private final ChoiceV2 transformMenuG2;
 102     private final ChoiceV2 methodsMenu;
 103     private final JComboBox<FontPanel.AAValues> antiAliasMenu;
 104     private final JComboBox<FontPanel.FMValues> fracMetricsMenu;
 105 
 106     private final JSlider contrastSlider;
 107 
 108     /// CheckboxMenuItems
 109     private CheckboxMenuItemV2 displayGridCBMI;
 110     private CheckboxMenuItemV2 force16ColsCBMI;
 111     private CheckboxMenuItemV2 showFontInfoCBMI;
 112 
 113     /// JDialog boxes
 114     private JDialog userTextDialog;
 115     private JTextArea userTextArea;
 116     private JDialog printDialog;
 117     private JDialog fontInfoDialog;
 118     private LabelV2[] fontInfos = new LabelV2[2];
 119     private JFileChooser filePromptDialog = null;
 120 
 121     private ButtonGroup printCBGroup;
 122     private JRadioButton[] printModeCBs = new JRadioButton[3];
 123 
 124     /// Status bar


 133     private static boolean canDisplayCheck = true;
 134 
 135     /// Initialize GUI variables and its layouts
 136     public Font2DTest( JFrame f, boolean isApplet ) {
 137         parent = f;
 138 
 139         rm = new RangeMenu( this, parent );
 140         fp = new FontPanel( this, parent );
 141         statusBar = new LabelV2("");
 142 
 143         fontMenu = new ChoiceV2( this, canDisplayCheck );
 144         sizeField = new JTextField( "12", 3 );
 145         sizeField.addActionListener( this );
 146         styleMenu = new ChoiceV2( this );
 147         textMenu = new ChoiceV2( ); // listener added later
 148         transformMenu = new ChoiceV2( this );
 149         transformMenuG2 = new ChoiceV2( this );
 150         methodsMenu = new ChoiceV2( this );
 151 
 152         antiAliasMenu =
 153             new JComboBox<>(FontPanel.AAValues.values());
 154         antiAliasMenu.addActionListener(this);
 155         fracMetricsMenu =
 156             new JComboBox<>(FontPanel.FMValues.values());
 157         fracMetricsMenu.addActionListener(this);
 158 
 159         contrastSlider = new JSlider(JSlider.HORIZONTAL, 100, 250,
 160                                  FontPanel.getDefaultLCDContrast().intValue());
 161         contrastSlider.setEnabled(false);
 162         contrastSlider.setMajorTickSpacing(20);
 163         contrastSlider.setMinorTickSpacing(10);
 164         contrastSlider.setPaintTicks(true);
 165         contrastSlider.setPaintLabels(true);
 166         contrastSlider.addChangeListener(this);
 167         setupPanel();
 168         setupMenu( isApplet );
 169         setupDialog( isApplet );
 170 
 171         if(canDisplayCheck) {
 172             fireRangeChanged();
 173         }
 174     }
 175 
 176     /// Set up the main interface panel


 341         LabelV2 message3 = new LabelV2( "(Supplementary chars can be denoted by \\UXXXXXX)" );
 342         userTextArea = new JTextArea( "Font2DTest!" );
 343         ButtonV2 bUpdate = new ButtonV2( "Update", this );
 344         userTextArea.setFont( new Font( "dialog", Font.PLAIN, 12 ));
 345         dialogTopPanel.setLayout( new GridLayout( 3, 1 ));
 346         dialogTopPanel.add( message1 );
 347         dialogTopPanel.add( message2 );
 348         dialogTopPanel.add( message3 );
 349         dialogBottomPanel.add( bUpdate );
 350         //ABP
 351         JScrollPane userTextAreaSP = new JScrollPane(userTextArea);
 352         userTextAreaSP.setPreferredSize(new Dimension(300, 100));
 353 
 354         userTextDialog.getContentPane().setLayout( new BorderLayout() );
 355         userTextDialog.getContentPane().add( "North", dialogTopPanel );
 356         userTextDialog.getContentPane().add( "Center", userTextAreaSP );
 357         userTextDialog.getContentPane().add( "South", dialogBottomPanel );
 358         userTextDialog.pack();
 359         userTextDialog.addWindowListener( new WindowAdapter() {
 360             public void windowClosing( WindowEvent e ) {
 361                 userTextDialog.setVisible(false);
 362             }
 363         });
 364 
 365         /// Prepare printing dialog...
 366         printCBGroup = new ButtonGroup();
 367         printModeCBs[ fp.ONE_PAGE ] =
 368           new JRadioButton( "Print one page from currently displayed character/line",
 369                          true );
 370         printModeCBs[ fp.CUR_RANGE ] =
 371           new JRadioButton( "Print all characters in currently selected range",
 372                          false );
 373         printModeCBs[ fp.ALL_TEXT ] =
 374           new JRadioButton( "Print all lines of text",
 375                          false );
 376         LabelV2 l =
 377           new LabelV2( "Note: Page range in native \"Print\" dialog will not affect the result" );
 378         JPanel buttonPanel = new JPanel();
 379         printModeCBs[ fp.ALL_TEXT ].setEnabled( false );
 380         buttonPanel.add( new ButtonV2( "Print", this ));
 381         buttonPanel.add( new ButtonV2( "Cancel", this ));
 382 
 383         printDialog = new JDialog( parent, "Print...", true );
 384         printDialog.setResizable( false );
 385         printDialog.addWindowListener( new WindowAdapter() {
 386             public void windowClosing( WindowEvent e ) {
 387                 printDialog.setVisible(false);
 388             }
 389         });
 390         printDialog.getContentPane().setLayout( new GridLayout( printModeCBs.length + 2, 1 ));
 391         printDialog.getContentPane().add( l );
 392         for ( int i = 0; i < printModeCBs.length; i++ ) {
 393             printCBGroup.add( printModeCBs[i] );
 394             printDialog.getContentPane().add( printModeCBs[i] );
 395         }
 396         printDialog.getContentPane().add( buttonPanel );
 397         printDialog.pack();
 398 
 399         /// Prepare font information dialog...
 400         fontInfoDialog = new JDialog( parent, "Font info", false );
 401         fontInfoDialog.setResizable( false );
 402         fontInfoDialog.addWindowListener( new WindowAdapter() {
 403             public void windowClosing( WindowEvent e ) {
 404                 fontInfoDialog.setVisible(false);
 405                 showFontInfoCBMI.setState( false );
 406             }
 407         });
 408         JPanel fontInfoPanel = new JPanel();
 409         fontInfoPanel.setLayout( new GridLayout( fontInfos.length, 1 ));
 410         for ( int i = 0; i < fontInfos.length; i++ ) {
 411             fontInfos[i] = new LabelV2("");
 412             fontInfoPanel.add( fontInfos[i] );
 413         }
 414         fontInfoDialog.getContentPane().add( fontInfoPanel );
 415 
 416         /// Move the location of the dialog...
 417         userTextDialog.setLocation( 200, 300 );
 418         fontInfoDialog.setLocation( 0, 400 );
 419     }
 420 
 421     /// RangeMenu object signals using this function
 422     /// when Unicode range has been changed and text needs to be redrawn
 423     public void fireRangeChanged() {
 424         int[] range = rm.getSelectedRange();


 449               fontInfos[i].setText( infos[i] );
 450             fontInfoDialog.pack();
 451         }
 452     }
 453 
 454     private void setupFontList(int rangeStart, int rangeEnd) {
 455 
 456         int listCount = fontMenu.getItemCount();
 457         int size = 16;
 458 
 459         try {
 460             size =  Float.valueOf(sizeField.getText()).intValue();
 461         }
 462         catch ( Exception e ) {
 463             System.out.println("Invalid font size in the size textField. Using default value of 16");
 464         }
 465 
 466         int style = fontStyles[styleMenu.getSelectedIndex()];
 467         Font f;
 468         for (int i = 0; i < listCount; i++) {
 469             String fontName = fontMenu.getItemAt(i);
 470             f = new Font(fontName, style, size);
 471             if ((rm.getSelectedIndex() != RangeMenu.SURROGATES_AREA_INDEX) &&
 472                 canDisplayRange(f, rangeStart, rangeEnd)) {
 473                 fontMenu.setBit(i, true);
 474             }
 475             else {
 476                 fontMenu.setBit(i, false);
 477             }
 478         }
 479 
 480         fontMenu.repaint();
 481     }
 482 
 483     protected boolean canDisplayRange(Font font, int rangeStart, int rangeEnd) {
 484         for (int i = rangeStart; i < rangeEnd; i++) {
 485             if (font.canDisplay(i)) {
 486                 return true;
 487             }
 488         }
 489         return false;


 655                 force16ColsCBMI.getState() + "\n" +
 656                 showFontInfoCBMI.getState() + "\n" +
 657                 rm.getSelectedItem() + "\n" +
 658                 range[0] + "\n" + range[1] + "\n" + curOptions + tFileName);
 659             byte[] toBeWritten = completeOptions.getBytes( "UTF-16" );
 660             bos.write( toBeWritten, 0, toBeWritten.length );
 661             bos.close();
 662         }
 663         catch ( Exception ex ) {
 664             fireChangeStatus( "ERROR: Failed to Save Options File; See Stack Trace", true );
 665             ex.printStackTrace();
 666         }
 667     }
 668 
 669     /// Updates GUI visibility/status after some parameters have changed
 670     private void updateGUI() {
 671         int selectedText = textMenu.getSelectedIndex();
 672 
 673         /// Set the visibility of User Text dialog
 674         if ( selectedText == fp.USER_TEXT )
 675           userTextDialog.setVisible(true);
 676         else
 677           userTextDialog.setVisible(false);
 678         /// Change the visibility/status/availability of Print JDialog buttons
 679         printModeCBs[ fp.ONE_PAGE ].setSelected( true );
 680         if ( selectedText == fp.FILE_TEXT || selectedText == fp.USER_TEXT ) {
 681             /// ABP
 682             /// update methodsMenu to show that TextLayout.draw is being used
 683             /// when we are in FILE_TEXT mode
 684             if ( selectedText == fp.FILE_TEXT )
 685                 methodsMenu.setSelectedItem("TextLayout.draw");
 686             methodsMenu.setEnabled( selectedText == fp.USER_TEXT );
 687             printModeCBs[ fp.CUR_RANGE ].setEnabled( false );
 688             printModeCBs[ fp.ALL_TEXT ].setEnabled( true );
 689         }
 690         else {
 691             /// ABP
 692             /// update methodsMenu to show that drawGlyph is being used
 693             /// when we are in ALL_GLYPHS mode
 694             if ( selectedText == fp.ALL_GLYPHS )
 695                 methodsMenu.setSelectedItem("drawGlyphVector");
 696             methodsMenu.setEnabled( selectedText == fp.RANGE_TEXT );
 697             printModeCBs[ fp.CUR_RANGE ].setEnabled( true );


 775             contrastSlider.setValue(lcdContrast);
 776 
 777             userTextArea.setText( dialogEntry );
 778             updateGUI();
 779 
 780             if ( textToUseOpt == fp.FILE_TEXT ) {
 781               tFileName = perLine.nextToken();
 782               readTextFile(tFileName );
 783             }
 784 
 785             /// Reset option variables and repaint
 786             fp.loadOptions( displayGridOpt, force16ColsOpt,
 787                             rangeStartOpt, rangeEndOpt,
 788                             fontNameOpt, fontSizeOpt,
 789                             fontStyleOpt, fontTransformOpt, g2TransformOpt,
 790                             textToUseOpt, drawMethodOpt,
 791                             antialiasOpt, fractionalOpt,
 792                             lcdContrast, userTextOpt );
 793             if ( showFontInfoOpt ) {
 794                 fireUpdateFontInfo();
 795                 fontInfoDialog.setVisible(true);
 796             }
 797             else
 798               fontInfoDialog.setVisible(false);
 799         }
 800         catch ( Exception ex ) {
 801             fireChangeStatus( "ERROR: Failed to Load Options File; See Stack Trace", true );
 802             ex.printStackTrace();
 803         }
 804     }
 805 
 806     /// Loads a previously saved image
 807     private void loadComparisonPNG( String fileName ) {
 808         try {
 809             BufferedImage image =
 810                 javax.imageio.ImageIO.read(new File(fileName));
 811             JFrame f = new JFrame( "Comparison PNG" );
 812             ImagePanel ip = new ImagePanel( image );
 813             f.setResizable( false );
 814             f.getContentPane().add( ip );
 815             f.addWindowListener( new WindowAdapter() {
 816                 public void windowClosing( WindowEvent e ) {
 817                     ( (JFrame) e.getSource() ).dispose();
 818                 }
 819             });
 820             f.pack();
 821             f.setVisible(true);
 822         }
 823         catch ( Exception ex ) {
 824             fireChangeStatus( "ERROR: Failed to Load PNG File; See Stack Trace", true );
 825             ex.printStackTrace();
 826         }
 827     }
 828 
 829     /// Interface functions...
 830 
 831     /// ActionListener interface function
 832     /// Responds to JMenuItem, JTextField and JButton actions
 833     public void actionPerformed( ActionEvent e ) {
 834         Object source = e.getSource();
 835 
 836         if ( source instanceof JMenuItem ) {
 837             JMenuItem mi = (JMenuItem) source;
 838             String itemName = mi.getText();
 839 
 840             if ( itemName.equals( "Save Selected Options..." )) {
 841                 String fileName = promptFile( true, "options.txt" );


 843                   writeCurrentOptions( fileName );
 844             }
 845             else if ( itemName.equals( "Load Options..." )) {
 846                 String fileName = promptFile( false, "options.txt" );
 847                 if ( fileName != null )
 848                   loadOptions( fileName );
 849             }
 850             else if ( itemName.equals( "Save as PNG..." )) {
 851                 String fileName = promptFile( true, fontMenu.getSelectedItem() + ".png" );
 852                 if ( fileName != null )
 853                   fp.doSavePNG( fileName );
 854             }
 855             else if ( itemName.equals( "Load PNG File to Compare..." )) {
 856                 String fileName = promptFile( false, null );
 857                 if ( fileName != null )
 858                   loadComparisonPNG( fileName );
 859             }
 860             else if ( itemName.equals( "Page Setup..." ))
 861               fp.doPageSetup();
 862             else if ( itemName.equals( "Print..." ))
 863               printDialog.setVisible(true);
 864             else if ( itemName.equals( "Close" ))
 865               parent.dispose();
 866             else if ( itemName.equals( "Exit" ))
 867               System.exit(0);
 868         }
 869 
 870         else if ( source instanceof JTextField ) {
 871             JTextField tf = (JTextField) source;
 872             float sz = 12f;
 873             try {
 874                  sz = Float.parseFloat(sizeField.getText());
 875                  if (sz < 1f || sz > 120f) {
 876                       sz = 12f;
 877                       sizeField.setText("12");
 878                  }
 879             } catch (Exception se) {
 880                  sizeField.setText("12");
 881             }
 882             if ( tf == sizeField )
 883               fp.setFontParams( fontMenu.getSelectedItem(),
 884                                 sz,
 885                                 styleMenu.getSelectedIndex(),
 886                                 transformMenu.getSelectedIndex() );
 887         }
 888 
 889         else if ( source instanceof JButton ) {
 890             String itemName = ( (JButton) source ).getText();
 891             /// Print dialog buttons...
 892             if ( itemName.equals( "Print" )) {
 893                 for ( int i = 0; i < printModeCBs.length; i++ )
 894                   if ( printModeCBs[i].isSelected() ) {
 895                       printDialog.setVisible(false);
 896                       fp.doPrint( i );
 897                   }
 898             }
 899             else if ( itemName.equals( "Cancel" ))
 900               printDialog.setVisible(false);
 901             /// Update button from Usert Text JDialog...
 902             else if ( itemName.equals( "Update" ))
 903               fp.setTextToDraw( fp.USER_TEXT, null,
 904                                 parseUserText( userTextArea.getText() ), null );
 905         }
 906         else if ( source instanceof JComboBox ) {
 907             JComboBox<?> c = (JComboBox<?>) source;
 908 
 909             /// RangeMenu handles actions by itself and then calls fireRangeChanged,
 910             /// so it is not listed or handled here
 911             if ( c == fontMenu || c == styleMenu || c == transformMenu ) {
 912                 float sz = 12f;
 913                 try {
 914                     sz = Float.parseFloat(sizeField.getText());
 915                     if (sz < 1f || sz > 120f) {
 916                         sz = 12f;
 917                         sizeField.setText("12");
 918                     }
 919                 } catch (Exception se) {
 920                     sizeField.setText("12");
 921                 }
 922                 fp.setFontParams(fontMenu.getSelectedItem(),
 923                                  sz,
 924                                  styleMenu.getSelectedIndex(),
 925                                  transformMenu.getSelectedIndex());
 926             } else if ( c == methodsMenu )
 927               fp.setDrawMethod( methodsMenu.getSelectedIndex() );


 978              fp.setRenderingHints(antiAliasMenu.getSelectedItem(),
 979                                   fracMetricsMenu.getSelectedItem(),
 980                                   contrastSlider.getValue());
 981          }
 982     }
 983 
 984     /// ItemListener interface function
 985     /// Responds to JCheckBoxMenuItem, JComboBox and JCheckBox actions
 986     public void itemStateChanged( ItemEvent e ) {
 987         Object source = e.getSource();
 988 
 989         if ( source instanceof JCheckBoxMenuItem ) {
 990             JCheckBoxMenuItem cbmi = (JCheckBoxMenuItem) source;
 991             if ( cbmi == displayGridCBMI )
 992               fp.setGridDisplay( displayGridCBMI.getState() );
 993             else if ( cbmi == force16ColsCBMI )
 994               fp.setForce16Columns( force16ColsCBMI.getState() );
 995             else if ( cbmi == showFontInfoCBMI ) {
 996                 if ( showFontInfoCBMI.getState() ) {
 997                     fireUpdateFontInfo();
 998                     fontInfoDialog.setVisible(true);
 999                 }
1000                 else
1001                   fontInfoDialog.setVisible(false);
1002             }
1003         }
1004     }
1005 
1006     private static void printUsage() {
1007         String usage = "Usage: java -jar Font2DTest.jar [options]\n" +
1008             "\nwhere options include:\n" +
1009             "    -dcdc | -disablecandisplaycheck disable canDisplay check for font\n" +
1010             "    -?    | -help                   print this help message\n" +
1011             "\nExample :\n" +
1012             "     To disable canDisplay check on font for ranges\n" +
1013             "     java -jar Font2DTest.jar -dcdc";
1014         System.out.println(usage);
1015         System.exit(0);
1016     }
1017 
1018     /// Main function
1019     public static void main(String[] argv) {
1020 
1021         if(argv.length > 0) {
1022             if(argv[0].equalsIgnoreCase("-disablecandisplaycheck") ||
1023                argv[0].equalsIgnoreCase("-dcdc")) {
1024                 canDisplayCheck = false;
1025             }
1026             else {
1027                 printUsage();
1028             }
1029         }
1030 
1031         UIManager.put("swing.boldMetal", Boolean.FALSE);
1032         final JFrame f = new JFrame( "Font2DTest" );
1033         final Font2DTest f2dt = new Font2DTest( f, false );
1034         f.addWindowListener( new WindowAdapter() {
1035             public void windowOpening( WindowEvent e ) { f2dt.repaint(); }
1036             public void windowClosing( WindowEvent e ) { System.exit(0); }
1037         });
1038 
1039         f.getContentPane().add( f2dt );
1040         f.pack();
1041         f.setVisible(true);
1042     }
1043 
1044     /// Inner class definitions...
1045 
1046     /// Class to display just an image file
1047     /// Used to show the comparison PNG image
1048     private final class ImagePanel extends JPanel {
1049         private final BufferedImage bi;
1050 
1051         public ImagePanel( BufferedImage image ) {
1052             bi = image;
1053         }
1054 
1055         public Dimension getPreferredSize() {
1056             return new Dimension( bi.getWidth(), bi.getHeight() );
1057         }
1058 
1059         public void paintComponent( Graphics g ) {
1060             g.drawImage( bi, 0, 0, this );
1061         }
1062     }
1063 
1064     /// Classes made to avoid repetitive calls... (being lazy)
1065     private final class ButtonV2 extends JButton {
1066         public ButtonV2( String name, ActionListener al ) {
1067             super( name );
1068             this.addActionListener( al );
1069         }
1070     }
1071 
1072     private final class ChoiceV2 extends JComboBox<String> {
1073 
1074         private BitSet bitSet = null;
1075 
1076         public ChoiceV2() {;}
1077 
1078         public ChoiceV2( ActionListener al ) {
1079             super();
1080             this.addActionListener( al );
1081         }
1082 
1083         public ChoiceV2( ActionListener al, boolean fontChoice) {
1084             this(al);
1085             if(fontChoice) {
1086                 //Register this component in ToolTipManager
1087                 setToolTipText("");
1088                 bitSet = new BitSet();
1089                 setRenderer(new ChoiceV2Renderer(this));
1090             }
1091         }
1092 


1123 
1124         public ChoiceV2Renderer(ChoiceV2 choice) {
1125             BufferedImage yes =
1126                 new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);
1127             Graphics2D g = yes.createGraphics();
1128             g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
1129                                RenderingHints.VALUE_ANTIALIAS_ON);
1130             g.setColor(Color.BLUE);
1131             g.drawLine(0, 5, 3, 10);
1132             g.drawLine(1, 5, 4, 10);
1133             g.drawLine(3, 10, 10, 0);
1134             g.drawLine(4, 9, 9, 0);
1135             g.dispose();
1136             BufferedImage blank =
1137                 new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);
1138             yesImage = new ImageIcon(yes);
1139             blankImage = new ImageIcon(blank);
1140             this.choice = choice;
1141         }
1142 
1143         public Component getListCellRendererComponent(JList<?> list,
1144                                                       Object value,
1145                                                       int index,
1146                                                       boolean isSelected,
1147                                                       boolean cellHasFocus) {
1148 
1149             if(textMenu.getSelectedIndex() == fp.RANGE_TEXT) {
1150 
1151                 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1152 
1153                 //For JComboBox if index is -1, its rendering the selected index.
1154                 if(index == -1) {
1155                     index = choice.getSelectedIndex();
1156                 }
1157 
1158                 if(choice.getBit(index)) {
1159                     setIcon(yesImage);
1160                 }
1161                 else {
1162                     setIcon(blankImage);
1163                 }


< prev index next >