KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sshtools > ui > swing > FontChooser


1 /*
2
3  * Gruntspud
4
5  *
6
7  * Copyright (C) 2002 Brett Smith.
8
9  *
10
11  * Written by: Brett Smith <t_magicthize@users.sourceforge.net>
12
13  *
14
15  * This program is free software; you can redistribute it and/or
16
17  * modify it under the terms of the GNU Library General Public License
18
19  * as published by the Free Software Foundation; either version 2 of
20
21  * the License, or (at your option) any later version.
22
23  * This program is distributed in the hope that it will be useful,
24
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28
29  * GNU Library General Public License for more details.
30
31  *
32
33  * You should have received a copy of the GNU Library General Public
34
35  * License along with this program; if not, write to the Free Software
36
37  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
38
39  */

40
41
42
43 package com.sshtools.ui.swing;
44
45
46
47 import java.awt.BorderLayout JavaDoc;
48
49 import java.awt.Color JavaDoc;
50
51 import java.awt.Component JavaDoc;
52
53 import java.awt.Dimension JavaDoc;
54
55 import java.awt.Font JavaDoc;
56
57 import java.awt.FontMetrics JavaDoc;
58
59 import java.awt.GraphicsEnvironment JavaDoc;
60
61 import java.awt.GridBagConstraints JavaDoc;
62
63 import java.awt.GridBagLayout JavaDoc;
64
65 import java.awt.Insets JavaDoc;
66
67 import java.awt.event.ActionEvent JavaDoc;
68
69 import java.awt.event.ActionListener JavaDoc;
70
71 import java.util.Vector JavaDoc;
72
73 import javax.swing.AbstractListModel JavaDoc;
74
75 import javax.swing.BorderFactory JavaDoc;
76
77 import javax.swing.DefaultListCellRenderer JavaDoc;
78
79 import javax.swing.JCheckBox JavaDoc;
80
81 import javax.swing.JComponent JavaDoc;
82
83 import javax.swing.JFormattedTextField JavaDoc;
84
85 import javax.swing.JLabel JavaDoc;
86
87 import javax.swing.JList JavaDoc;
88
89 import javax.swing.JOptionPane JavaDoc;
90
91 import javax.swing.JPanel JavaDoc;
92
93 import javax.swing.JScrollPane JavaDoc;
94
95 import javax.swing.JTextField JavaDoc;
96
97 import javax.swing.SwingConstants JavaDoc;
98
99 import javax.swing.UIManager JavaDoc;
100
101 import javax.swing.event.DocumentEvent JavaDoc;
102
103 import javax.swing.event.DocumentListener JavaDoc;
104
105 import javax.swing.event.ListSelectionEvent JavaDoc;
106
107 import javax.swing.event.ListSelectionListener JavaDoc;
108
109 import com.sshtools.ui.swing.UIUtil;
110
111
112
113 /**
114
115  * Choose a font
116
117  *
118
119  * @author Brett Smith
120
121  */

