001    package nl.cwi.sen1.tide.tool.prefeditor;
002    
003    import java.awt.BorderLayout;
004    import java.awt.Color;
005    import java.awt.Dimension;
006    import java.awt.Font;
007    import java.awt.GraphicsEnvironment;
008    import java.awt.GridLayout;
009    import java.awt.event.ActionEvent;
010    import java.awt.event.ActionListener;
011    import java.util.Iterator;
012    
013    import javax.swing.JCheckBox;
014    import javax.swing.JComboBox;
015    import javax.swing.JLabel;
016    import javax.swing.JPanel;
017    import javax.swing.SwingConstants;
018    
019    import nl.cwi.sen1.tide.PreferenceListener;
020    import nl.cwi.sen1.tide.PreferenceSet;
021    
022    public class FontPreferenceEditor
023      extends JPanel
024      implements PreferenceListener
025    {
026      private static final int MAX_FONTS = 16;
027    
028      private PreferencesEditor editor;
029      private PreferenceSet preferences;
030    
031      private int fontCount;
032      private FontPanel[] fontPanels;
033      private JLabel preview;
034    
035      //{{{ public FontPreferenceEditor(editor, preferences)
036    
037      public FontPreferenceEditor(PreferencesEditor editor,
038                                  PreferenceSet preferences)
039      {
040        this.editor      = editor;
041        this.preferences = preferences;
042    
043        preferences.addPreferenceListener(this);
044    
045        setLayout(new BorderLayout());
046        //setBackground(Color.white);
047    
048        JPanel fontPanel = new JPanel();
049        fontPanel.setLayout(new GridLayout(0,1));
050        add("North", fontPanel);
051        fontPanel.add(new JPanel());
052    
053        fontPanels = new FontPanel[MAX_FONTS];
054        Iterator<String> fonts = preferences.preferenceNameIterator("font.spec.");
055        while (fonts.hasNext()) {
056          String name = fonts.next();
057          String key  = name.substring("font.spec.".length());
058          String fontName = preferences.getPreference("font.name." + key);
059          if (fontName == null) {
060            fontName = key;
061          }
062          //String fontSpec = preferences.getPreference("font.spec." + key);
063          fontPanels[fontCount] = new FontPanel(this, preferences, key);
064          fontPanel.add(fontPanels[fontCount]);
065          fontCount++;
066        }
067    
068        preview = new JLabel("", SwingConstants.CENTER);
069        preview.setForeground(Color.black);
070        add("Center", preview);
071      }
072    
073      //}}}
074      //{{{ protected void cleanup()
075    
076      protected void cleanup()
077      {
078        preferences.removePreferenceListener(this);
079      }
080    
081      //}}}
082      //{{{ protected void doRevert()
083    
084      protected void doRevert()
085      {
086        for (int i=0; i<fontCount; i++) {
087          fontPanels[i].doRevert();
088        }
089      }
090    
091      //}}}
092      //{{{ protected void doUpdate()
093    
094      protected void doUpdate()
095      {
096        for (int i=0; i<fontCount; i++) {
097          fontPanels[i].doUpdate();
098        }
099      }
100    
101      //}}}
102      //{{{ protected void changePending(FontPanel panel)
103    
104      protected void changePending(FontPanel panel)
105      {
106        editor.changePending();
107        preview.setFont(panel.getFont());
108        preview.setText("This is an example of the " + panel.getName()
109                       + " font - {}();:#$*");
110      }
111    
112      //}}}
113    
114      //{{{ public void preferenceChanged(prefs, name, oldValue, newValue)
115    
116      public void preferenceChanged(PreferenceSet prefs, String name, String oldValue, String newValue)
117      {
118        doRevert();
119      }
120    
121      //}}}
122      //{{{ public void preferencesChanged(PreferenceSet prefs)
123    
124      public void preferencesChanged(PreferenceSet prefs)
125      {
126        doRevert();
127      }
128    
129      //}}}
130      //{{{ public void preferencesStatusChanged(boolean clean)
131    
132      public void preferencesStatusChanged(PreferenceSet set, boolean clean){}
133    
134      //}}}
135    }
136    
137    class FontPanel
138      extends JPanel
139      implements ActionListener
140    {
141      private static final int MIN_SIZE =  8;
142      private static final int MAX_SIZE = 24;
143    
144      private static final Color COLOR_UNCHANGED = Color.black;
145      private static final Color COLOR_CHANGED   = Color.red;
146    
147      private FontPreferenceEditor editor;
148      private PreferenceSet preferences;
149      private String    key;
150      private String    name;
151    
152      private JLabel    fontLabel;
153      private JComboBox fontFamily;
154      private JComboBox fontSize;
155      private JCheckBox fontBold;
156      private JCheckBox fontItalic;
157      private Font      font;
158    
159      private boolean   inRevert;
160    
161      //{{{ public FontPanel(editor, prefs, key)
162    
163      public FontPanel(FontPreferenceEditor editor, PreferenceSet prefs,
164                       String key)
165      {
166        this.editor = editor;
167    
168        setLayout(new BorderLayout());
169    
170        this.preferences = prefs;
171        this.key         = key;
172    
173        GraphicsEnvironment env =
174          GraphicsEnvironment.getLocalGraphicsEnvironment();
175        //String[] families = env.getAvailableFontFamilyNames();
176        String[] families = env.getAvailableFontFamilyNames();
177        String[] sizes = new String[MAX_SIZE-MIN_SIZE+1];
178        for (int i=MIN_SIZE; i<=MAX_SIZE; i++) {
179          sizes[i-MIN_SIZE] = String.valueOf(i);
180        }
181    
182        name = preferences.getPreference("font.name." + key);
183    
184        fontLabel  = new JLabel(name + ": ");
185        fontFamily = new JComboBox(families);
186        fontSize   = new JComboBox(sizes);
187        fontBold   = new JCheckBox("Bold");
188        fontItalic = new JCheckBox("Italic");
189    
190        fontFamily.addActionListener(this);
191        fontSize.addActionListener(this);
192        fontBold.addActionListener(this);
193        fontItalic.addActionListener(this);
194    
195        doRevert();
196    
197        Dimension dim = new Dimension(120, 1);
198        fontLabel.setPreferredSize(dim);
199        fontLabel.setMaximumSize(dim);
200        fontLabel.setMinimumSize(dim);
201    
202        add("West", fontLabel);
203        add("Center", fontFamily);
204        
205        JPanel right = new JPanel();
206        right.setLayout(new GridLayout(1,3));
207        right.add(fontSize);
208        right.add(fontBold);
209        right.add(fontItalic);
210        add("East", right);
211      }
212    
213      //}}}
214      //{{{ private String getFontSpec()
215    
216      private String getFontSpec()
217      {
218        String fontSpec = fontFamily.getSelectedItem() + "-";
219        String style = null;
220        if (fontBold.isSelected()) {
221          style = "BOLD";
222        }
223        if (fontItalic.isSelected()) {
224          if (style == null) {
225            style = "ITALIC";
226          } else {
227            style += "ITALIC";
228          }
229        }
230        if (style == null) {
231          style = "PLAIN";
232        }
233    
234        fontSpec += style + "-" + (fontSize.getSelectedIndex()+MIN_SIZE);
235    
236        /*
237        String family = font.getFamily();
238        String style = null;
239        switch (font.getStyle()) {
240          case Font.BOLD:
241            style = "BOLD";
242            break;
243          case Font.ITALIC:
244            style = "ITALIC";
245            break;
246          case Font.BOLD+Font.ITALIC:
247            style = "BOLDITALIC";
248            break;
249        }
250        String size = String.valueOf(font.getSize());
251    
252        return family + "-" + style + "-" + size;
253        */
254    
255        return fontSpec;
256      }
257    
258      //}}}
259      //{{{ public String getName()
260    
261      public String getName()
262      {
263        return name;
264      }
265    
266      //}}}
267      //{{{ public Font getFont()
268    
269      public Font getFont()
270      {
271        return font;
272      }
273    
274      //}}}
275      //{{{ protected void doRevert()
276    
277      protected void doRevert()
278      {
279        inRevert = true;
280    
281        String fontSpec = preferences.getPreference("font.spec." + key);
282    
283        if (fontSpec == null) {
284          fontSpec = preferences.getPreference("font.spec.default");
285        }
286    
287        int index;
288    
289        index = fontSpec.indexOf('-');
290        String family = fontSpec.substring(0, index);
291    
292        font = Font.decode(fontSpec);
293        System.out.println("selecting family: " + family);
294        fontFamily.setSelectedItem(family);
295        fontSize.setSelectedIndex(font.getSize()-MIN_SIZE);
296        fontBold.setSelected((font.getStyle() & Font.BOLD) == Font.BOLD);
297        fontItalic.setSelected((font.getStyle()
298                                & Font.ITALIC) == Font.ITALIC);
299        fontLabel.setForeground(COLOR_UNCHANGED);
300    
301        inRevert = false;
302      }
303    
304      //}}}
305      //{{{ protected void doUpdate()
306    
307      protected void doUpdate()
308      {
309        String fontSpec = getFontSpec();
310        System.out.println("fontSpec = " + fontSpec);
311        font = Font.decode(fontSpec);
312    
313        preferences.setPreference("font.spec." + key, fontSpec);
314        
315        fontLabel.setForeground(COLOR_UNCHANGED);
316      }
317    
318      //}}}
319    
320      //{{{ public void actionPerformed(ActionEvent event)
321    
322      public void actionPerformed(ActionEvent event)
323      {
324        if (!inRevert) {
325          font = Font.decode(getFontSpec());
326    
327          editor.changePending(this);
328          fontLabel.setForeground(COLOR_CHANGED);
329        }
330      }
331    
332      //}}}
333    }