001: package net.suberic.util.swing;
002:
003: import java.awt.*;
004: import javax.swing.*;
005: import javax.swing.event.*;
006: import java.awt.event.*;
007:
008: /**
009: * A panel which allows the user to select a Font from the list of all
010: * available fonts on the system.
011: */
012: public class JFontChooser extends JComponent {
013:
014: JList fontList = null;
015: JList styleList = null;
016: JList sizeList = null;
017:
018: JTextArea previewTextArea = null;
019:
020: boolean changing = false;
021:
022: Font originalFont = null;
023:
024: Font selectedFont = null;
025:
026: private static String[] allowedFontSizes = new String[] { "6", "8",
027: "9", "10", "11", "12", "14", "16", "18", "20", "22", "24",
028: "36", "48", "72" };
029:
030: private static String[] allowedFontStyles = new String[] { "Plain",
031: "Italic", "Bold", "Bold Italic" };
032:
033: /**
034: * Creates a new JFontChooser with a default font.
035: */
036: public JFontChooser() {
037: configureChooser(new Font("monospaced", Font.PLAIN, 12),
038: "The quick brown fox jumped over the lazy god [sic].");
039: }
040:
041: /**
042: * Creates a new JFontChooser with the specified font.
043: */
044: public JFontChooser(Font initialFont) {
045: configureChooser(initialFont,
046: "The quick brown fox jumped over the lazy god [sic].");
047: }
048:
049: /**
050: * Creates a new JFontChooser with the given preview phrase and a
051: * default font.
052: */
053: public JFontChooser(String previewPhrase) {
054: configureChooser(new Font("monospaced", Font.PLAIN, 12),
055: previewPhrase);
056: }
057:
058: /**
059: * Creates a new JFontChooser with the specified font and given
060: * preview phrase.
061: */
062: public JFontChooser(Font initialFont, String previewPhrase) {
063: configureChooser(initialFont, previewPhrase);
064: }
065:
066: /**
067: * Creates and returns a new dialog containing the specified
068: * FontChooser pane along with "OK", "Cancel", and "Reset"
069: * buttons.
070: */
071: public static JDialog createDialog(Component parent, String title,
072: boolean modal, JFontChooser chooserPane,
073: ActionListener okListener, ActionListener cancelListener) {
074: JDialog returnValue = new JDialog(JOptionPane
075: .getFrameForComponent(parent), title, modal);
076:
077: returnValue.getContentPane().setLayout(
078: new BoxLayout(returnValue.getContentPane(),
079: BoxLayout.Y_AXIS));
080: returnValue.getContentPane().add(chooserPane);
081: returnValue.getContentPane().add(
082: chooserPane.createButtonPanel(okListener,
083: cancelListener, returnValue));
084: Container cp = returnValue.getContentPane();
085: if (cp instanceof JComponent) {
086: ((JComponent) cp).setBorder(BorderFactory
087: .createEtchedBorder());
088: }
089: return returnValue;
090: }
091:
092: /**
093: * Returns the currently selected Font.
094: */
095: public Font getFont() {
096: return previewTextArea.getFont();
097: }
098:
099: /**
100: * Returns the currently selected Font in a String form which is
101: * compatible with <code>Font.decode(String)</code>.
102: */
103: public String getFontString() {
104: return encodeFont(getFont());
105: }
106:
107: /**
108: * Encodes the given Font in a String form which is
109: * compatible with <code>Font.decode(String)</code>.
110: */
111: public static String encodeFont(Font f) {
112: StringBuffer returnBuffer = new StringBuffer();
113: returnBuffer.append(f.getName());
114: returnBuffer.append('-');
115: returnBuffer.append(getFontStyle(f));
116: returnBuffer.append('-');
117: returnBuffer.append(f.getSize());
118: return returnBuffer.toString();
119: }
120:
121: /**
122: * Sets the currently selected Font to the given Font.
123: */
124: public void setFont(Font newFont) {
125: changing = true;
126:
127: if (previewTextArea != null) {
128: if (newFont != null) {
129: if (fontList != null) {
130: String fontName = newFont.getName();
131: fontList.setSelectedValue(fontName, true);
132: }
133:
134: if (styleList != null) {
135: String style = getFontStyle(newFont);
136: if (style != null && style == "BoldItalic")
137: styleList.setSelectedValue("Bold Italic", true);
138: else
139: styleList.setSelectedValue(style, true);
140: }
141:
142: if (sizeList != null) {
143: String size = Integer.toString(newFont.getSize());
144: sizeList.setSelectedValue(size, true);
145: }
146:
147: previewTextArea.setFont(newFont);
148:
149: }
150: }
151: changing = false;
152:
153: }
154:
155: /**
156: * Gets the Font style as a String.
157: */
158: public static String getFontStyle(Font f) {
159: int style = f.getStyle();
160:
161: if (style == Font.PLAIN)
162: return (allowedFontStyles[0]);
163: else if (style == Font.BOLD)
164: return (allowedFontStyles[1]);
165: else if (style == Font.ITALIC)
166: return (allowedFontStyles[2]);
167: else if (style == Font.BOLD + Font.ITALIC)
168: return (allowedFontStyles[3]);
169: else
170: return (allowedFontStyles[0]);
171: }
172:
173: /**
174: * Shows a modal font-chooser dialog and blocks until the
175: * dialog is hidden. If the user presses the "OK" button, then
176: * this method hides/disposes the dialog and returns the selected font.
177: * If the user presses the "Cancel" button or closes the dialog without
178: * pressing "OK", then this method hides/disposes the dialog and returns
179: * null.
180: */
181: public static Font showDialog(Component component, String title,
182: Font initialFont) {
183:
184: final JFontChooser jfc = new JFontChooser(initialFont);
185: ActionListener okListener = new ActionListener() {
186: public void actionPerformed(ActionEvent e) {
187: Font currentFont = jfc.getFont();
188: jfc.setSelectedFont(currentFont);
189: }
190: };
191:
192: JDialog dialog = createDialog(component, title, true, jfc,
193: okListener, null);
194:
195: dialog.pack();
196: dialog.setVisible(true);
197:
198: return jfc.getSelectedFont();
199: }
200:
201: /**
202: * Shows a modal font-chooser dialog and blocks until the
203: * dialog is hidden. If the user presses the "OK" button, then
204: * this method hides/disposes the dialog and returns the String
205: * representation of the selected Font.
206: * If the user presses the "Cancel" button or closes the dialog without
207: * pressing "OK", then this method hides/disposes the dialog and returns
208: * null.
209: */
210: public static String showStringDialog(Component component,
211: String title, Font initialFont) {
212: Font selectedFont = showDialog(component, title, initialFont);
213: if (selectedFont != null) {
214: return encodeFont(selectedFont);
215: }
216:
217: return null;
218: }
219:
220: /* private functions */
221:
222: /**
223: * Configures a new JFontChooser.
224: */
225: private void configureChooser(Font f, String previewString) {
226: originalFont = f;
227: Box mainBox = Box.createVerticalBox();
228: mainBox.add(createChooserPanel(f));
229: mainBox.add(Box.createVerticalStrut(10));
230: mainBox.add(createPreviewPanel(f, previewString));
231: setFont(f);
232: this .setLayout(new BorderLayout());
233: this .add(mainBox, BorderLayout.CENTER);
234: //this.pack();
235: }
236:
237: /**
238: * Creates the Chooser panel.
239: */
240: private Component createChooserPanel(Font f) {
241: JPanel returnValue = new JPanel();
242:
243: ListSelectionListener changeListener = new ListSelectionListener() {
244: public void valueChanged(ListSelectionEvent lse) {
245: if (!changing)
246: fontSelectionChanged();
247: }
248: };
249:
250: Box chooser = Box.createHorizontalBox();
251:
252: Box fontBox = Box.createVerticalBox();
253: fontBox.add(new JLabel("Font"));
254: fontList = new JList(getFontNames());
255: fontList.addListSelectionListener(changeListener);
256: JScrollPane fontNameScroller = new JScrollPane(fontList);
257: fontBox.add(fontNameScroller);
258:
259: chooser.add(fontBox);
260: chooser.add(Box.createHorizontalStrut(15));
261:
262: Box styleBox = Box.createVerticalBox();
263: styleBox.add(new JLabel("Font Style"));
264: styleList = new JList(getStyleNames());
265: styleList.addListSelectionListener(changeListener);
266: JScrollPane styleScroller = new JScrollPane(styleList);
267: styleBox.add(styleScroller);
268:
269: chooser.add(styleBox);
270: chooser.add(Box.createHorizontalStrut(15));
271:
272: Box sizeBox = Box.createVerticalBox();
273: sizeBox.add(new JLabel("Size"));
274: sizeList = new JList(getSizeNames());
275: sizeList.addListSelectionListener(changeListener);
276: JScrollPane sizeScroller = new JScrollPane(sizeList);
277: sizeBox.add(sizeScroller);
278:
279: chooser.add(sizeBox);
280:
281: returnValue.add(chooser);
282: returnValue.setBorder(BorderFactory.createEtchedBorder());
283:
284: return returnValue;
285: }
286:
287: /**
288: * Creates the preview panel.
289: */
290: private Component createPreviewPanel(Font f, String previewText) {
291: previewTextArea = new JTextArea(previewText);
292: previewTextArea.setFont(f);
293: JPanel returnValue = new JPanel();
294: returnValue.add(previewTextArea);
295:
296: returnValue.setBorder(BorderFactory.createEtchedBorder());
297: returnValue.setMinimumSize(new java.awt.Dimension(50, 50));
298:
299: return returnValue;
300: }
301:
302: private Component createButtonPanel(ActionListener okListener,
303: ActionListener cancelListener, JDialog newDialog) {
304: final JDialog dialog = newDialog;
305: JPanel returnValue = new JPanel();
306: returnValue.setLayout(new FlowLayout(FlowLayout.CENTER));
307:
308: JButton okButton = new JButton("OK");
309:
310: if (okListener != null)
311: okButton.addActionListener(okListener);
312:
313: okButton.addActionListener(new ActionListener() {
314: public void actionPerformed(ActionEvent e) {
315: dialog.setVisible(false);
316: }
317: });
318:
319: JButton cancelButton = new JButton("Cancel");
320: cancelButton.addActionListener(cancelListener);
321:
322: cancelButton.addActionListener(new ActionListener() {
323: public void actionPerformed(ActionEvent e) {
324: dialog.setVisible(false);
325: }
326: });
327:
328: JButton resetButton = new JButton("Reset");
329: resetButton.addActionListener(new ActionListener() {
330: public void actionPerformed(ActionEvent e) {
331: reset();
332: }
333: });
334:
335: returnValue.add(okButton);
336: returnValue.add(resetButton);
337: returnValue.add(cancelButton);
338:
339: getRootPane().setDefaultButton(okButton);
340:
341: returnValue.setBorder(BorderFactory.createEtchedBorder());
342:
343: return returnValue;
344: }
345:
346: /**
347: * Resets the font to the original font.
348: */
349: public void reset() {
350: setFont(originalFont);
351: }
352:
353: /**
354: * called when any of the JLists change.
355: */
356: protected void fontSelectionChanged() {
357: Font currentFont = previewTextArea.getFont();
358:
359: String fontName = (String) fontList.getSelectedValue();
360: String styleString = (String) styleList.getSelectedValue();
361: String sizeString = (String) sizeList.getSelectedValue();
362:
363: if (fontName == null || fontName.length() == 0) {
364: fontName = currentFont.getFontName();
365: }
366:
367: int style = currentFont.getStyle();
368: if (styleString != null) {
369: if (styleString.equalsIgnoreCase("plain"))
370: style = Font.PLAIN;
371: else if (styleString.equalsIgnoreCase("bold"))
372: style = Font.BOLD;
373: else if (styleString.equalsIgnoreCase("italic"))
374: style = Font.ITALIC;
375: else if (styleString.equalsIgnoreCase("bold italic"))
376: style = Font.BOLD + Font.ITALIC;
377: }
378:
379: int size = currentFont.getSize();
380: if (sizeString != null) {
381: try {
382: size = Integer.parseInt(sizeString);
383: } catch (Exception e) {
384: }
385: }
386:
387: Font newFont = new Font(fontName, style, size);
388:
389: previewTextArea.setFont(newFont);
390: SwingUtilities.windowForComponent(this ).pack();
391: }
392:
393: /**
394: * Gets all of the available font names.
395: */
396: private String[] getFontNames() {
397: return GraphicsEnvironment.getLocalGraphicsEnvironment()
398: .getAvailableFontFamilyNames();
399: }
400:
401: /**
402: * Gets all of the available styles.
403: */
404: private String[] getStyleNames() {
405: return allowedFontStyles;
406: }
407:
408: /**
409: * Gets all of the available sizes.
410: */
411: private String[] getSizeNames() {
412: return allowedFontSizes;
413: }
414:
415: /**
416: * Gets the font selected by the chooser. if 'cancel' was pressed,
417: * then no font is selected.
418: */
419: public Font getSelectedFont() {
420: return selectedFont;
421: }
422:
423: /**
424: * Sets the font selected by the chooser. this should be called when
425: * the 'ok' button is presed.
426: */
427: public void setSelectedFont(Font newFont) {
428: selectedFont = newFont;
429: }
430: }
|