CoverityFix-CID:1351082 Unread field should be static
[scilab.git] / scilab / modules / gui / src / java / org / scilab / modules / gui / bridge / fontchooser / SwingScilabFontChooser.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2008 - INRIA - Vincent Couvert
4  * Copyright (C) 2010 - DIGITEO - Vincent Couvert
5  *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14  *
15  */
16
17 package org.scilab.modules.gui.bridge.fontchooser;
18
19 import java.awt.BorderLayout;
20 import java.awt.Color;
21 import java.awt.Cursor;
22 import java.awt.Dimension;
23 import java.awt.FlowLayout;
24 import java.awt.Font;
25 import java.awt.GraphicsEnvironment;
26 import java.awt.GridLayout;
27 import java.awt.event.ActionEvent;
28 import java.awt.event.ActionListener;
29 import java.awt.event.ItemEvent;
30 import java.awt.event.ItemListener;
31
32 import javax.swing.BoxLayout;
33 import javax.swing.DefaultListModel;
34 import javax.swing.ImageIcon;
35 import javax.swing.JButton;
36 import javax.swing.JCheckBox;
37 import javax.swing.JDialog;
38 import javax.swing.JFrame;
39 import javax.swing.JLabel;
40 import javax.swing.JList;
41 import javax.swing.JPanel;
42 import javax.swing.JScrollPane;
43 import javax.swing.ListSelectionModel;
44 import javax.swing.border.EtchedBorder;
45 import javax.swing.border.LineBorder;
46 import javax.swing.border.TitledBorder;
47 import javax.swing.event.ChangeEvent;
48 import javax.swing.event.ChangeListener;
49 import javax.swing.event.ListSelectionEvent;
50 import javax.swing.event.ListSelectionListener;
51
52 import org.scilab.modules.commons.gui.FindIconHelper;
53 import org.scilab.modules.gui.fontchooser.SimpleFontChooser;
54 import org.scilab.modules.gui.utils.ScilabFontUtils;
55 import org.scilab.modules.gui.utils.ScilabSwingUtilities;
56 import org.scilab.modules.localization.Messages;
57
58 /**
59  * Swing implementation of a Scilab FileChooser
60  * @author Vincent COUVERT
61  */
62 public class SwingScilabFontChooser extends JDialog implements SimpleFontChooser {
63
64     private static final long serialVersionUID = 1L;
65
66     private static final int HGAP = 10;
67     private static final int VGAP = 2;
68     private static final int PREVIEW_WIDTH = 120;
69     private static final int PREVIEW_HEIGHT = 40;
70     private static final int DEFAULT_FONT_SIZE = 12;
71
72     private int elementId;
73
74     private final JList fontNameList;
75     private final String[] availableFontNames;
76
77     private final JList fontSizeList;
78     private final String[] availableFontSizes = {"8", "10", "11", "12",
79                                                  "13", "14", "16", "18", "20",
80                                                  "24", "30", "36", "40",
81                                                  "48", "60", "72"
82                                                 };
83
84     private final boolean calledFromScinotes;
85     private final JCheckBox boldCheckbox;
86     private final JCheckBox italicCheckbox;
87     private final JCheckBox monospacedCheckbox;
88     private JCheckBox scinotesCompatibleCheckbox;
89
90     private final JLabel preview;
91     private static final String PREVIEW_TEXT = "The Quick Brown Fox Jumps Over The Lazy Dog";
92
93     /* User choices */
94     private Font selectedFont;
95
96     /**
97      * Default constructor
98      * @param font the default font
99      */
100     public SwingScilabFontChooser(Font font) {
101         this(new JFrame(), font, false);
102     }
103
104     /**
105      * Default constructor
106      * @param owner the Dialog owner
107      * @param font the default font
108      * @param calledFromScinotes true if called from SciNotes (specific options to display)
109      */
110     public SwingScilabFontChooser(JFrame owner, Font font, boolean calledFromScinotes) {
111         super(owner, Messages.gettext("Font Chooser"), true);
112         this.calledFromScinotes = calledFromScinotes;
113         ((JFrame) getParent()).setIconImage(new ImageIcon(FindIconHelper.findIcon("scilab", "256x256")).getImage());
114
115         getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
116
117         /* Panel used to display available fonts and sizes */
118         JPanel fontPanel = new JPanel(new GridLayout(1, 2, HGAP, VGAP));
119         fontPanel.setBorder(new TitledBorder(new EtchedBorder(), Messages.gettext("Font")));
120
121         /* Font names list */
122         fontNameList = new JList();
123         fontNameList.setModel(new DefaultListModel());
124         fontNameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
125         fontPanel.add(new JScrollPane(fontNameList));
126
127         /* Get the system fonts */
128         availableFontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
129
130         /* Add the font names to the list */
131         for (int fontIndex = 0; fontIndex < availableFontNames.length; fontIndex++) {
132             ((DefaultListModel) fontNameList.getModel()).addElement(availableFontNames[fontIndex]);
133             if ((font != null) && (availableFontNames[fontIndex].equals(font.getFamily()))) {
134                 fontNameList.setSelectedIndex(fontIndex);
135             }
136         }
137         if (fontNameList.getSelectedIndex() == -1) {
138             fontNameList.setSelectedIndex(0);
139         }
140
141
142         ScilabSwingUtilities.closeOnEscape(this);
143
144         /* Font size list */
145         fontSizeList = new JList();
146         fontSizeList.setModel(new DefaultListModel());
147         fontSizeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
148         fontPanel.add(new JScrollPane(fontSizeList));
149
150         /* Add the font sizes to the list */
151         for (int sizeIndex = 0; sizeIndex < availableFontSizes.length; sizeIndex++) {
152             ((DefaultListModel) fontSizeList.getModel()).addElement(availableFontSizes[sizeIndex]);
153             if ((font != null) && (availableFontSizes[sizeIndex].equals(Integer.toString(font.getSize())))) {
154                 fontSizeList.setSelectedIndex(sizeIndex);
155             }
156         }
157         if (fontSizeList.getSelectedIndex() == -1) {
158             fontSizeList.setSelectedIndex(0);
159         }
160
161
162         getContentPane().add(fontPanel);
163
164         /* Attributes panel */
165         JPanel attributes = new JPanel(new GridLayout(2, 2, HGAP, VGAP));
166         attributes.setBorder(new TitledBorder(new EtchedBorder(), Messages.gettext("Attributes")));
167         boldCheckbox = new JCheckBox(Messages.gettext("Bold"), (font != null) && font.isBold());
168         attributes.add(boldCheckbox);
169         italicCheckbox = new JCheckBox(Messages.gettext("Italic"), (font != null) && font.isItalic());
170         attributes.add(italicCheckbox);
171         monospacedCheckbox = new JCheckBox(Messages.gettext("Monospaced"), false);
172         attributes.add(monospacedCheckbox);
173         monospacedCheckbox.addItemListener(new ItemListener() {
174             @Override
175             public void itemStateChanged(ItemEvent e) {
176                 updateFontNameList();
177             }
178         });
179
180         if (calledFromScinotes) {
181             boldCheckbox.setEnabled(false);
182             italicCheckbox.setEnabled(false);
183             scinotesCompatibleCheckbox = new JCheckBox(Messages.gettext("SciNotes compatible"), false);
184             attributes.add(scinotesCompatibleCheckbox);
185             scinotesCompatibleCheckbox.addItemListener(new ItemListener() {
186                 @Override
187                 public void itemStateChanged(ItemEvent e) {
188                     updateFontNameList();
189                 }
190             });
191         }
192         getContentPane().add(attributes);
193
194         /* Preview panel */
195         JPanel previewPanel = new JPanel(new BorderLayout());
196         previewPanel.setBorder(new TitledBorder(new EtchedBorder(), Messages.gettext("Preview")));
197         preview = new JLabel(PREVIEW_TEXT, JLabel.CENTER);
198         preview.setBackground(Color.white);
199         preview.setForeground(Color.black);
200         preview.setOpaque(true);
201         preview.setBorder(new LineBorder(Color.black));
202         preview.setPreferredSize(new Dimension(PREVIEW_WIDTH, PREVIEW_HEIGHT));
203         previewPanel.add(preview, BorderLayout.CENTER);
204
205         getContentPane().add(previewPanel);
206
207         /* Buttons panel */
208         JPanel buttonsContainer = new JPanel(new FlowLayout());
209         JPanel buttonsPanel = new JPanel(new GridLayout(1, 2, HGAP, VGAP));
210
211         JButton okButton = new JButton(Messages.gettext("Ok"));
212         buttonsPanel.add(okButton);
213         getRootPane().setDefaultButton(okButton);
214         okButton.addActionListener(new ActionListener() {
215             @Override
216             public void actionPerformed(ActionEvent e) {
217                 previewFont();
218                 dispose();
219                 setVisible(false);
220             }
221         });
222
223         JButton canButton = new JButton(Messages.gettext("Cancel"));
224         buttonsPanel.add(canButton);
225         canButton.addActionListener(new ActionListener() {
226             @Override
227             public void actionPerformed(ActionEvent e) {
228                 selectedFont = null;
229                 dispose();
230                 setVisible(false);
231             }
232         });
233
234         buttonsContainer.add(buttonsPanel);
235         getContentPane().add(buttonsContainer);
236
237         fontSizeList.addListSelectionListener(new ListSelectionListener() {
238             @Override
239             public void valueChanged(ListSelectionEvent arg0) {
240                 previewFont();
241             }
242         });
243         fontNameList.addListSelectionListener(new ListSelectionListener() {
244             @Override
245             public void valueChanged(ListSelectionEvent arg0) {
246                 previewFont();
247             }
248         });
249         boldCheckbox.addChangeListener(new ChangeListener() {
250             @Override
251             public void stateChanged(ChangeEvent arg0) {
252                 previewFont();
253             }
254         });
255         italicCheckbox.addChangeListener(new ChangeListener() {
256             @Override
257             public void stateChanged(ChangeEvent arg0) {
258                 previewFont();
259             }
260         });
261
262         previewFont();
263
264         pack();
265
266         setPreferredSize(getSize());
267
268         setResizable(false);
269     }
270
271     /**
272      * Set the element id for this file chooser
273      * @param id the id of the corresponding file chooser object
274      */
275     @Override
276     public void setElementId(int id) {
277         this.elementId = id;
278     }
279
280     /**
281      * Get the element id for this chooser
282      * @return id the id of the corresponding chooser object
283      */
284     @Override
285     public int getElementId() {
286         return this.elementId;
287     }
288
289     /**
290      * Retrieve the selected font, or null
291      * @return the selected font
292      */
293     @Override
294     public Font getSelectedFont() {
295         return selectedFont;
296     }
297
298     /**
299      * Update the preview label
300      */
301     protected void previewFont() {
302         if (fontNameList.getSelectedIndex() == -1 || fontSizeList.getSelectedIndex() == -1) {
303             return;
304         }
305         String selectedFontName = (String) fontNameList.getSelectedValue();
306         String resultSizeName = (String) fontSizeList.getSelectedValue();
307         int selectedFontSize = Integer.parseInt(resultSizeName);
308         int attrs = Font.PLAIN;
309
310         boolean selectedBold = boldCheckbox.isSelected();
311         boolean selectedItalic = italicCheckbox.isSelected();
312         if (selectedBold) {
313             attrs = Font.BOLD;
314         }
315         if (selectedItalic) {
316             attrs |= Font.ITALIC;
317         }
318         selectedFont = new Font(selectedFontName, attrs, selectedFontSize);
319         preview.setFont(selectedFont);
320         pack();
321     }
322
323     /**
324      * Set the default font name
325      * @param fontName the default font name
326      */
327     @Override
328     public void setDefaultFontName(String fontName) {
329         for (int fontIndex = 0; fontIndex < availableFontNames.length; fontIndex++) {
330             if (availableFontNames[fontIndex].equalsIgnoreCase(fontName)) {
331                 fontNameList.setSelectedIndex(fontIndex);
332             }
333         }
334     }
335
336     /**
337      * Set the default font size
338      * @param fontSize the default font size
339      */
340     @Override
341     public void setDefaultFontSize(int fontSize) {
342         for (int sizeIndex = 0; sizeIndex < availableFontSizes.length; sizeIndex++) {
343             if (availableFontSizes[sizeIndex].equals(Integer.toString(fontSize))) {
344                 fontSizeList.setSelectedIndex(sizeIndex);
345             }
346         }
347     }
348
349     /**
350      * Set the default font bold attribute
351      * @param bold the default font bold attribute
352      */
353     @Override
354     public void setDefaultBold(boolean bold) {
355         boldCheckbox.setSelected(bold);
356     }
357
358     /**
359      * Set the default font italic attribute
360      * @param italic the default font italic attribute
361      */
362     @Override
363     public void setDefaultItalic(boolean italic) {
364         italicCheckbox.setSelected(italic);
365     }
366
367     /**
368      * Display the font chooser and wait for a user input
369      */
370     @Override
371     public void displayAndWait() {
372         setVisible(true);
373     }
374
375     /**
376      * Update font names list according to the checkboxes status
377      */
378     private void updateFontNameList() {
379         boolean monospacedMode = monospacedCheckbox.isSelected();
380         boolean scinotesMode = calledFromScinotes && scinotesCompatibleCheckbox.isSelected();
381
382         setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
383
384         ((DefaultListModel) fontNameList.getModel()).removeAllElements();
385
386         if (!monospacedMode & !scinotesMode) {
387             /* Display all fonts */
388             for (int fontIndex = 0; fontIndex < availableFontNames.length; fontIndex++) {
389                 ((DefaultListModel) fontNameList.getModel()).addElement(availableFontNames[fontIndex]);
390             }
391         }
392
393         if (monospacedMode & !scinotesMode) {
394             /* Display only monospaced fonts */
395             for (int fontIndex = 0; fontIndex < availableFontNames.length; fontIndex++) {
396                 if (ScilabFontUtils.isMonospaced(new Font(availableFontNames[fontIndex], Font.PLAIN, DEFAULT_FONT_SIZE))) {
397                     ((DefaultListModel) fontNameList.getModel()).addElement(availableFontNames[fontIndex]);
398                 }
399             }
400         }
401
402         if (!monospacedMode & scinotesMode) {
403             /* Display only SciNotes compatibles fonts */
404             for (int fontIndex = 0; fontIndex < availableFontNames.length; fontIndex++) {
405                 if (ScilabFontUtils.isAllStylesSameWidths(availableFontNames[fontIndex])) {
406                     ((DefaultListModel) fontNameList.getModel()).addElement(availableFontNames[fontIndex]);
407                 }
408             }
409         }
410
411         if (monospacedMode & scinotesMode) {
412             /* Display only SciNotes compatibles fonts which are monospaced */
413             for (int fontIndex = 0; fontIndex < availableFontNames.length; fontIndex++) {
414                 if (ScilabFontUtils.isMonospaced(new Font(availableFontNames[fontIndex], Font.PLAIN, DEFAULT_FONT_SIZE))
415                         && ScilabFontUtils.isAllStylesSameWidths(availableFontNames[fontIndex])) {
416                     ((DefaultListModel) fontNameList.getModel()).addElement(availableFontNames[fontIndex]);
417                 }
418             }
419         }
420
421         setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
422     }
423 }