Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
FontChooser | 49 | 184 | 42 |
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.appletgui; | |
22 | ||
23 | import jalview.util.MessageManager; | |
24 | ||
25 | import java.awt.BorderLayout; | |
26 | import java.awt.Button; | |
27 | import java.awt.Checkbox; | |
28 | import java.awt.Choice; | |
29 | import java.awt.Color; | |
30 | import java.awt.FlowLayout; | |
31 | import java.awt.Font; | |
32 | import java.awt.FontMetrics; | |
33 | import java.awt.Frame; | |
34 | import java.awt.GraphicsEnvironment; | |
35 | import java.awt.Label; | |
36 | import java.awt.Panel; | |
37 | import java.awt.event.ActionEvent; | |
38 | import java.awt.event.ActionListener; | |
39 | import java.awt.event.ItemEvent; | |
40 | import java.awt.event.ItemListener; | |
41 | ||
42 | /** | |
43 | * This dialog allows the user to try different font settings and related | |
44 | * options. Changes are immediately visible on the alignment or tree. The user | |
45 | * can dismiss the dialog by confirming changes with 'OK', or reverting to | |
46 | * previous settings with 'Cancel'. | |
47 | */ | |
48 | @SuppressWarnings("serial") | |
49 | public class FontChooser extends Panel implements ItemListener | |
50 | { | |
51 | private static final Font VERDANA_11PT = new Font("Verdana", 0, 11); | |
52 | ||
53 | private Choice fontSize = new Choice(); | |
54 | ||
55 | private Choice fontStyle = new Choice(); | |
56 | ||
57 | private Choice fontName = new Choice(); | |
58 | ||
59 | private Checkbox scaleAsCdna = new Checkbox(); | |
60 | ||
61 | private Checkbox fontAsCdna = new Checkbox(); | |
62 | ||
63 | private Button ok = new Button(); | |
64 | ||
65 | private Button cancel = new Button(); | |
66 | ||
67 | private AlignmentPanel ap; | |
68 | ||
69 | private TreePanel tp; | |
70 | ||
71 | private Font oldFont; | |
72 | ||
73 | private Font oldComplementFont; | |
74 | ||
75 | private int oldCharWidth = 0; | |
76 | ||
77 | /* | |
78 | * the state of 'scale protein to cDNA' on opening the dialog | |
79 | */ | |
80 | private boolean oldScaleProtein = false; | |
81 | ||
82 | /* | |
83 | * the state of 'same font for protein and cDNA' on opening the dialog | |
84 | */ | |
85 | boolean oldMirrorFont; | |
86 | ||
87 | private Font lastSelected = null; | |
88 | ||
89 | private int lastSelStyle = 0; | |
90 | ||
91 | private int lastSelSize = 0; | |
92 | ||
93 | private boolean init = true; | |
94 | ||
95 | private Frame frame; | |
96 | ||
97 | boolean inSplitFrame = false; | |
98 | ||
99 | /** | |
100 | * Constructor for a TreePanel font chooser | |
101 | * | |
102 | * @param tp | |
103 | */ | |
104 | 0 | public FontChooser(TreePanel tp) |
105 | { | |
106 | 0 | try |
107 | { | |
108 | 0 | jbInit(); |
109 | } catch (Exception e) | |
110 | { | |
111 | 0 | e.printStackTrace(); |
112 | } | |
113 | ||
114 | 0 | this.tp = tp; |
115 | 0 | oldFont = tp.getTreeFont(); |
116 | 0 | init(); |
117 | } | |
118 | ||
119 | /** | |
120 | * Constructor for an AlignmentPanel font chooser | |
121 | * | |
122 | * @param ap | |
123 | */ | |
124 | 0 | public FontChooser(AlignmentPanel ap) |
125 | { | |
126 | 0 | this.ap = ap; |
127 | 0 | oldFont = ap.av.getFont(); |
128 | 0 | oldCharWidth = ap.av.getCharWidth(); |
129 | 0 | oldScaleProtein = ap.av.isScaleProteinAsCdna(); |
130 | 0 | oldMirrorFont = ap.av.isProteinFontAsCdna(); |
131 | ||
132 | 0 | try |
133 | { | |
134 | 0 | jbInit(); |
135 | } catch (Exception e) | |
136 | { | |
137 | 0 | e.printStackTrace(); |
138 | } | |
139 | 0 | init(); |
140 | } | |
141 | ||
142 | /** | |
143 | * Populate choice lists and open this dialog | |
144 | */ | |
145 | 0 | void init() |
146 | { | |
147 | // String fonts[] = Toolkit.getDefaultToolkit().getFontList(); | |
148 | 0 | String fonts[] = GraphicsEnvironment.getLocalGraphicsEnvironment() |
149 | .getAvailableFontFamilyNames(); | |
150 | 0 | for (int i = 0; i < fonts.length; i++) |
151 | { | |
152 | 0 | fontName.addItem(fonts[i]); |
153 | } | |
154 | ||
155 | 0 | for (int i = 1; i < 31; i++) |
156 | { | |
157 | 0 | fontSize.addItem(i + ""); |
158 | } | |
159 | ||
160 | 0 | fontStyle.addItem("plain"); |
161 | 0 | fontStyle.addItem("bold"); |
162 | 0 | fontStyle.addItem("italic"); |
163 | ||
164 | 0 | fontName.select(oldFont.getName()); |
165 | 0 | fontSize.select(oldFont.getSize() + ""); |
166 | 0 | fontStyle.select(oldFont.getStyle()); |
167 | ||
168 | 0 | this.frame = new Frame(); |
169 | 0 | frame.add(this); |
170 | 0 | jalview.bin.JalviewLite.addFrame(frame, |
171 | MessageManager.getString("action.change_font"), 440, 145); | |
172 | ||
173 | 0 | init = false; |
174 | } | |
175 | ||
176 | /** | |
177 | * Actions on change of font name, size or style. | |
178 | */ | |
179 | 0 | @Override |
180 | public void itemStateChanged(ItemEvent evt) | |
181 | { | |
182 | 0 | final Object source = evt.getSource(); |
183 | 0 | if (source == fontName) |
184 | { | |
185 | 0 | fontName_actionPerformed(); |
186 | } | |
187 | 0 | else if (source == fontSize) |
188 | { | |
189 | 0 | fontSize_actionPerformed(); |
190 | } | |
191 | 0 | else if (source == fontStyle) |
192 | { | |
193 | 0 | fontStyle_actionPerformed(); |
194 | } | |
195 | 0 | else if (source == scaleAsCdna) |
196 | { | |
197 | 0 | scaleAsCdna_actionPerformed(); |
198 | } | |
199 | 0 | else if (source == fontAsCdna) |
200 | { | |
201 | 0 | mirrorFont_actionPerformed(); |
202 | } | |
203 | } | |
204 | ||
205 | /** | |
206 | * Action on checking or unchecking 'use same font across split screen' | |
207 | * option. When checked, the font settings are copied to the other half of the | |
208 | * split screen. When unchecked, the other half is restored to its initial | |
209 | * settings. | |
210 | */ | |
211 | 0 | protected void mirrorFont_actionPerformed() |
212 | { | |
213 | 0 | boolean selected = fontAsCdna.getState(); |
214 | 0 | ap.av.setProteinFontAsCdna(selected); |
215 | 0 | ap.av.getCodingComplement().setProteinFontAsCdna(selected); |
216 | ||
217 | 0 | if (!selected) |
218 | { | |
219 | 0 | ap.av.getCodingComplement().setFont(oldComplementFont, true); |
220 | } | |
221 | 0 | changeFont(); |
222 | } | |
223 | ||
224 | /** | |
225 | * Close this dialog on OK to confirm any changes. Also updates the overview | |
226 | * window if displayed. | |
227 | */ | |
228 | 0 | protected void ok_actionPerformed() |
229 | { | |
230 | 0 | frame.setVisible(false); |
231 | 0 | if (ap != null) |
232 | { | |
233 | 0 | if (ap.getOverviewPanel() != null) |
234 | { | |
235 | 0 | ap.getOverviewPanel().updateOverviewImage(); |
236 | } | |
237 | } | |
238 | } | |
239 | ||
240 | /** | |
241 | * Close this dialog on Cancel, reverting to previous font settings. | |
242 | */ | |
243 | 0 | protected void cancel_actionPerformed() |
244 | { | |
245 | 0 | if (ap != null) |
246 | { | |
247 | 0 | ap.av.setScaleProteinAsCdna(oldScaleProtein); |
248 | 0 | ap.av.setProteinFontAsCdna(oldMirrorFont); |
249 | ||
250 | 0 | if (ap.av.getCodingComplement() != null) |
251 | { | |
252 | 0 | ap.av.getCodingComplement().setScaleProteinAsCdna(oldScaleProtein); |
253 | 0 | ap.av.getCodingComplement().setProteinFontAsCdna(oldMirrorFont); |
254 | 0 | ap.av.getCodingComplement().setFont(oldComplementFont, true); |
255 | 0 | SplitFrame splitFrame = ap.alignFrame.getSplitFrame(); |
256 | 0 | splitFrame.adjustLayout(); |
257 | 0 | splitFrame.getComplement(ap.alignFrame).alignPanel.fontChanged(); |
258 | 0 | splitFrame.repaint(); |
259 | } | |
260 | ||
261 | 0 | ap.av.setFont(oldFont, true); |
262 | 0 | if (ap.av.getCharWidth() != oldCharWidth) |
263 | { | |
264 | 0 | ap.av.setCharWidth(oldCharWidth); |
265 | } | |
266 | 0 | ap.paintAlignment(true, false); |
267 | } | |
268 | 0 | else if (tp != null) |
269 | { | |
270 | 0 | tp.setTreeFont(oldFont); |
271 | 0 | tp.treeCanvas.repaint(); |
272 | } | |
273 | ||
274 | 0 | fontName.select(oldFont.getName()); |
275 | 0 | fontSize.select(oldFont.getSize() + ""); |
276 | 0 | fontStyle.select(oldFont.getStyle()); |
277 | ||
278 | 0 | frame.setVisible(false); |
279 | } | |
280 | ||
281 | /** | |
282 | * DOCUMENT ME! | |
283 | */ | |
284 | 0 | void changeFont() |
285 | { | |
286 | 0 | if (lastSelected == null) |
287 | { | |
288 | // initialise with original font | |
289 | 0 | lastSelected = oldFont; |
290 | 0 | lastSelSize = oldFont.getSize(); |
291 | 0 | lastSelStyle = oldFont.getStyle(); |
292 | } | |
293 | ||
294 | 0 | Font newFont = new Font(fontName.getSelectedItem().toString(), |
295 | fontStyle.getSelectedIndex(), | |
296 | Integer.parseInt(fontSize.getSelectedItem().toString())); | |
297 | 0 | FontMetrics fm = getGraphics().getFontMetrics(newFont); |
298 | 0 | double mw = fm.getStringBounds("M", getGraphics()).getWidth(), |
299 | iw = fm.getStringBounds("I", getGraphics()).getWidth(); | |
300 | 0 | if (mw < 1 || iw < 1) |
301 | { | |
302 | // TODO: JAL-1100 | |
303 | 0 | fontName.select(lastSelected.getName()); |
304 | 0 | fontStyle.select(lastSelStyle); |
305 | 0 | fontSize.select("" + lastSelSize); |
306 | 0 | JVDialog d = new JVDialog(this.frame, |
307 | MessageManager.getString("label.invalid_font"), true, 350, | |
308 | 200); | |
309 | 0 | Panel mp = new Panel(); |
310 | 0 | d.cancel.setVisible(false); |
311 | 0 | mp.setLayout(new FlowLayout()); |
312 | 0 | mp.add(new Label( |
313 | "Font doesn't have letters defined\nso cannot be used\nwith alignment data.")); | |
314 | 0 | d.setMainPanel(mp); |
315 | 0 | d.setVisible(true); |
316 | 0 | return; |
317 | } | |
318 | 0 | if (tp != null) |
319 | { | |
320 | 0 | tp.setTreeFont(newFont); |
321 | } | |
322 | 0 | else if (ap != null) |
323 | { | |
324 | 0 | ap.av.setFont(newFont, true); |
325 | 0 | ap.fontChanged(); |
326 | ||
327 | /* | |
328 | * and change font in other half of split frame if any | |
329 | */ | |
330 | 0 | if (inSplitFrame) |
331 | { | |
332 | 0 | if (fontAsCdna.getState()) |
333 | { | |
334 | 0 | ap.av.getCodingComplement().setFont(newFont, true); |
335 | } | |
336 | 0 | SplitFrame splitFrame = ap.alignFrame.getSplitFrame(); |
337 | 0 | splitFrame.adjustLayout(); |
338 | 0 | splitFrame.getComplement(ap.alignFrame).alignPanel.fontChanged(); |
339 | 0 | splitFrame.repaint(); |
340 | } | |
341 | } | |
342 | // remember last selected | |
343 | 0 | lastSelected = newFont; |
344 | } | |
345 | ||
346 | 0 | protected void fontName_actionPerformed() |
347 | { | |
348 | 0 | if (init) |
349 | { | |
350 | 0 | return; |
351 | } | |
352 | 0 | changeFont(); |
353 | } | |
354 | ||
355 | 0 | protected void fontSize_actionPerformed() |
356 | { | |
357 | 0 | if (init) |
358 | { | |
359 | 0 | return; |
360 | } | |
361 | 0 | changeFont(); |
362 | } | |
363 | ||
364 | 0 | protected void fontStyle_actionPerformed() |
365 | { | |
366 | 0 | if (init) |
367 | { | |
368 | 0 | return; |
369 | } | |
370 | 0 | changeFont(); |
371 | } | |
372 | ||
373 | /** | |
374 | * Construct this panel's contents | |
375 | * | |
376 | * @throws Exception | |
377 | */ | |
378 | 0 | private void jbInit() throws Exception |
379 | { | |
380 | 0 | this.setLayout(new BorderLayout()); |
381 | 0 | this.setBackground(Color.white); |
382 | ||
383 | 0 | Label fontLabel = new Label(MessageManager.getString("label.font")); |
384 | 0 | fontLabel.setFont(VERDANA_11PT); |
385 | 0 | fontLabel.setAlignment(Label.RIGHT); |
386 | 0 | fontSize.setFont(VERDANA_11PT); |
387 | 0 | fontSize.addItemListener(this); |
388 | 0 | fontStyle.setFont(VERDANA_11PT); |
389 | 0 | fontStyle.addItemListener(this); |
390 | ||
391 | 0 | Label sizeLabel = new Label(MessageManager.getString("label.size")); |
392 | 0 | sizeLabel.setAlignment(Label.RIGHT); |
393 | 0 | sizeLabel.setFont(VERDANA_11PT); |
394 | ||
395 | 0 | Label styleLabel = new Label(MessageManager.getString("label.style")); |
396 | 0 | styleLabel.setAlignment(Label.RIGHT); |
397 | 0 | styleLabel.setFont(VERDANA_11PT); |
398 | ||
399 | 0 | fontName.setFont(VERDANA_11PT); |
400 | 0 | fontName.addItemListener(this); |
401 | ||
402 | 0 | scaleAsCdna.setLabel(MessageManager.getString("label.scale_as_cdna")); |
403 | 0 | scaleAsCdna.setFont(VERDANA_11PT); |
404 | 0 | scaleAsCdna.addItemListener(this); |
405 | 0 | scaleAsCdna.setState(ap.av.isScaleProteinAsCdna()); |
406 | ||
407 | 0 | fontAsCdna.setLabel(MessageManager.getString("label.font_as_cdna")); |
408 | 0 | fontAsCdna.setFont(VERDANA_11PT); |
409 | 0 | fontAsCdna.addItemListener(this); |
410 | 0 | fontAsCdna.setState(ap.av.isProteinFontAsCdna()); |
411 | ||
412 | 0 | ok.setFont(VERDANA_11PT); |
413 | 0 | ok.setLabel(MessageManager.getString("action.ok")); |
414 | 0 | ok.addActionListener(new ActionListener() |
415 | { | |
416 | 0 | @Override |
417 | public void actionPerformed(ActionEvent e) | |
418 | { | |
419 | 0 | ok_actionPerformed(); |
420 | } | |
421 | }); | |
422 | 0 | cancel.setFont(VERDANA_11PT); |
423 | 0 | cancel.setLabel(MessageManager.getString("action.cancel")); |
424 | 0 | cancel.addActionListener(new ActionListener() |
425 | { | |
426 | 0 | @Override |
427 | public void actionPerformed(ActionEvent e) | |
428 | { | |
429 | 0 | cancel_actionPerformed(); |
430 | } | |
431 | }); | |
432 | ||
433 | 0 | Panel fontPanel = new Panel(); |
434 | 0 | fontPanel.setLayout(new BorderLayout()); |
435 | 0 | Panel stylePanel = new Panel(); |
436 | 0 | stylePanel.setLayout(new BorderLayout()); |
437 | 0 | Panel sizePanel = new Panel(); |
438 | 0 | sizePanel.setLayout(new BorderLayout()); |
439 | 0 | Panel scalePanel = new Panel(); |
440 | 0 | scalePanel.setLayout(new BorderLayout()); |
441 | 0 | Panel okCancelPanel = new Panel(); |
442 | 0 | Panel optionsPanel = new Panel(); |
443 | ||
444 | 0 | fontPanel.setBackground(Color.white); |
445 | 0 | stylePanel.setBackground(Color.white); |
446 | 0 | sizePanel.setBackground(Color.white); |
447 | 0 | okCancelPanel.setBackground(Color.white); |
448 | 0 | optionsPanel.setBackground(Color.white); |
449 | ||
450 | 0 | fontPanel.add(fontLabel, BorderLayout.WEST); |
451 | 0 | fontPanel.add(fontName, BorderLayout.CENTER); |
452 | 0 | stylePanel.add(styleLabel, BorderLayout.WEST); |
453 | 0 | stylePanel.add(fontStyle, BorderLayout.CENTER); |
454 | 0 | sizePanel.add(sizeLabel, BorderLayout.WEST); |
455 | 0 | sizePanel.add(fontSize, BorderLayout.CENTER); |
456 | 0 | scalePanel.add(scaleAsCdna, BorderLayout.NORTH); |
457 | 0 | scalePanel.add(fontAsCdna, BorderLayout.SOUTH); |
458 | 0 | okCancelPanel.add(ok, null); |
459 | 0 | okCancelPanel.add(cancel, null); |
460 | ||
461 | 0 | optionsPanel.add(fontPanel, null); |
462 | 0 | optionsPanel.add(sizePanel, null); |
463 | 0 | optionsPanel.add(stylePanel, null); |
464 | ||
465 | /* | |
466 | * Only show 'scale protein as cDNA' in a SplitFrame | |
467 | */ | |
468 | 0 | this.add(optionsPanel, BorderLayout.NORTH); |
469 | 0 | if (ap.alignFrame.getSplitFrame() != null) |
470 | { | |
471 | 0 | inSplitFrame = true; |
472 | 0 | oldComplementFont = ((AlignViewport) ap.av.getCodingComplement()) |
473 | .getFont(); | |
474 | 0 | this.add(scalePanel, BorderLayout.CENTER); |
475 | } | |
476 | 0 | this.add(okCancelPanel, BorderLayout.SOUTH); |
477 | } | |
478 | ||
479 | /** | |
480 | * Turn on/off scaling of protein characters to 3 times the width of cDNA | |
481 | * characters | |
482 | */ | |
483 | 0 | protected void scaleAsCdna_actionPerformed() |
484 | { | |
485 | 0 | ap.av.setScaleProteinAsCdna(scaleAsCdna.getState()); |
486 | 0 | ap.av.getCodingComplement() |
487 | .setScaleProteinAsCdna(scaleAsCdna.getState()); | |
488 | 0 | changeFont(); |
489 | } | |
490 | ||
491 | } |