/* * [FontShower.java] * * Summary: FontShower: displays Swing fonts. * * Copyright: (c) 2005-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.5 2004-05-18 initial released Fahd Shariff * TODO: add more entities, Greek, hex, JColorChooser * figure out why anti-alias sometimes fails. * 1.6 2004-05-18 Roedy, add about box, make work as application too. change defaults. * add more pangrams. * 1.7 2004-05-18 Use JSpinner for font size. * 1.8 2005-07-20 add more sample chars, allow anti-alias. * 1.9 2005-08-11 prompt whether selecting text or background color. * Separate out FontSamples class to make it common * to FontShower and FontShowerAwt. * Sort out why anti-alias was not working. Remove Baht char. * 2.0 2005-09-01 add Japanese Hiragana and Katagana char. * 2.1 2006-03-05 * 2.2 2007-02-09 more Chinese sample chars * 2.3 2007-05-03 more reserved colour scheme. * 2.4 2008-04-01 display title and build number. * 2.5 2008-05-26 add arrows to sample chars * 2.6 2008-08-18 summary list of all fonts you can copy paste. * 2.7 2008-11-20 add Esperanto accented letters * 2.8 2009-01-23 add Kanji digits to font samples. * 2.9 2009-09-30 add true font heights to allfonts display */ package com.mindprod.fontshower; import com.mindprod.common18.Build; import com.mindprod.common18.CMPAboutJBox; import com.mindprod.common18.Common18; import com.mindprod.common18.FontFactory; import com.mindprod.common18.HybridJ; import com.mindprod.common18.JEButton; import com.mindprod.common18.Misc; import com.mindprod.common18.ST; import com.mindprod.common18.VersionCheck; import com.mindprod.fontshowerawt.FontSamples; import javax.swing.JApplet; import javax.swing.JButton; import javax.swing.JColorChooser; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JSpinner; import javax.swing.JToggleButton; import javax.swing.SpinnerNumberModel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.Color; import java.awt.Container; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics2D; import java.awt.GraphicsEnvironment; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.font.FontRenderContext; import java.awt.font.LineMetrics; import java.awt.image.BufferedImage; import java.text.DecimalFormat; import java.util.Arrays; import java.util.Vector; import static java.lang.System.*; /** * FontShower: displays Swing fonts. *

*

 * An Applet that lets you choose the font family, size, style
 * text color, background color and displays a message in the selected
 * font. Requires Swing.  Text for sample comes from
 * com.mindprod.fontshowerawt.FontSamples.
 * Use either as Applet with
 * <applet code="com.mindprod.fontshower.FontShower.class"
 * archive="fontshower.jar"
 * width="655"
 * height="370"
 * vspace="10"
 * hspace="10"
 * alt="Sorry, you need Java to run FontShower">
 * Sorry, you need Java to run FontShower
 * </applet>
 * 

* or as an application with: * java -ea -jar fontshower.jar *

*

* * @author Roedy Green, Canadian Mind Products * @version 2.9 2009-09-30 add true font heights to all fonts display * @noinspection FieldCanBeLocal * @since 2005 */ public final class FontShower extends JApplet { /** * height of Applet box in pixels. Does not include surrounding frame. */ private static final int APPLET_HEIGHT = 660; /** * Width of Applet box in pixels., wide enough for a very long font name. */ private static final int APPLET_WIDTH = 720; /** * starting font size */ private static final int defaultSize = 18; private static final int FIRST_COPYRIGHT_YEAR = 2005; /** * how the all fonts option is displayed */ private static final String allFontsWording = "\u00aball fonts summary\u00bb"; /** * starting font */ private static final String defaultFontFamily = "Dialog"; /** * undisplayed copyright notice * * @noinspection UnusedDeclaration */ private static final String EMBEDDED_COPYRIGHT = "Copyright: (c) 2005-2017 Roedy Green, Canadian Mind Products, http://mindprod.com"; private static final String RELEASE_DATE = "2009-09-30"; /** * title for about box */ private static final String TITLE_STRING = "Swing Font Shower"; /** * program version for about box */ private static final String VERSION_STRING = "2.9"; /** * background colour, light violet */ private static final Color BACKGROUND_FOR_BODY = new Color( 0xfce8ff ); /** * light green to match mindprod.com background. */ private static final Color BACKGROUND_FOR_DEFAULT = Build.BACKGROUND_FOR_BLENDING; /** * dark green foreground */ private static final Color FOREGROUND_FOR_DEFAULT = new Color( 0x004000 ); /** * for titles */ private static final Color FOREGROUND_FOR_TITLE = new Color( 0xdc143c ); /** * formats the true height of a 10 point font with one decimal place */ private static final DecimalFormat fontSizeFormatter = new DecimalFormat( "#0.9" ); /** * for for titles and About buttons */ private static final Font FONT_FOR_TITLE = FontFactory.build( "Dialog", Font.BOLD, 16 ); /** * for for title second line */ private static final Font FONT_FOR_TITLE2 = FontFactory.build( "Dialog", Font.PLAIN, 14 ); /** * show all fonts at once. */ private AntiAliasedJTextArea allDisplayArea; /** * where we display the font sample */ private AntiAliasedJTextArea displayArea; /** * about button */ private JButton about; /** * select background color */ private JButton chooseBackgroundColor; /** * select foreground color */ private JButton chooseForegroundColor; /** * choice of all supported fonts */ private JComboBox fontChoices; /** * Applet Title */ private JLabel title; /** * title, second line */ private JLabel title2; /** * scrolls list of all fonts */ private JScrollPane allScroller; /** * scrolls the font sample */ private JScrollPane scroller; /** * font size selection */ private JSpinner sizeSpinner; /** * toggle anti-alias state */ private JToggleButton toggleAntiAlias; /** * toggle bold state */ private JToggleButton toggleBold; /** * toggle italic state */ private JToggleButton toggleItalic; /** * helper for sizeSpinner */ private SpinnerNumberModel sizeSpinnerModel; /** * get actual height of font * * @param FontName name of font * * @return true height of a 10 point font in pixels. */ private static float getTrueFontHeight( String FontName ) { final Font f = new Font( FontName, Font.PLAIN, 10 ); final BufferedImage dummybi = new BufferedImage( 200 /* dummy */, 200 /* dummy */, BufferedImage.TYPE_4BYTE_ABGR_PRE ); final Graphics2D dummyg2d = dummybi.createGraphics(); final FontRenderContext fr = dummyg2d.getFontRenderContext(); final LineMetrics lm = f.getLineMetrics( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghiklmnoprstuvwxyz01234567809()[]{}", fr ); return lm.getDescent() + lm.getAscent(); } /** * allocate the components */ private void buildComponents() { title = new JLabel( TITLE_STRING + " " + VERSION_STRING ); title.setFont( FONT_FOR_TITLE ); title.setForeground( FOREGROUND_FOR_TITLE ); title2 = new JLabel( "released:" + RELEASE_DATE + " build:" + Build.BUILD_NUMBER ); title2.setFont( FONT_FOR_TITLE2 ); title2.setForeground( FOREGROUND_FOR_TITLE ); buildFontChoices(); fontChoices.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { final String newFontFamily = ( String ) fontChoices.getSelectedItem(); if ( newFontFamily.equals( allFontsWording ) ) { if ( !allScroller.isVisible() ) { scroller.setVisible( false ); allScroller.setVisible( true ); validate(); } } else { if ( !scroller.isVisible() ) { allScroller.setVisible( false ); scroller.setVisible( true ); validate(); } // display a single font final Font oldFont = displayArea.getFont(); // don't use FontFactory. We want the official font. displayArea.setFont( new Font( newFontFamily, oldFont.getStyle(), oldFont.getSize() ) ); } } } ); // font sizes sizeSpinner = new JSpinner(); Dimension d = new Dimension( 40, 25 ); sizeSpinner.setMinimumSize( d ); sizeSpinner.setPreferredSize( d ); sizeSpinner.setMaximumSize( d ); sizeSpinnerModel = new SpinnerNumberModel( /* init value */ 18, /* min*/ 8, /* max */ 300, /* step */ 1 ); sizeSpinner.setModel( sizeSpinnerModel ); sizeSpinner.addChangeListener( new ChangeListener() { /** * Invoked when the sizeSpinner changes * @param e a ChangeEvent object */ public void stateChanged( ChangeEvent e ) { float fontSize = sizeSpinnerModel.getNumber().floatValue(); displayArea.setFont( displayArea.getFont().deriveFont( fontSize ) ); allDisplayArea.setFont( allDisplayArea.getFont().deriveFont( fontSize ) ); } } ); // bold button toggleBold = new JToggleButton( "Bold", false ); toggleBold.setMnemonic( KeyEvent.VK_B ); toggleBold.setToolTipText( "Bold" ); ActionListener styleChangeListener = new ActionListener() { public void actionPerformed( ActionEvent e ) { changeStyle(); } }; toggleBold.addActionListener( styleChangeListener ); // italic toggleItalic = new JToggleButton( "Italics", false ); toggleItalic.setMnemonic( KeyEvent.VK_I ); toggleItalic.setToolTipText( "Italic" ); toggleItalic.addActionListener( styleChangeListener ); // anti-alias toggleAntiAlias = new JToggleButton( "Anti-alias", false ); toggleAntiAlias.setMnemonic( KeyEvent.VK_A ); toggleAntiAlias.setToolTipText( "Anti-alias font smoothing" ); toggleAntiAlias.addActionListener( styleChangeListener ); // background chooseBackgroundColor = new JEButton( "Background Colour", false ); chooseBackgroundColor.setMnemonic( KeyEvent.VK_C ); chooseBackgroundColor.setToolTipText( "Change Background Colour" ); chooseBackgroundColor.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { final Color newBackground = getColorChoice( false ); displayArea.setBackground( newBackground ); allDisplayArea.setBackground( newBackground ); } } ); // foreground chooseForegroundColor = new JEButton( "Text Colour", false ); chooseForegroundColor.setMnemonic( KeyEvent.VK_T ); chooseForegroundColor.setToolTipText( "Change Text Colour" ); chooseForegroundColor.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { Color newForeground = getColorChoice( true ); displayArea.setForeground( newForeground ); allDisplayArea.setForeground( newForeground ); } } ); // about about = new JEButton( "About" ); about.setToolTipText( "About " + TITLE_STRING + " " + VERSION_STRING ); about.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { // open aboutbox frame new CMPAboutJBox( Misc.getParentFrame( FontShower.this ), TITLE_STRING, VERSION_STRING, "Shows you what fonts are available in Swing and what they", "look like, in various styles, sizes and colours.", "freeware", RELEASE_DATE, FIRST_COPYRIGHT_YEAR, "Fahd Shariff, Roedy Green", "FONTSHOWER", "1.8" ); } } ); displayArea = new AntiAliasedJTextArea( FontSamples.getFontSampleText() ); // build some text to display to show all fonts at once. displayArea.setEditable( false ); displayArea.setBackground( BACKGROUND_FOR_DEFAULT ); displayArea.setForeground( FOREGROUND_FOR_DEFAULT ); // don't use FontFactory. We want the official font. displayArea.setFont( new Font( defaultFontFamily, Font.PLAIN, defaultSize ) ); displayArea.setAntiAlias( false ); // make the text sit back a bit from the edges. displayArea.setMargin( new Insets( 3, 3, 3, 3 ) ); scroller = new JScrollPane( displayArea );// VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED) // displaying a sample of each font means the page takes about 6 seconds to render -- too slow to react // to the buttons, so we just show the name. final GraphicsEnvironment ge = GraphicsEnvironment .getLocalGraphicsEnvironment(); final String[] fontNames = ge.getAvailableFontFamilyNames(); StringBuilder sb = new StringBuilder( fontNames.length * 25 + 100 ); sb.append( "Fonts Available to Java under " ); sb.append( System.getProperty( "os.name", "unknown OS" ) ); sb.append( "\n" ); sb.append( ST.rightPad( "Font Name", 30, false ) ); sb.append( "True height of a 10 point font" ); sb.append( "\n" ); for ( String f : fontNames ) { sb.append( ST.rightPad( f, 30, false ) ); sb.append( ST.leftPad( fontSizeFormatter.format( getTrueFontHeight( f ) ), 4, false ) ); sb.append( "\n" ); } final String allFontsList = sb.toString(); // echo list of all fonts to console for easy copy/paste out.println( allFontsList ); // put list of all fonts to component for rapid showing. allDisplayArea = new AntiAliasedJTextArea( sb.toString() ); allDisplayArea.setEditable( false ); allDisplayArea.setBackground( BACKGROUND_FOR_DEFAULT ); allDisplayArea.setForeground( FOREGROUND_FOR_DEFAULT ); // don't use FontFactory. We want the official font. allDisplayArea.setFont( new Font( "Monospaced", Font.PLAIN, defaultSize ) ); allDisplayArea.setAntiAlias( true ); // make the text sit back a bit from the edges. allDisplayArea.setMargin( new Insets( 3, 3, 3, 3 ) ); allScroller = new JScrollPane( allDisplayArea );// VERTICAL_SCROLLBAR_AS_NEEDED, // HORIZONTAL_SCROLLBAR_AS_NEEDED) allScroller.setVisible( false ); } /** * set up fontChoices Widget with lislt of all possible fonts, but not listeners. */ private void buildFontChoices() { // font names final GraphicsEnvironment ge = GraphicsEnvironment .getLocalGraphicsEnvironment(); final String[] fontNames = ge.getAvailableFontFamilyNames(); // use Vector instead of ArrayList because JComboBox wants a vector final Vector v = new Vector<>( fontNames.length + 1 ); v.add( allFontsWording ); v.addAll( Arrays.asList( fontNames ) ); fontChoices = new JComboBox<>( v ); fontChoices.setMaximumSize( fontChoices.getPreferredSize() ); fontChoices.setEditable( true ); fontChoices.setSelectedItem( defaultFontFamily ); } /** * Changes the style (Bold, Italic ) of the selected text by checking the style buttons */ private void changeStyle() { int style = Font.PLAIN; if ( toggleBold.isSelected() ) { style |= Font.BOLD; } if ( toggleItalic.isSelected() ) { style |= Font.ITALIC; } displayArea.setFont( displayArea.getFont().deriveFont( style ) ); displayArea.setAntiAlias( toggleAntiAlias.isSelected() ); allDisplayArea.setFont( allDisplayArea.getFont().deriveFont( style ) ); allDisplayArea.setAntiAlias( toggleAntiAlias.isSelected() ); // changing font invalidates textarea. } /** * Displays a color chooser and returns the selected color. * * @param foreground true if want to change the foreground color, false to change the background color. * * @return the selected Color */ private Color getColorChoice( boolean foreground ) { return JColorChooser.showDialog( this, "Choose " + ( foreground ? "Text" : "Background" ) + " Color", foreground ? displayArea.getForeground() : displayArea.getBackground() ); } /** * layout all the components in a GridBag * * @param contentPane where to place the components */ private void layoutComponents( Container contentPane ) { // --0---0----1----2-----3-------4----------5---------6---- // 0 title -----------------title2---------------- about // 1 font size bold italics antialias background textcolor- // 2 -----------scroller------------------------------------- // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( title, new GridBagConstraints( 0, 0, 4, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 10, 10, 5, 10 ), 0, 0 ) ); contentPane.add( title2, new GridBagConstraints( 4, 0, 2, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 10, 10, 5, 10 ), 0, 0 ) ); contentPane.add( about, new GridBagConstraints( 6, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 10, 10, 5, 10 ), 0, 0 ) ); contentPane.add( fontChoices, new GridBagConstraints( 0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 0, 10, 5, 5 ), 0, 0 ) ); contentPane.add( sizeSpinner, new GridBagConstraints( 1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 0, 0, 5, 5 ), 5, 0 ) ); contentPane.add( toggleBold, new GridBagConstraints( 2, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 0, 0, 5, 5 ), 0, 0 ) ); contentPane.add( toggleItalic, new GridBagConstraints( 3, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 0, 0, 5, 5 ), 0, 0 ) ); contentPane.add( toggleAntiAlias, new GridBagConstraints( 4, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 0, 0, 5, 5 ), 0, 0 ) ); contentPane.add( chooseBackgroundColor, new GridBagConstraints( 5, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 0, 0, 5, 5 ), 0, 0 ) ); contentPane.add( chooseForegroundColor, new GridBagConstraints( 6, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 0, 0, 5, 10 ), 0, 0 ) ); contentPane.add( scroller, /* sample chars */ new GridBagConstraints( 0, 2, 7, 1, 100.0, 100.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 0, 10, 10, 10 ), 0, 0 ) ); contentPane.add( allScroller, /* names of all fonts */ new GridBagConstraints( 0, 2, 7, 1, 100.0, 100.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 0, 10, 10, 10 ), 0, 0 ) ); } /** * Allow this Applet to run as as application as well. * * @param args command line arguments ignored. */ public static void main( String args[] ) { HybridJ.fireup( new FontShower(), TITLE_STRING + " " + VERSION_STRING, APPLET_WIDTH, APPLET_HEIGHT ); } // end main /** * Called by the browser or Applet viewer to inform * this Applet that it is being reclaimed and that it should destroy * any resources that it has allocated. */ public void destroy() { about = null; allDisplayArea = null; allScroller = null; chooseBackgroundColor = null; chooseForegroundColor = null; displayArea = null; fontChoices = null; scroller = null; sizeSpinner = null; sizeSpinnerModel = null; title = null; title2 = null; toggleAntiAlias = null; toggleBold = null; toggleItalic = null; } /** * Called by the browser or Applet viewer to inform * this Applet that it has been loaded into the system. */ @Override public void init() { // need 1.3 for Swing if ( !VersionCheck.isJavaVersionOK( 1, 7, 0, this.getContentPane() ) ) { // effectively abort return; } Common18.setLaf(); Container contentPane = this.getContentPane(); contentPane.setLayout( new GridBagLayout() ); contentPane.setBackground( BACKGROUND_FOR_BODY ); buildComponents(); layoutComponents( contentPane ); this.validate(); this.setVisible( true ); } }