]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.spreadsheet.ui/src/org/simantics/spreadsheet/ui/JFontChooser.java
Database backwards compatibility fix for fail-safe import changes
[simantics/platform.git] / bundles / org.simantics.spreadsheet.ui / src / org / simantics / spreadsheet / ui / JFontChooser.java
1 package org.simantics.spreadsheet.ui;
2
3 import java.awt.BorderLayout;
4 import java.awt.Component;
5 import java.awt.Dimension;
6 import java.awt.Font;
7 import java.awt.Frame;
8 import java.awt.GraphicsEnvironment;
9 import java.awt.GridLayout;
10 import java.awt.event.ActionEvent;
11 import java.awt.event.FocusAdapter;
12 import java.awt.event.FocusEvent;
13 import java.awt.event.KeyAdapter;
14 import java.awt.event.KeyEvent;
15 import java.awt.event.WindowAdapter;
16 import java.awt.event.WindowEvent;
17
18 import javax.swing.AbstractAction;
19 import javax.swing.Action;
20 import javax.swing.ActionMap;
21 import javax.swing.BorderFactory;
22 import javax.swing.BoxLayout;
23 import javax.swing.InputMap;
24 import javax.swing.JButton;
25 import javax.swing.JComponent;
26 import javax.swing.JDialog;
27 import javax.swing.JLabel;
28 import javax.swing.JList;
29 import javax.swing.JPanel;
30 import javax.swing.JScrollPane;
31 import javax.swing.JTextField;
32 import javax.swing.KeyStroke;
33 import javax.swing.ListSelectionModel;
34 import javax.swing.SwingUtilities;
35 import javax.swing.border.Border;
36 import javax.swing.event.DocumentEvent;
37 import javax.swing.event.DocumentListener;
38 import javax.swing.event.ListSelectionEvent;
39 import javax.swing.event.ListSelectionListener;
40 import javax.swing.text.BadLocationException;
41 import javax.swing.text.Document;
42 import javax.swing.text.JTextComponent;
43 import javax.swing.text.Position;
44
45 /**
46  * The <code>JFontChooser</code> class is a swing component 
47  * for font selection.
48  * This class has <code>JFileChooser</code> like APIs.
49  * The following code pops up a font chooser dialog.
50  * <pre>
51  *   JFontChooser fontChooser = new JFontChooser();
52  *   int result = fontChooser.showDialog(parent);
53  *   if (result == JFontChooser.OK_OPTION)
54  *   {
55  *      Font font = fontChooser.getSelectedFont(); 
56  *      System.out.println("Selected Font : " + font); 
57  *   }
58  * <pre>
59  **/
60 public class JFontChooser extends JComponent
61 {
62         private static final long serialVersionUID = -8803227254655562584L;
63         // class variables
64     /**
65      * Return value from <code>showDialog()</code>.
66      * @see #showDialog
67      **/
68     public static final int OK_OPTION = 0;
69     /**
70      * Return value from <code>showDialog()</code>.
71      * @see #showDialog
72      **/
73     public static final int CANCEL_OPTION = 1;
74     /**
75      * Return value from <code>showDialog()</code>.
76      * @see #showDialog
77      **/
78     public static final int ERROR_OPTION = -1;
79     private static final Font DEFAULT_SELECTED_FONT = new Font("Serif", Font.PLAIN, 12);
80     private static final Font DEFAULT_FONT = new Font("Dialog", Font.PLAIN, 10);
81     private static final int[] FONT_STYLE_CODES =
82     {
83         Font.PLAIN, Font.BOLD, Font.ITALIC, Font.BOLD | Font.ITALIC
84     };
85     private static final String[] DEFAULT_FONT_SIZE_STRINGS =
86     {
87         "8", "9", "10", "11", "12", "14", "16", "18", "20",
88         "22", "24", "26", "28", "36", "48", "72",
89     };
90
91     // instance variables
92     protected int dialogResultValue = ERROR_OPTION;
93
94
95
96     private String[] fontStyleNames = null;
97     private String[] fontFamilyNames = null;
98     private String[] fontSizeStrings = null;
99     private JTextField fontFamilyTextField = null;
100     private JTextField fontStyleTextField = null;
101     private JTextField fontSizeTextField = null;
102     private JList fontNameList = null;
103     private JList fontStyleList = null;
104     private JList fontSizeList = null;
105     private JPanel fontNamePanel = null;
106     private JPanel fontStylePanel = null;
107     private JPanel fontSizePanel = null;
108     private JPanel samplePanel = null;
109     private JTextField sampleText = null;
110
111     /**
112      * Constructs a <code>JFontChooser</code> object.
113      **/
114     public JFontChooser()
115     {
116         this(DEFAULT_FONT_SIZE_STRINGS);
117     }
118
119     /**
120      * Constructs a <code>JFontChooser</code> object using the given font size array.
121      * @param fontSizeStrings  the array of font size string.
122      **/
123     public JFontChooser(String[] fontSizeStrings)
124     {
125         if (fontSizeStrings == null)
126         {
127             fontSizeStrings = DEFAULT_FONT_SIZE_STRINGS;
128         }
129         this.fontSizeStrings = fontSizeStrings;
130
131         JPanel selectPanel = new JPanel();
132         selectPanel.setLayout(new BoxLayout(selectPanel, BoxLayout.X_AXIS));
133         selectPanel.add(getFontFamilyPanel());
134         selectPanel.add(getFontStylePanel());
135         selectPanel.add(getFontSizePanel());
136
137         JPanel contentsPanel = new JPanel();
138         contentsPanel.setLayout(new GridLayout(2, 1));
139         contentsPanel.add(selectPanel, BorderLayout.NORTH);
140         contentsPanel.add(getSamplePanel(), BorderLayout.CENTER);
141
142         this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
143         this.add(contentsPanel);
144         this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
145         this.setSelectedFont(DEFAULT_SELECTED_FONT);
146     }
147
148     public JTextField getFontFamilyTextField()
149     {
150         if (fontFamilyTextField == null)
151         {
152             fontFamilyTextField = new JTextField();
153             fontFamilyTextField.addFocusListener(
154                 new TextFieldFocusHandlerForTextSelection(fontFamilyTextField));
155             fontFamilyTextField.addKeyListener(
156                 new TextFieldKeyHandlerForListSelectionUpDown(getFontFamilyList()));
157             fontFamilyTextField.getDocument().addDocumentListener(
158                 new ListSearchTextFieldDocumentHandler(getFontFamilyList()));
159             fontFamilyTextField.setFont(DEFAULT_FONT);
160
161         }
162         return fontFamilyTextField;
163     }
164
165     public JTextField getFontStyleTextField()
166     {
167         if (fontStyleTextField == null)
168         {
169             fontStyleTextField = new JTextField();
170             fontStyleTextField.addFocusListener(
171                 new TextFieldFocusHandlerForTextSelection(fontStyleTextField));
172             fontStyleTextField.addKeyListener(
173                 new TextFieldKeyHandlerForListSelectionUpDown(getFontStyleList()));
174             fontStyleTextField.getDocument().addDocumentListener(
175                 new ListSearchTextFieldDocumentHandler(getFontStyleList()));
176             fontStyleTextField.setFont(DEFAULT_FONT);
177         }
178         return fontStyleTextField;
179     }
180
181     public JTextField getFontSizeTextField()
182     {
183         if (fontSizeTextField == null)
184         {
185             fontSizeTextField = new JTextField();
186             fontSizeTextField.addFocusListener(
187                 new TextFieldFocusHandlerForTextSelection(fontSizeTextField));
188             fontSizeTextField.addKeyListener(
189                 new TextFieldKeyHandlerForListSelectionUpDown(getFontSizeList()));
190             fontSizeTextField.getDocument().addDocumentListener(
191                 new ListSearchTextFieldDocumentHandler(getFontSizeList()));
192             fontSizeTextField.setFont(DEFAULT_FONT);
193         }
194         return fontSizeTextField;
195     }
196
197     public JList getFontFamilyList()
198     {
199         if (fontNameList == null)
200         {
201             fontNameList = new JList(getFontFamilies());
202             fontNameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
203             fontNameList.addListSelectionListener(
204                 new ListSelectionHandler(getFontFamilyTextField()));
205             fontNameList.setSelectedIndex(0);
206             fontNameList.setFont(DEFAULT_FONT);
207             fontNameList.setFocusable(false);
208         }
209         return fontNameList;
210     }
211
212     public JList getFontStyleList()
213     {
214         if (fontStyleList == null)
215         {
216             fontStyleList = new JList(getFontStyleNames());
217             fontStyleList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
218             fontStyleList.addListSelectionListener(
219                 new ListSelectionHandler(getFontStyleTextField()));
220             fontStyleList.setSelectedIndex(0);
221             fontStyleList.setFont(DEFAULT_FONT);
222             fontStyleList.setFocusable(false);
223         }
224         return fontStyleList;
225     }
226
227     public JList getFontSizeList()
228     {
229         if (fontSizeList == null)
230         {
231             fontSizeList = new JList(this.fontSizeStrings);
232             fontSizeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
233             fontSizeList.addListSelectionListener(
234                 new ListSelectionHandler(getFontSizeTextField()));
235             fontSizeList.setSelectedIndex(0);
236             fontSizeList.setFont(DEFAULT_FONT);
237             fontSizeList.setFocusable(false);
238         }
239         return fontSizeList;
240     }
241
242     /**
243      * Get the family name of the selected font.
244      * @return  the font family of the selected font.
245      *
246      * @see #setSelectedFontFamily
247      **/
248     public String getSelectedFontFamily()
249     {
250         String fontName = (String) getFontFamilyList().getSelectedValue();
251         return fontName;
252     }
253
254     /**
255      * Get the style of the selected font.
256      * @return  the style of the selected font.
257      *          <code>Font.PLAIN</code>, <code>Font.BOLD</code>,
258      *          <code>Font.ITALIC</code>, <code>Font.BOLD|Font.ITALIC</code>
259      *
260      * @see java.awt.Font#PLAIN
261      * @see java.awt.Font#BOLD
262      * @see java.awt.Font#ITALIC
263      * @see #setSelectedFontStyle
264      **/
265     public int getSelectedFontStyle()
266     {
267         int index = getFontStyleList().getSelectedIndex();
268         return FONT_STYLE_CODES[index];
269     }
270
271     /**
272      * Get the size of the selected font.
273      * @return  the size of the selected font
274      *
275      * @see #setSelectedFontSize
276      **/
277     public int getSelectedFontSize()
278     {
279         int fontSize = 1;
280         String fontSizeString = getFontSizeTextField().getText();
281         while (true)
282         {
283             try
284             {
285                 fontSize = Integer.parseInt(fontSizeString);
286                 break;
287             }
288             catch (NumberFormatException e)
289             {
290                 fontSizeString = (String) getFontSizeList().getSelectedValue();
291                 getFontSizeTextField().setText(fontSizeString);
292             }
293         }
294
295         return fontSize;
296     }
297
298     /**
299      * Get the selected font.
300      * @return  the selected font
301      *
302      * @see #setSelectedFont
303      * @see java.awt.Font
304      **/
305     public Font getSelectedFont()
306     {
307         Font font = new Font(getSelectedFontFamily(),
308             getSelectedFontStyle(), getSelectedFontSize());
309         return font;
310     }
311
312     /**
313      * Set the family name of the selected font.
314      * @param name  the family name of the selected font. 
315      *
316      * @see getSelectedFontFamily
317      **/
318     public void setSelectedFontFamily(String name)
319     {
320         String[] names = getFontFamilies();
321         for (int i = 0; i < names.length; i++)
322         {
323             if (names[i].toLowerCase().equals(name.toLowerCase()))
324             {
325                 getFontFamilyList().setSelectedIndex(i);
326                 break;
327             }
328         }
329         updateSampleFont();
330     }
331
332     /**
333      * Set the style of the selected font.
334      * @param style  the size of the selected font.
335      *               <code>Font.PLAIN</code>, <code>Font.BOLD</code>,
336      *               <code>Font.ITALIC</code>, or
337      *               <code>Font.BOLD|Font.ITALIC</code>.
338      *
339      * @see java.awt.Font#PLAIN
340      * @see java.awt.Font#BOLD
341      * @see java.awt.Font#ITALIC
342      * @see #getSelectedFontStyle
343      **/
344     public void setSelectedFontStyle(int style)
345     {
346         for (int i = 0; i < FONT_STYLE_CODES.length; i++)
347         {
348             if (FONT_STYLE_CODES[i] == style)
349             {
350                 getFontStyleList().setSelectedIndex(i);
351                 break;
352             }
353         }
354         updateSampleFont();
355     }
356
357     /**
358      * Set the size of the selected font.
359      * @param size the size of the selected font
360      *
361      * @see #getSelectedFontSize
362      **/
363     public void setSelectedFontSize(int size)
364     {
365         String sizeString = String.valueOf(size);
366         for (int i = 0; i < this.fontSizeStrings.length; i++)
367         {
368             if (this.fontSizeStrings[i].equals(sizeString))
369             {
370                 getFontSizeList().setSelectedIndex(i);
371                 break;
372             }
373         }
374         getFontSizeTextField().setText(sizeString);
375         updateSampleFont();
376     }
377
378     /**
379      * Set the selected font.
380      * @param font the selected font
381      *
382      * @see #getSelectedFont
383      * @see java.awt.Font
384      **/
385     public void setSelectedFont(Font font)
386     {
387         setSelectedFontFamily(font.getFamily());
388         setSelectedFontStyle(font.getStyle());
389         setSelectedFontSize(font.getSize());
390     }
391
392     public String getVersionString()
393     {
394         return ("Version");
395     }
396
397     /**
398      *  Show font selection dialog.
399      *  @param parent Dialog's Parent component.
400      *  @return OK_OPTION, CANCEL_OPTION or ERROR_OPTION
401      *
402      *  @see #OK_OPTION 
403      *  @see #CANCEL_OPTION
404      *  @see #ERROR_OPTION
405      **/
406     public int showDialog(Component parent)
407     {
408         dialogResultValue = ERROR_OPTION;
409         JDialog dialog = createDialog(parent);
410         dialog.addWindowListener(new WindowAdapter()
411         {
412             public void windowClosing(WindowEvent e)
413             {
414                 dialogResultValue = CANCEL_OPTION;
415             }
416         });
417
418         dialog.setVisible(true);
419         dialog.dispose();
420         dialog = null;
421
422         return dialogResultValue;
423     }
424
425     protected class ListSelectionHandler implements ListSelectionListener
426     {
427         private JTextComponent textComponent;
428
429         ListSelectionHandler(JTextComponent textComponent)
430         {
431             this.textComponent = textComponent;
432         }
433
434         public void valueChanged(ListSelectionEvent e)
435         {
436             if (e.getValueIsAdjusting() == false)
437             {
438                 JList list = (JList) e.getSource();
439                 String selectedValue = (String) list.getSelectedValue();
440
441                 String oldValue = textComponent.getText();
442                 textComponent.setText(selectedValue);
443                 if (!oldValue.equalsIgnoreCase(selectedValue))
444                 {
445                     textComponent.selectAll();
446                     textComponent.requestFocus();
447                 }
448
449                 updateSampleFont();
450             }
451         }
452     }
453
454     protected class TextFieldFocusHandlerForTextSelection extends FocusAdapter
455     {
456         private JTextComponent textComponent;
457
458         public TextFieldFocusHandlerForTextSelection(JTextComponent textComponent)
459         {
460             this.textComponent = textComponent;
461         }
462
463         public void focusGained(FocusEvent e)
464         {
465             textComponent.selectAll();
466         }
467
468         public void focusLost(FocusEvent e)
469         {
470             textComponent.select(0, 0);
471             updateSampleFont();
472         }
473     }
474
475     protected class TextFieldKeyHandlerForListSelectionUpDown extends KeyAdapter
476     {
477         private JList targetList;
478
479         public TextFieldKeyHandlerForListSelectionUpDown(JList list)
480         {
481             this.targetList = list;
482         }
483
484         public void keyPressed(KeyEvent e)
485         {
486             int i = targetList.getSelectedIndex();
487             switch (e.getKeyCode())
488             {
489                 case KeyEvent.VK_UP:
490                     i = targetList.getSelectedIndex() - 1;
491                     if (i < 0)
492                     {
493                         i = 0;
494                     }
495                     targetList.setSelectedIndex(i);
496                     break;
497                 case KeyEvent.VK_DOWN:
498                     int listSize = targetList.getModel().getSize();
499                     i = targetList.getSelectedIndex() + 1;
500                     if (i >= listSize)
501                     {
502                         i = listSize - 1;
503                     }
504                     targetList.setSelectedIndex(i);
505                     break;
506                 default:
507                     break;
508             }
509         }
510     }
511
512     protected class ListSearchTextFieldDocumentHandler implements DocumentListener
513     {
514         JList targetList;
515
516         public ListSearchTextFieldDocumentHandler(JList targetList)
517         {
518             this.targetList = targetList;
519         }
520
521         public void insertUpdate(DocumentEvent e)
522         {
523             update(e);
524         }
525
526         public void removeUpdate(DocumentEvent e)
527         {
528             update(e);
529         }
530
531         public void changedUpdate(DocumentEvent e)
532         {
533             update(e);
534         }
535
536         private void update(DocumentEvent event)
537         {
538             String newValue = "";
539             try
540             {
541                 Document doc = event.getDocument();
542                 newValue = doc.getText(0, doc.getLength());
543             }
544             catch (BadLocationException e)
545             {
546                 e.printStackTrace();
547             }
548
549             if (newValue.length() > 0)
550             {
551                 int index = targetList.getNextMatch(newValue, 0, Position.Bias.Forward);
552                 if (index < 0)
553                 {
554                     index = 0;
555                 }
556                 targetList.ensureIndexIsVisible(index);
557
558                 String matchedName = targetList.getModel().getElementAt(index).toString();
559                 if (newValue.equalsIgnoreCase(matchedName))
560                 {
561                     if (index != targetList.getSelectedIndex())
562                     {
563                         SwingUtilities.invokeLater(new ListSelector(index));
564                     }
565                 }
566             }
567         }
568
569         public class ListSelector implements Runnable
570         {
571             private int index;
572
573             public ListSelector(int index)
574             {
575                 this.index = index;
576             }
577
578             public void run()
579             {
580                 targetList.setSelectedIndex(this.index);
581             }
582         }
583     }
584
585     protected class DialogOKAction extends AbstractAction
586     {
587         protected static final String ACTION_NAME = "OK";
588         private JDialog dialog;
589
590         protected DialogOKAction(JDialog dialog)
591         {
592             this.dialog = dialog;
593             putValue(Action.DEFAULT, ACTION_NAME);
594             putValue(Action.ACTION_COMMAND_KEY, ACTION_NAME);
595             putValue(Action.NAME, (ACTION_NAME));
596         }
597
598         public void actionPerformed(ActionEvent e)
599         {
600             dialogResultValue = OK_OPTION;
601             dialog.setVisible(false);
602         }
603     }
604
605     protected class DialogCancelAction extends AbstractAction
606     {
607         protected static final String ACTION_NAME = "Cancel";
608         private JDialog dialog;
609
610         protected DialogCancelAction(JDialog dialog)
611         {
612             this.dialog = dialog;
613             putValue(Action.DEFAULT, ACTION_NAME);
614             putValue(Action.ACTION_COMMAND_KEY, ACTION_NAME);
615             putValue(Action.NAME, (ACTION_NAME));
616         }
617
618         public void actionPerformed(ActionEvent e)
619         {
620             dialogResultValue = CANCEL_OPTION;
621             dialog.setVisible(false);
622         }
623     }
624
625     protected JDialog createDialog(Component parent)
626     {
627         Frame frame = parent instanceof Frame ? (Frame) parent
628             : (Frame) SwingUtilities.getAncestorOfClass(Frame.class, parent);
629         JDialog dialog = new JDialog(frame, ("Select Font"), true);
630
631         Action okAction = new DialogOKAction(dialog);
632         Action cancelAction = new DialogCancelAction(dialog);
633
634         JButton okButton = new JButton(okAction);
635         okButton.setFont(DEFAULT_FONT);
636         JButton cancelButton = new JButton(cancelAction);
637         cancelButton.setFont(DEFAULT_FONT);
638
639         JPanel buttonsPanel = new JPanel();
640         buttonsPanel.setLayout(new GridLayout(2, 1));
641         buttonsPanel.add(okButton);
642         buttonsPanel.add(cancelButton);
643         buttonsPanel.setBorder(BorderFactory.createEmptyBorder(25, 0, 10, 10));
644
645         ActionMap actionMap = buttonsPanel.getActionMap();
646         actionMap.put(cancelAction.getValue(Action.DEFAULT), cancelAction);
647         actionMap.put(okAction.getValue(Action.DEFAULT), okAction);
648         InputMap inputMap = buttonsPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
649         inputMap.put(KeyStroke.getKeyStroke("ESCAPE"), cancelAction.getValue(Action.DEFAULT));
650         inputMap.put(KeyStroke.getKeyStroke("ENTER"), okAction.getValue(Action.DEFAULT));
651
652         JPanel dialogEastPanel = new JPanel();
653         dialogEastPanel.setLayout(new BorderLayout());
654         dialogEastPanel.add(buttonsPanel, BorderLayout.NORTH);
655
656         dialog.getContentPane().add(this, BorderLayout.CENTER);
657         dialog.getContentPane().add(dialogEastPanel, BorderLayout.EAST);
658         dialog.pack();
659         dialog.setLocationRelativeTo(frame);
660         return dialog;
661     }
662
663     protected void updateSampleFont()
664     {
665         Font font = getSelectedFont();
666         getSampleTextField().setFont(font);
667     }
668
669     protected JPanel getFontFamilyPanel()
670     {
671         if (fontNamePanel == null)
672         {
673             fontNamePanel = new JPanel();
674             fontNamePanel.setLayout(new BorderLayout());
675             fontNamePanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
676             fontNamePanel.setPreferredSize(new Dimension(180, 130));
677
678             JScrollPane scrollPane = new JScrollPane(getFontFamilyList());
679             scrollPane.getVerticalScrollBar().setFocusable(false);
680             scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
681
682             JPanel p = new JPanel();
683             p.setLayout(new BorderLayout());
684             p.add(getFontFamilyTextField(), BorderLayout.NORTH);
685             p.add(scrollPane, BorderLayout.CENTER);
686
687             JLabel label = new JLabel(("Font Name"));
688             label.setHorizontalAlignment(JLabel.LEFT);
689             label.setHorizontalTextPosition(JLabel.LEFT);
690             label.setLabelFor(getFontFamilyTextField());
691             label.setDisplayedMnemonic('F');
692
693             fontNamePanel.add(label, BorderLayout.NORTH);
694             fontNamePanel.add(p, BorderLayout.CENTER);
695
696         }
697         return fontNamePanel;
698     }
699
700     protected JPanel getFontStylePanel()
701     {
702         if (fontStylePanel == null)
703         {
704             fontStylePanel = new JPanel();
705             fontStylePanel.setLayout(new BorderLayout());
706             fontStylePanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
707             fontStylePanel.setPreferredSize(new Dimension(140, 130));
708
709             JScrollPane scrollPane = new JScrollPane(getFontStyleList());
710             scrollPane.getVerticalScrollBar().setFocusable(false);
711             scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
712
713             JPanel p = new JPanel();
714             p.setLayout(new BorderLayout());
715             p.add(getFontStyleTextField(), BorderLayout.NORTH);
716             p.add(scrollPane, BorderLayout.CENTER);
717
718             JLabel label = new JLabel(("Font Style"));
719             label.setHorizontalAlignment(JLabel.LEFT);
720             label.setHorizontalTextPosition(JLabel.LEFT);
721             label.setLabelFor(getFontStyleTextField());
722             label.setDisplayedMnemonic('Y');
723
724             fontStylePanel.add(label, BorderLayout.NORTH);
725             fontStylePanel.add(p, BorderLayout.CENTER);
726         }
727         return fontStylePanel;
728     }
729
730     protected JPanel getFontSizePanel()
731     {
732         if (fontSizePanel == null)
733         {
734             fontSizePanel = new JPanel();
735             fontSizePanel.setLayout(new BorderLayout());
736             fontSizePanel.setPreferredSize(new Dimension(70, 130));
737             fontSizePanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
738
739             JScrollPane scrollPane = new JScrollPane(getFontSizeList());
740             scrollPane.getVerticalScrollBar().setFocusable(false);
741             scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
742
743             JPanel p = new JPanel();
744             p.setLayout(new BorderLayout());
745             p.add(getFontSizeTextField(), BorderLayout.NORTH);
746             p.add(scrollPane, BorderLayout.CENTER);
747
748             JLabel label = new JLabel(("Font Size"));
749             label.setHorizontalAlignment(JLabel.LEFT);
750             label.setHorizontalTextPosition(JLabel.LEFT);
751             label.setLabelFor(getFontSizeTextField());
752             label.setDisplayedMnemonic('S');
753
754             fontSizePanel.add(label, BorderLayout.NORTH);
755             fontSizePanel.add(p, BorderLayout.CENTER);
756         }
757         return fontSizePanel;
758     }
759
760     protected JPanel getSamplePanel()
761     {
762         if (samplePanel == null)
763         {
764             Border titledBorder = BorderFactory.createTitledBorder(
765                 BorderFactory.createEtchedBorder(), ("Sample"));
766             Border empty = BorderFactory.createEmptyBorder(5, 10, 10, 10);
767             Border border = BorderFactory.createCompoundBorder(titledBorder, empty);
768
769             samplePanel = new JPanel();
770             samplePanel.setLayout(new BorderLayout());
771             samplePanel.setBorder(border);
772
773             samplePanel.add(getSampleTextField(), BorderLayout.CENTER);
774         }
775         return samplePanel;
776     }
777
778     protected JTextField getSampleTextField()
779     {
780         if (sampleText == null)
781         {
782             Border lowered = BorderFactory.createLoweredBevelBorder();
783
784             sampleText = new JTextField(("AaBbYyZz"));
785             sampleText.setBorder(lowered);
786             sampleText.setPreferredSize(new Dimension(300, 100));
787         }
788         return sampleText;
789     }
790
791     protected String[] getFontFamilies()
792     {
793         if (fontFamilyNames == null)
794         {
795             GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
796             fontFamilyNames = env.getAvailableFontFamilyNames();
797         }
798         return fontFamilyNames;
799     }
800
801     protected String[] getFontStyleNames()
802     {
803         if (fontStyleNames == null)
804         {
805             int i = 0;
806             fontStyleNames = new String[4];
807             fontStyleNames[i++] = ("Plain");
808             fontStyleNames[i++] = ("Bold");
809             fontStyleNames[i++] = ("Italic");
810             fontStyleNames[i++] = ("BoldItalic");
811         }
812         return fontStyleNames;
813     }
814 }