2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
23 import jalview.bin.Cache;
24 import jalview.jbgui.GFontChooser;
25 import jalview.util.MessageManager;
28 import java.awt.FontMetrics;
29 import java.awt.geom.Rectangle2D;
31 import javax.swing.JInternalFrame;
32 import javax.swing.JLayeredPane;
40 public class FontChooser extends GFontChooser
47 * The font on opening the dialog (to be restored on Cancel)
52 * The font on opening the dialog (to be restored on Cancel)
53 * on the other half of a split frame (if applicable)
55 Font oldComplementFont;
58 * the state of 'scale protein as cDNA' on opening the dialog
60 boolean oldProteinScale;
63 * the state of 'same font for protein and cDNA' on opening the dialog
65 boolean oldMirrorFont;
72 * The last font settings selected in the dialog
74 private Font lastSelected = null;
76 private boolean lastSelMono = false;
78 private boolean oldSmoothFont;
80 private boolean oldComplementSmooth;
83 * Creates a new FontChooser for a tree panel
87 public FontChooser(TreePanel treePanel)
90 ap = treePanel.getTreeCanvas().getAssociatedPanel();
91 oldFont = treePanel.getTreeFont();
92 defaultButton.setVisible(false);
93 smoothFont.setEnabled(false);
98 * Creates a new FontChooser for an alignment panel
102 public FontChooser(AlignmentPanel alignPanel)
104 oldFont = alignPanel.av.getFont();
105 oldProteinScale = alignPanel.av.isScaleProteinAsCdna();
106 oldMirrorFont = alignPanel.av.isProteinFontAsCdna();
107 oldSmoothFont = alignPanel.av.antiAlias;
108 this.ap = alignPanel;
114 frame = new JInternalFrame();
115 frame.setContentPane(this);
117 smoothFont.setSelected(ap.av.antiAlias);
120 * Enable 'scale protein as cDNA' in a SplitFrame view. The selection is
121 * stored in the ViewStyle of both dna and protein Viewport. Also enable
122 * checkbox for copy font changes to other half of split frame.
124 boolean inSplitFrame = ap.av.getCodingComplement() != null;
127 oldComplementFont = ((AlignViewport) ap.av.getCodingComplement())
129 oldComplementSmooth = ((AlignViewport) ap.av
130 .getCodingComplement()).antiAlias;
131 scaleAsCdna.setVisible(true);
132 scaleAsCdna.setSelected(ap.av.isScaleProteinAsCdna());
133 fontAsCdna.setVisible(true);
134 fontAsCdna.setSelected(ap.av.isProteinFontAsCdna());
139 Desktop.addInternalFrame(frame,
140 MessageManager.getString("action.change_font_tree_panel"),
145 Desktop.addInternalFrame(frame,
146 MessageManager.getString("action.change_font"), 380, 220,
150 frame.setLayer(JLayeredPane.PALETTE_LAYER);
152 String[] fonts = java.awt.GraphicsEnvironment
153 .getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
155 for (int i = 0; i < fonts.length; i++)
157 fontName.addItem(fonts[i]);
160 for (int i = 1; i < 51; i++)
165 fontStyle.addItem("plain");
166 fontStyle.addItem("bold");
167 fontStyle.addItem("italic");
169 fontName.setSelectedItem(oldFont.getName());
170 fontSize.setSelectedItem(oldFont.getSize());
171 fontStyle.setSelectedIndex(oldFont.getStyle());
173 FontMetrics fm = getGraphics().getFontMetrics(oldFont);
174 monospaced.setSelected(
175 fm.getStringBounds("M", getGraphics()).getWidth() == fm
176 .getStringBounds("|", getGraphics()).getWidth());
182 protected void smoothFont_actionPerformed()
184 ap.av.antiAlias = smoothFont.isSelected();
185 ap.getAnnotationPanel().image = null;
186 ap.paintAlignment(true, false);
187 if (ap.av.getCodingComplement() != null && ap.av.isProteinFontAsCdna())
189 ((AlignViewport) ap.av
190 .getCodingComplement()).antiAlias = ap.av.antiAlias;
191 SplitFrame sv = (SplitFrame) ap.alignFrame.getSplitViewContainer();
205 protected void ok_actionPerformed()
209 frame.setClosed(true);
210 } catch (Exception ex)
216 if (ap.getOverviewPanel() != null)
218 // changes size of rectangle
219 // BH 2019.07.29 -- updateOverviewImage forces a redraw, but all we are
220 // doing is changing the box size.
222 ap.getOverviewPanel().repaint();// updateOverviewImage();
234 protected void cancel_actionPerformed()
238 tp.setTreeFont(oldFont);
242 ap.av.setFont(oldFont, true);
243 ap.av.setScaleProteinAsCdna(oldProteinScale);
244 ap.av.setProteinFontAsCdna(oldMirrorFont);
245 ap.av.antiAlias = oldSmoothFont;
248 if (scaleAsCdna.isVisible() && scaleAsCdna.isEnabled())
250 ap.av.getCodingComplement().setScaleProteinAsCdna(oldProteinScale);
251 ap.av.getCodingComplement().setProteinFontAsCdna(oldMirrorFont);
252 ((AlignViewport) ap.av
253 .getCodingComplement()).antiAlias = oldComplementSmooth;
254 ap.av.getCodingComplement().setFont(oldComplementFont, true);
255 SplitFrame splitFrame = (SplitFrame) ap.alignFrame
256 .getSplitViewContainer();
257 splitFrame.adjustLayout();
258 splitFrame.repaint();
264 frame.setClosed(true);
265 } catch (Exception ex)
270 private boolean isTreeFont()
280 if (lastSelected == null)
282 // initialise with original font
283 lastSelected = oldFont;
284 FontMetrics fm = getGraphics().getFontMetrics(oldFont);
285 double mw = fm.getStringBounds("M", getGraphics()).getWidth();
286 double iw = fm.getStringBounds("I", getGraphics()).getWidth();
287 lastSelMono = (mw == iw); // == on double - flaky?
290 Font newFont = new Font(fontName.getSelectedItem().toString(),
291 fontStyle.getSelectedIndex(),
292 (Integer) fontSize.getSelectedItem());
293 FontMetrics fm = getGraphics().getFontMetrics(newFont);
294 double mw = fm.getStringBounds("M", getGraphics()).getWidth();
295 final Rectangle2D iBounds = fm.getStringBounds("I", getGraphics());
296 double iw = iBounds.getWidth();
297 if (mw < 1 || iw < 1)
299 String message = iBounds.getHeight() < 1
301 .getString("label.font_doesnt_have_letters_defined")
302 : MessageManager.getString("label.font_too_small");
303 JvOptionPane.showInternalMessageDialog(this, message,
304 MessageManager.getString("label.invalid_font"),
305 JvOptionPane.WARNING_MESSAGE);
307 * Restore the changed value - note this will reinvoke this method via the
308 * ActionListener, but now validation should pass
310 if (lastSelected.getSize() != (Integer) fontSize.getSelectedItem()) // autoboxing
312 fontSize.setSelectedItem(lastSelected.getSize());
314 if (!lastSelected.getName()
315 .equals(fontName.getSelectedItem().toString()))
317 fontName.setSelectedItem(lastSelected.getName());
319 if (lastSelected.getStyle() != fontStyle.getSelectedIndex())
321 fontStyle.setSelectedIndex(lastSelected.getStyle());
323 if (lastSelMono != monospaced.isSelected())
325 monospaced.setSelected(lastSelMono);
331 tp.setTreeFont(newFont);
335 ap.av.setFont(newFont, true);
339 * adjust other half of split frame if present, whether or not same font or
340 * scale to cDNA is selected, because a font change may affect character
341 * width, and this is kept the same in both panels
343 if (fontAsCdna.isVisible())
345 if (fontAsCdna.isSelected())
347 ap.av.getCodingComplement().setFont(newFont, true);
350 SplitFrame splitFrame = (SplitFrame) ap.alignFrame
351 .getSplitViewContainer();
352 splitFrame.adjustLayout();
353 splitFrame.repaint();
357 monospaced.setSelected(mw == iw);
360 * Remember latest valid selection, so it can be restored if followed by an
363 lastSelected = newFont;
367 * Updates on change of selected font name
370 protected void fontName_actionPerformed()
381 * Updates on change of selected font size
384 protected void fontSize_actionPerformed()
395 * Updates on change of selected font style
398 protected void fontStyle_actionPerformed()
409 * Make selected settings the defaults by storing them (via Cache class) in
410 * the .jalview_properties file (the file is only written when Jalview exits)
413 public void defaultButton_actionPerformed()
415 Cache.setProperty(Preferences.FONT_NAME, fontName.getSelectedItem().toString());
416 Cache.setProperty(Preferences.FONT_STYLE, fontStyle.getSelectedIndex() + "");
417 Cache.setProperty(Preferences.FONT_SIZE, fontSize.getSelectedItem().toString());
418 Cache.setProperty(Preferences.ANTI_ALIAS,
419 Boolean.toString(smoothFont.isSelected()));
420 Cache.setProperty(Preferences.SCALE_PROTEIN_TO_CDNA,
421 Boolean.toString(scaleAsCdna.isSelected()));
425 * Turn on/off scaling of protein characters to 3 times the width of cDNA
429 protected void scaleAsCdna_actionPerformed()
431 ap.av.setScaleProteinAsCdna(scaleAsCdna.isSelected());
432 ap.av.getCodingComplement()
433 .setScaleProteinAsCdna(scaleAsCdna.isSelected());
434 final SplitFrame splitFrame = (SplitFrame) ap.alignFrame
435 .getSplitViewContainer();
436 splitFrame.adjustLayout();
437 splitFrame.repaint();
441 * Turn on/off mirroring of font across split frame. If turning on, also
442 * copies the current font across the split frame. If turning off, restores
443 * the other half of the split frame to its initial font.
446 protected void mirrorFonts_actionPerformed()
448 boolean selected = fontAsCdna.isSelected();
449 ap.av.setProteinFontAsCdna(selected);
450 ap.av.getCodingComplement().setProteinFontAsCdna(selected);
453 * reset other half of split frame if turning option off
457 ap.av.getCodingComplement().setFont(oldComplementFont, true);