122
123 public class FontChooser
124
125     extends JPanel JavaDoc {
126
127     private static FontNameListModel fontNameListModel;
128
129     private JList JavaDoc fontNameList;
130
131     private JList JavaDoc fontSizeList;
132
133     private JTextField JavaDoc fontName;
134
135     private Font JavaDoc chosenFont;
136
137     private JCheckBox JavaDoc bold;
138
139     private JCheckBox JavaDoc italic;
140
141     private JFormattedTextField JavaDoc fontSize;
142
143     private JLabel JavaDoc preview;
144
145     private boolean adjusting;
146
147
148
149     /**
150
151      * Construct a <code>FontChooser</code>
152
153      *
154
155      * @param none
156
157      */

158
159     public FontChooser() {
160
161         this(null, true, false);
162
163     }
164
165
166
167     /**
168
169      * Construct a <code>FontChooser</code>
170
171      *
172
173      * @param font initiali font
174
175      */

176
177     public FontChooser(Font JavaDoc font, boolean showSize, boolean monospacedOnly) {
178
179         super(new BorderLayout JavaDoc());
180
181
182
183         // Lazily create the font list name model
184

185         if (fontNameListModel == null) {
186
187             fontNameListModel = new FontNameListModel(monospacedOnly);
188
189
190
191             // Create the name list
192

193         }
194
195         fontNameList = new JList JavaDoc(fontNameListModel);
196
197         fontNameList.setCellRenderer(new FontNameListCellRenderer());
198
199         fontNameList.setVisibleRowCount(7);
200
201 // fontNameList.setAutoscrolls(true);
202

203         fontNameList.addListSelectionListener(new ListSelectionListener JavaDoc() {
204
205             public void valueChanged(ListSelectionEvent JavaDoc e) {
206
207                 if (!fontNameList.isSelectionEmpty() &&
208
209                     !e.getValueIsAdjusting()) {
210
211                     try {
212
213                         adjusting = true;
214
215                         fontName.setText( ( (Font JavaDoc) fontNameList.
216
217                                            getSelectedValue()).getName());
218
219                     }
220
221                     catch (IllegalStateException JavaDoc iee) {
222
223                     }
224
225                     adjusting = false;
226
227
228
229                     changeFontBasedOnState();
230
231                 }
232
233             }
234
235         });
236
237
238
239         // Create the font style selection panel
240

241         JPanel JavaDoc stylePanel = new JPanel JavaDoc(new GridBagLayout JavaDoc());
242
243         stylePanel.setBorder(BorderFactory.createTitledBorder("Font style"));
244
245
246
247         GridBagConstraints JavaDoc gBC = new GridBagConstraints JavaDoc();
248
249         gBC.fill = GridBagConstraints.BOTH;
250
251         gBC.anchor = GridBagConstraints.CENTER;
252
253         gBC.weighty = 0.0;
254
255         gBC.insets = new Insets JavaDoc(2, 2, 2, 2);
256
257
258
259         ActionListener JavaDoc l = new ActionListener JavaDoc() {
260
261             public void actionPerformed(ActionEvent JavaDoc evt) {
262
263                 changeFontBasedOnState();
264
265             }
266
267         };
268
269
270
271         UIUtil.jGridBagAdd(stylePanel, bold = new JCheckBox JavaDoc("Bold"), gBC,
272
273                            GridBagConstraints.REMAINDER);
274
275         bold.addActionListener(l);
276
277         bold.setMnemonic('b');
278
279         UIUtil.jGridBagAdd(stylePanel, italic = new JCheckBox JavaDoc("Italic"), gBC,
280
281                            GridBagConstraints.REMAINDER);
282
283         italic.setMnemonic('i');
284
285         italic.addActionListener(l);
286
287
288
289         // Create the font size list
290

291         // @todo make this more specific to the font. not sure how yet :-)
292

293         JPanel JavaDoc sizePanel = null;
294
295         if(showSize) {
296
297             fontSizeList = new JList JavaDoc(new Integer JavaDoc[] {
298
299                                      new Integer JavaDoc(8), new Integer JavaDoc(9), new Integer JavaDoc(10),
300
301                                      new Integer JavaDoc(11), new Integer JavaDoc(12),
302
303                                      new Integer JavaDoc(14),
304
305                                      new Integer JavaDoc(16), new Integer JavaDoc(18),
306
307                                      new Integer JavaDoc(20),
308
309                                      new Integer JavaDoc(22), new Integer JavaDoc(24),
310
311                                      new Integer JavaDoc(26),
312
313                                      new Integer JavaDoc(28), new Integer JavaDoc(36),
314
315                                      new Integer JavaDoc(48),
316
317                                      new Integer JavaDoc(72)
318
319             });
320
321             fontSizeList.setVisibleRowCount(4);
322
323             fontSizeList.setAutoscrolls(true);
324
325             fontSizeList.addListSelectionListener(new ListSelectionListener JavaDoc() {
326
327                 public void valueChanged(ListSelectionEvent JavaDoc e) {
328
329                     if (!fontNameList.isSelectionEmpty() &&
330
331                         !e.getValueIsAdjusting()) {
332
333                         try {
334
335                             fontSize.setValue( ( (Integer JavaDoc) fontSizeList.
336
337                                                 getSelectedValue()));
338
339                         }
340
341                         catch (IllegalStateException JavaDoc iee) {
342
343                         }
344
345     
346
347                         changeFontBasedOnState();
348
349                     }
350
351                 }
352
353             });
354
355     
356
357             // Create the font size selection panel
358

359             sizePanel = new JPanel JavaDoc(new GridBagLayout JavaDoc());
360
361             sizePanel.setBorder(BorderFactory.createTitledBorder("Font size"));
362
363
364
365
366
367             GridBagConstraints JavaDoc gBC3 = new GridBagConstraints JavaDoc();
368
369             gBC3.fill = GridBagConstraints.BOTH;
370
371             gBC3.anchor = GridBagConstraints.WEST;
372
373             gBC3.weightx = 1.0;
374
375             gBC3.weighty = 0.0;
376
377             gBC3.insets = new Insets JavaDoc(2, 2, 2, 2);
378
379             UIUtil.jGridBagAdd(sizePanel, new JLabel JavaDoc("Size:"), gBC3,
380
381                                GridBagConstraints.REMAINDER);
382
383             UIUtil.jGridBagAdd(sizePanel,
384
385                                fontSize = new JFormattedTextField JavaDoc(new Integer JavaDoc(4)),
386
387                                gBC3, GridBagConstraints.REMAINDER);
388
389             fontSize.getDocument().addDocumentListener(new DocumentListener JavaDoc() {
390
391                 public void insertUpdate(DocumentEvent JavaDoc e) {
392
393                     changeFontBasedOnState();
394
395                 }
396
397
398
399                 public void removeUpdate(DocumentEvent JavaDoc e) {
400
401                     changeFontBasedOnState();
402
403                 }
404
405
406
407                 public void changedUpdate(DocumentEvent JavaDoc e) {
408
409                     changeFontBasedOnState();
410
411                 }
412
413             });
414
415             gBC3.weighty = 1.0;
416
417             UIUtil.jGridBagAdd(sizePanel, new JScrollPane JavaDoc(fontSizeList), gBC3,
418
419                                GridBagConstraints.REMAINDER);
420
421         }
422
423
424
425         // Create the panel where selection of the font name takes place
426

427         JPanel JavaDoc namePanel = new JPanel JavaDoc(new GridBagLayout JavaDoc());
428
429         namePanel.setBorder(BorderFactory.createTitledBorder("Font name"));
430
431
432
433         GridBagConstraints JavaDoc gBC2 = new GridBagConstraints JavaDoc();
434
435         gBC2.fill = GridBagConstraints.BOTH;
436
437         gBC2.anchor = GridBagConstraints.WEST;
438
439         gBC2.weightx = 1.0;
440
441         gBC2.weighty = 0.0;
442
443         gBC2.insets = new Insets JavaDoc(2, 2, 2, 2);
444
445         UIUtil.jGridBagAdd(namePanel, new JLabel JavaDoc("Name:"), gBC2,
446
447                            GridBagConstraints.REMAINDER);
448
449         UIUtil.jGridBagAdd(namePanel, fontName = new JTextField JavaDoc(10), gBC2,
450
451                            GridBagConstraints.REMAINDER);
452
453         gBC2.weighty = 1.0;
454
455         UIUtil.jGridBagAdd(namePanel, new JScrollPane JavaDoc(fontNameList), gBC2,
456
457                            GridBagConstraints.REMAINDER);
458
459
460
461         // Create the preview label
462

463         preview = new JLabel JavaDoc("Some sample text") {
464
465             public Dimension JavaDoc getMinimumSize() {
466
467                 return new Dimension JavaDoc(super.getMinimumSize().width, 64);
468
469             }
470
471
472
473             public Dimension JavaDoc getPreferredSize() {
474
475                 return new Dimension JavaDoc(320, 64);
476
477             }
478
479         };
480
481         preview.setBackground(Color.white);
482
483         preview.setForeground(Color.black);
484
485         preview.setOpaque(true);
486
487         preview.setHorizontalAlignment(SwingConstants.CENTER);
488
489         preview.setBorder(BorderFactory.createLineBorder(Color.black));
490
491
492
493         // Create the preview panel
494

495         JPanel JavaDoc previewPanel = new JPanel JavaDoc(new BorderLayout JavaDoc());
496
497         previewPanel.setBorder(BorderFactory.createTitledBorder("Preview"));
498
499         previewPanel.add(preview, BorderLayout.CENTER);
500
501
502
503         // Create the right panel
504

505         JPanel JavaDoc rightPanel = new JPanel JavaDoc(new BorderLayout JavaDoc());
506
507         rightPanel.add(stylePanel, BorderLayout.NORTH);
508
509         if(sizePanel != null) {
510
511             rightPanel.add(sizePanel, BorderLayout.CENTER);
512
513         }
514
515
516
517         // Listen for changes in the font name and select the closest font in
518

519         // the list
520

521         fontName.getDocument().addDocumentListener(new DocumentListener JavaDoc() {
522
523             public void insertUpdate(DocumentEvent JavaDoc e) {
524
525                 if(!adjusting) {
526
527                     findClosestFont();
528
529                 }
530
531             }
532
533
534
535             public void removeUpdate(DocumentEvent JavaDoc e) {
536
537                 if(!adjusting) {
538
539                     findClosestFont();
540
541                 }
542
543             }
544
545
546
547             public void changedUpdate(DocumentEvent JavaDoc e) {
548
549                 if(!adjusting) {
550
551                     findClosestFont();
552
553                 }
554
555             }
556
557         });
558
559
560
561         //
562

563         add(namePanel, BorderLayout.CENTER);
564
565         add(rightPanel, BorderLayout.EAST);
566
567         add(previewPanel, BorderLayout.SOUTH);
568
569
570
571         // Create the panel where the font name may be selected
572

573         setChosenFont(font);
574
575     }
576
577
578
579     private void findClosestFont() {
580
581         for (int i = 0; i < fontNameList.getModel().getSize(); i++) {
582
583             Font JavaDoc f = (Font JavaDoc) fontNameList.getModel().getElementAt(i);
584
585
586
587             if (f.getName().toLowerCase().startsWith(fontName.getText()
588
589                 .toLowerCase())) {
590
591                 if(fontNameList.getSelectedIndex() != i) {
592
593                     fontNameList.setSelectedIndex(i);
594
595                     fontNameList.scrollRectToVisible(fontNameList.getCellBounds(i,
596
597                         i));
598
599                     changeFontBasedOnState();
600
601                 }
602
603
604
605                 break;
606
607             }
608
609         }
610
611     }
612
613
614
615     private void changeFontBasedOnState() {
616
617         Font JavaDoc f = ( (Font JavaDoc) fontNameList.getSelectedValue());
618
619
620
621         if (f != null) {
622
623             int size = fontSize == null ? ( chosenFont == null ? 12 : chosenFont.getSize() ) : ((Integer JavaDoc)fontSize.getValue()).intValue();
624
625             int style = (bold.isSelected() ? Font.BOLD : 0) |
626
627                 (italic.isSelected() ? Font.ITALIC : 0);
628
629             chosenFont = new Font JavaDoc(f.getName(), style, size);
630
631             preview.setFont(chosenFont);
632
633         }
634
635     }
636
637
638
639     /**
640
641      * Set the currently chosen font
642
643      *
644
645      * @param font font
646
647      */

648
649     public void setChosenFont(Font JavaDoc f) {
650
651         // We cant have a null font, so default to the one for JLabel
652

653         if (f == null) {
654
655             f = UIManager.getFont("Label.font");
656
657
658
659             // Sort out the selections
660

661         }
662
663         fontName.setText(f.getName());
664
665         findClosestFont();
666
667         if(fontSize != null) {
668
669             fontSize.setValue(new Integer JavaDoc(f.getSize()));
670
671         }
672
673         bold.setSelected(f.isBold());
674
675         italic.setSelected(f.isItalic());
676
677         chosenFont = f;
678
679         preview.setFont(f);
680
681     }
682
683
684
685     /**
686
687      * Get the currently chosen font
688
689      *
690
691      * @return font font
692
693      */

694
695     public Font JavaDoc getChosenFont() {
696
697         return chosenFont;
698
699     }
700
701
702
703     /**
704
705      * Show a chooser dialog
706
707      */

708
709     public static Font JavaDoc showDialog(JComponent JavaDoc parent, Font JavaDoc initialFont) {
710
711         return showDialog(parent, initialFont, true, false);
712
713     }
714
715         /**
716
717          * Show a chooser dialog
718
719          */

720
721     public static Font JavaDoc showDialog(JComponent JavaDoc parent, Font JavaDoc initialFont, boolean showSize, boolean monospacedOnly) {
722
723         // Create the font chooser
724

725         final FontChooser fc = new FontChooser(initialFont, showSize, monospacedOnly);
726
727         fc.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
728
729         if(JOptionPane.showConfirmDialog(parent, fc, "Choose Font", JOptionPane.OK_CANCEL_OPTION) ==
730
731             JOptionPane.OK_OPTION) {
732
733             return fc.getChosenFont();
734
735             
736
737         }
738
739         return null;
740
741     }
742
743
744
745     // font name list model
746

747     class FontNameListModel
748
749         extends AbstractListModel JavaDoc
750
751         implements Runnable JavaDoc {
752
753         private Vector JavaDoc fonts;
754
755         private boolean monospacedOnly;
756
757
758
759         FontNameListModel(boolean monospacedOnly) {
760
761             fonts = new Vector JavaDoc();
762
763             this.monospacedOnly = monospacedOnly;
764
765
766
767             Thread JavaDoc t = new Thread JavaDoc(this);
768
769             t.start();
770
771         }
772
773
774
775         public void run() {
776
777             Font JavaDoc[] f = GraphicsEnvironment.getLocalGraphicsEnvironment()
778
779                 .getAllFonts();
780
781
782
783             for (int i = 0; i < f.length; i++) {
784
785                 if(!monospacedOnly || isMonospaced(f[i])) {
786
787                     fonts.addElement(f[i]);
788
789                 }
790
791
792
793             }
794
795             fireContentsChanged(this, 0, getSize() - 1);
796
797         }
798
799         
800
801         boolean isMonospaced(Font JavaDoc f) {
802
803             int width = -1;
804
805             FontMetrics JavaDoc fm = getFontMetrics(f);
806
807             for(char i = ' '; i <= 'z'; i++) {
808
809                 int cw = fm.charWidth(i);
810
811                 if(width == -1 || cw == width) {
812
813                     width = cw;
814
815                 }
816
817                 else {
818
819                     return false;
820
821                 }
822
823             }
824
825             return true;
826
827             
828
829         }
830
831
832
833         public Object JavaDoc getElementAt(int i) {
834
835             return fonts.elementAt(i);
836
837         }
838
839
840
841         public int getSize() {
842
843             return fonts.size();
844
845         }
846
847     }
848
849
850
851     // Render just the font name in the list
852

853     class FontNameListCellRenderer
854
855         extends DefaultListCellRenderer JavaDoc {
856
857         public Component JavaDoc getListCellRendererComponent(JList JavaDoc list, Object JavaDoc value,
858
859             int index, boolean isSelected, boolean cellHasFocus) {
860
861             super.getListCellRendererComponent(list, value, index, isSelected,
862
863                                                cellHasFocus);
864
865             setText( ( (Font JavaDoc) value).getName());
866
867
868
869             return this;
870
871         }
872
873     }
874
875 }
876
877
Popular Tags