JAL-1690 fix NPE on Cancel when not in split frame
[jalview.git] / src / jalview / gui / FontChooser.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.gui;
22
23 import java.awt.Font;
24 import java.awt.FontMetrics;
25 import java.awt.event.ActionEvent;
26
27 import javax.swing.JInternalFrame;
28 import javax.swing.JLayeredPane;
29 import javax.swing.JOptionPane;
30
31 import jalview.bin.Cache;
32 import jalview.jbgui.GFontChooser;
33 import jalview.util.MessageManager;
34
35 /**
36  * DOCUMENT ME!
37  * 
38  * @author $author$
39  * @version $Revision$
40  */
41 public class FontChooser extends GFontChooser
42 {
43   AlignmentPanel ap;
44
45   TreePanel tp;
46
47   Font oldFont;
48
49   boolean oldProteinScale;
50
51   boolean init = true;
52
53   JInternalFrame frame;
54
55   /**
56    * Creates a new FontChooser object.
57    * 
58    * @param ap
59    *          DOCUMENT ME!
60    */
61   public FontChooser(TreePanel tp)
62   {
63     this.tp = tp;
64     ap = tp.treeCanvas.ap;
65     oldFont = tp.getTreeFont();
66     defaultButton.setVisible(false);
67     smoothFont.setEnabled(false);
68     init();
69   }
70
71   /**
72    * Creates a new FontChooser object.
73    * 
74    * @param ap
75    *          DOCUMENT ME!
76    */
77   public FontChooser(AlignmentPanel ap)
78   {
79     oldFont = ap.av.getFont();
80     oldProteinScale = ap.av.isScaleProteinAsCdna();
81
82     this.ap = ap;
83     init();
84   }
85
86   void init()
87   {
88     frame = new JInternalFrame();
89     frame.setContentPane(this);
90
91     smoothFont.setSelected(ap.av.antiAlias);
92
93     /*
94      * Enable 'scale protein as cDNA' in a SplitFrame view. The selection is
95      * stored in the ViewStyle of both dna and protein Viewport
96      */
97     scaleAsCdna.setEnabled(false);
98     if (ap.av.getCodingComplement() != null)
99     {
100       scaleAsCdna.setEnabled(true);
101       scaleAsCdna.setVisible(true);
102       scaleAsCdna.setSelected(ap.av.isScaleProteinAsCdna());
103     }
104
105     if (tp != null)
106     {
107       Desktop.addInternalFrame(frame,
108               MessageManager.getString("action.change_font_tree_panel"),
109               400, 200, false);
110     }
111     else
112     {
113       Desktop.addInternalFrame(frame,
114               MessageManager.getString("action.change_font"), 380, 200,
115               false);
116     }
117
118     frame.setLayer(JLayeredPane.PALETTE_LAYER);
119
120     String[] fonts = java.awt.GraphicsEnvironment
121             .getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
122
123     for (int i = 0; i < fonts.length; i++)
124     {
125       fontName.addItem(fonts[i]);
126     }
127
128     for (int i = 1; i < 51; i++)
129     {
130       fontSize.addItem(i);
131     }
132
133     fontStyle.addItem("plain");
134     fontStyle.addItem("bold");
135     fontStyle.addItem("italic");
136
137     fontName.setSelectedItem(oldFont.getName());
138     fontSize.setSelectedItem(oldFont.getSize());
139     fontStyle.setSelectedIndex(oldFont.getStyle());
140
141     FontMetrics fm = getGraphics().getFontMetrics(oldFont);
142     monospaced.setSelected(fm.getStringBounds("M", getGraphics())
143             .getWidth() == fm.getStringBounds("|", getGraphics())
144             .getWidth());
145
146     init = false;
147   }
148
149   public void smoothFont_actionPerformed(ActionEvent e)
150   {
151     ap.av.antiAlias = smoothFont.isSelected();
152     ap.getAnnotationPanel().image = null;
153     ap.paintAlignment(true);
154   }
155
156   /**
157    * DOCUMENT ME!
158    * 
159    * @param e
160    *          DOCUMENT ME!
161    */
162   protected void ok_actionPerformed(ActionEvent e)
163   {
164     try
165     {
166       frame.setClosed(true);
167     } catch (Exception ex)
168     {
169     }
170
171     if (ap != null)
172     {
173       if (ap.getOverviewPanel() != null)
174       {
175         ap.getOverviewPanel().updateOverviewImage();
176       }
177     }
178   }
179
180   /**
181    * DOCUMENT ME!
182    * 
183    * @param e
184    *          DOCUMENT ME!
185    */
186   protected void cancel_actionPerformed(ActionEvent e)
187   {
188     if (ap != null)
189     {
190       ap.av.setFont(oldFont, true);
191       ap.av.setScaleProteinAsCdna(oldProteinScale);
192       ap.paintAlignment(true);
193       if (scaleAsCdna.isEnabled())
194       {
195         ap.av.setScaleProteinAsCdna(oldProteinScale);
196         ap.av.getCodingComplement().setScaleProteinAsCdna(oldProteinScale);
197       }
198     }
199     else if (tp != null)
200     {
201       tp.setTreeFont(oldFont);
202     }
203     fontName.setSelectedItem(oldFont.getName());
204     fontSize.setSelectedItem(oldFont.getSize());
205     fontStyle.setSelectedIndex(oldFont.getStyle());
206
207     try
208     {
209       frame.setClosed(true);
210     } catch (Exception ex)
211     {
212     }
213   }
214
215   private Font lastSelected = null;
216
217   private int lastSelStyle = 0;
218
219   private int lastSelSize = 0;
220
221   private boolean lastSelMono = false;
222
223   /**
224    * DOCUMENT ME!
225    */
226   void changeFont()
227   {
228     if (lastSelected == null)
229     {
230       // initialise with original font
231       lastSelected = oldFont;
232       lastSelSize = oldFont.getSize();
233       lastSelStyle = oldFont.getStyle();
234       FontMetrics fm = getGraphics().getFontMetrics(oldFont);
235       double mw = fm.getStringBounds("M", getGraphics()).getWidth(), iw = fm
236               .getStringBounds("I", getGraphics()).getWidth();
237       lastSelMono = mw == iw;
238     }
239
240     Font newFont = new Font(fontName.getSelectedItem().toString(),
241             fontStyle.getSelectedIndex(),
242             (Integer) fontSize.getSelectedItem());
243     FontMetrics fm = getGraphics().getFontMetrics(newFont);
244     double mw = fm.getStringBounds("M", getGraphics()).getWidth(), iw = fm
245             .getStringBounds("I", getGraphics()).getWidth();
246     if (mw < 1 || iw < 1)
247     {
248       JOptionPane
249               .showInternalMessageDialog(
250                       this,
251                       MessageManager.getString("label.font_doesnt_have_letters_defined"),
252                       MessageManager.getString("label.invalid_font"), JOptionPane.WARNING_MESSAGE);
253       /*
254        * Restore previous values - size first to avoid recursive calls to this
255        * point!
256        */
257       fontSize.setSelectedItem(lastSelSize);
258       fontName.setSelectedItem(lastSelected.getName());
259       fontStyle.setSelectedIndex(lastSelStyle);
260       monospaced.setSelected(lastSelMono);
261       return;
262     }
263     if (tp != null)
264     {
265       tp.setTreeFont(newFont);
266     }
267     else if (ap != null)
268     {
269       ap.av.setFont(newFont, true);
270       ap.fontChanged();
271     }
272
273     monospaced.setSelected(mw == iw);
274     // remember last selected
275     lastSelected = newFont;
276   }
277
278   /**
279    * DOCUMENT ME!
280    * 
281    * @param e
282    *          DOCUMENT ME!
283    */
284   protected void fontName_actionPerformed(ActionEvent e)
285   {
286     if (init)
287     {
288       return;
289     }
290
291     changeFont();
292   }
293
294   /**
295    * DOCUMENT ME!
296    * 
297    * @param e
298    *          DOCUMENT ME!
299    */
300   protected void fontSize_actionPerformed(ActionEvent e)
301   {
302     if (init)
303     {
304       return;
305     }
306
307     changeFont();
308   }
309
310   /**
311    * DOCUMENT ME!
312    * 
313    * @param e
314    *          DOCUMENT ME!
315    */
316   protected void fontStyle_actionPerformed(ActionEvent e)
317   {
318     if (init)
319     {
320       return;
321     }
322
323     changeFont();
324   }
325
326   /**
327    * Make selected settings the defaults by storing them (via Cache class) in
328    * the .jalview_properties file (the file is only written when Jalview exits)
329    * 
330    * @param e
331    */
332   public void defaultButton_actionPerformed(ActionEvent e)
333   {
334     Cache.setProperty("FONT_NAME", fontName.getSelectedItem().toString());
335     Cache.setProperty("FONT_STYLE", fontStyle.getSelectedIndex() + "");
336     Cache.setProperty("FONT_SIZE", fontSize.getSelectedItem().toString());
337     Cache.setProperty("ANTI_ALIAS",
338             Boolean.toString(smoothFont.isSelected()));
339     Cache.setProperty(Preferences.SCALE_PROTEIN_TO_CDNA,
340             Boolean.toString(scaleAsCdna.isSelected()));
341   }
342
343   /**
344    * Turn on/off scaling of protein characters to 3 times the width of cDNA
345    * characters
346    */
347   @Override
348   protected void scaleAsCdna_actionPerformed(ActionEvent e)
349   {
350     ap.av.setScaleProteinAsCdna(scaleAsCdna.isSelected());
351     ap.av.getCodingComplement().setScaleProteinAsCdna(
352             scaleAsCdna.isSelected());
353     final SplitFrame splitFrame = (SplitFrame) ap.alignFrame
354             .getSplitViewContainer();
355     splitFrame.adjustLayout();
356     splitFrame.repaint();
357     // ap.paintAlignment(true);
358     // TODO would like to repaint
359   }
360 }