|
001 package examples.fontfinder;
002 //start auto-imports
003 import java.awt.*;
004 import java.awt.geom.*;
005 //end auto-imports
006
007 import fang.*;
008
009 /**This class displays all of the
010 * fonts available on the computer.
011 * @author Jam Jenkins
012 */
013 public class FontFinder extends Game
014 implements Runnable
015 {
016 /**loading message*/
017 private StringSprite loadingMessage;
018
019 /**true while the sprites are still being made*/
020 private boolean loading;
021
022 /**the large box at the bottom
023 * of the screen*/
024 private Sprite scroll;
025 /**the position indicator in the
026 * larger box*/
027 private Sprite bar;
028
029 /**the string sprite corresponding
030 * to a given font family name*/
031 private PrettyStringSprite[] text;
032 /**the names of all the font
033 * family names*/
034 private String[] loadedFonts;
035 /**how many sprites to display
036 * at once on the screen*/
037 private int textLines=10;
038
039 /**the previous and next StringSprite
040 * style buttons*/
041 private ButtonSprite[] buttons;
042 /**the current position in the
043 * array of font names*/
044 private int index=0;
045
046 /**the current drag position if scrolling*/
047 private Location2D drag;
048
049 /**makes and adds the sprites to the
050 * canvas. This also sets a subset
051 * of the sprites visible. Making the
052 * sprites takes some time, so this is
053 * done in a separate thread. Once the
054 * sprites have been made, they are
055 * added in the advanceFrame method.
056 * The sprites cannot be added in the
057 * separate thread because this may cause
058 * a concurrent modification exception.
059 * The sprites can however be made in
060 * the separate thread because they are
061 * not part of any collection yet.*/
062 public void setup()
063 {
064 loadingMessage=new StringSprite("Loading: 00%");
065 loadingMessage.setWidth(0.9);
066 loadingMessage.setLocation(0.05, 0.5);
067 loadingMessage.leftJustify();
068 addSprite(loadingMessage);
069 setHelp("resources/FontFinderHelp.txt");
070 loading=true;
071 new Thread(this).start();
072 }
073
074 /**
075 * makes the sprites
076 */
077 public void run()
078 {
079 loadedFonts=getLoadedFonts();
080 makeSprites();
081 loading=false;
082 }
083
084 /**makes the scrollbar*/
085 private void makeScrollbar()
086 {
087 scroll=new RectangleSprite(0.33, 0.033);
088 scroll.setLocation(0.5,
089 (textLines+0.5)/
090 (textLines+1));
091 bar=new RectangleSprite(scroll.getSize()*0.1, scroll.getSize()*0.1);
092 bar.setLocation(
093 scroll.getX()-scroll.getSize()/2+
094 index*scroll.getSize()/loadedFonts.length,
095 scroll.getY());
096 bar.setColor(getColor("red"));
097 }
098
099 /**makes the next and previous buttons*/
100 private void makeButtons()
101 {
102 buttons=new ButtonSprite[2];
103 buttons[0]=new ButtonSprite("Previous");
104 buttons[1]=new ButtonSprite("Previous");
105 buttons[1].setText("Next");
106 buttons[0].setSize(0.2);
107 buttons[1].setSize(0.2);
108 buttons[0].setLocation(0.1, 0.95);
109 buttons[1].setLocation(0.9, 0.95);
110 }
111
112 /**makes the Sprites representing the fonts*/
113 private void makeTextSprites()
114 {
115 text=new PrettyStringSprite[loadedFonts.length];
116 for(int i=0; i<loadedFonts.length; i++)
117 {
118 int percent=(int)(i*100.0/loadedFonts.length);
119 loadingMessage.setText("Loading: "+percent+"%");
120 canvas.paintImmediately(canvas.getBounds());
121 text[i]=new PrettyStringSprite(
122 loadedFonts[index], true);
123 text[i].setFontFamilyName(loadedFonts[index]);
124 index=(index+1)%loadedFonts.length;
125 text[i].setHeight(
126 1.0/(textLines+1));
127 if(text[i].getWidth()>0.9)
128 text[i].scale(
129 0.9/
130 text[i].getWidth());
131 text[i].topJustify();
132 text[i].setVisible(false);
133 }
134 loadingMessage.setText("Loaded\n\nClick on\nStart");
135 canvas.paintImmediately(canvas.getBounds());
136 }
137
138 /**gets all the fonts family names
139 * available on the computer
140 * @return the names of font families*/
141 private String[] getLoadedFonts()
142 {
143 GraphicsEnvironment environment;
144 environment=GraphicsEnvironment.getLocalGraphicsEnvironment();
145 return environment.getAvailableFontFamilyNames();
146
147 }
148
149 /**makes all of the sprites.*/
150 private void makeSprites()
151 {
152 makeTextSprites();
153 makeButtons();
154 makeScrollbar();
155 index=0;
156 updateFonts(0);
157 }
158
159 /**adds all of the sprites to the screen*/
160 private void addSprites()
161 {
162 for(Sprite sprite: text)
163 addSprite(sprite);
164 for(Sprite sprite: buttons)
165 addSprite(sprite);
166 canvas.addSprite(scroll);
167 canvas.addSprite(bar);
168 }
169
170 /**makes the next set of fonts visible
171 * @param direction where the next set
172 * of fonts should be drawn from. Zero
173 * indicates they should come from the
174 * current location, 1 means they should
175 * come from the next locations, and -1
176 * means they should come from the
177 * previous locations.*/
178 private void updateFonts(int direction)
179 {
180 index+=direction*textLines+loadedFonts.length;
181 index=index%loadedFonts.length;
182 for(PrettyStringSprite t: text)
183 t.setVisible(false);
184 for(int i=0; i<textLines; i++)
185 {
186 text[(index+i)%text.length].setVisible(true);
187 text[(index+i)%text.length].setLocation(
188 0.5,
189 i*1.0/(textLines+1));
190 }
191 bar.setLocation(
192 scroll.getX()-scroll.getSize()/2+
193 index*scroll.getSize()/loadedFonts.length,
194 scroll.getY());
195 }
196
197 /**checks for clicks*/
198 public void advance(double timeAdvanced)
199 {
200 if(!loading)
201 {
202 removeSprite(loadingMessage);
203 addSprites();
204 }
205 Location2D click=getClick2D();
206 if(drag!=null ||
207 click!=null &&
208 scroll.intersects(click))
209 drag=getMouse2D();
210 if(!mousePressed())
211 drag=null;
212 if(drag!=null)
213 {
214 double width=scroll.getSize();
215 double start=scroll.getX()-width/2;
216 //keeps the drage position within the scrollbar
217 double dragPosition=Math.max(drag.x, start);
218 dragPosition=Math.min(dragPosition, start+width);
219 double fromLeft=dragPosition-start;
220 index=(int)(fromLeft*loadedFonts.length/width);
221 updateFonts(0);
222 }
223 if(click!=null)
224 {
225 if(buttons[0].intersects(click))
226 {
227 updateFonts(-1);
228 }
229 if(buttons[1].intersects(click))
230 {
231 updateFonts(1);
232 }
233 }
234 }
235
236 /**runs font finder as an application
237 * @param args not used*/
238 public static void main(String[] args)
239 {
240 FontFinder finder=new FontFinder();
241 finder.runAsApplication();
242 }
243 }
|