/* LanguageTool, a natural language style checker * Copyright (C) 2014 Panagiotis Minos * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 * USA */ package org.languagetool.gui; import java.awt.ComponentOrientation; import java.awt.Font; import java.awt.Frame; import java.awt.GraphicsEnvironment; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Locale; import java.util.ResourceBundle; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.KeyStroke; import javax.swing.ListSelectionModel; import javax.swing.border.TitledBorder; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.languagetool.JLanguageTool; /** * A font chooser dialog * * @author Panagiotis Minos * @since 2.6 */ class FontChooser extends JDialog implements ActionListener, DocumentListener, ListSelectionListener { private static final Integer[] fontSizesArray = { 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24, 26, 28, 32 }; private static final String ACTION_COMMAND_OK = "OK"; private static final String ACTION_COMMAND_CANCEL = "CANCEL"; private static final String ACTION_COMMAND_RESET = "RESET"; private String[] fontStylesArray; private final ResourceBundle messages; private JTextField fontNameTextField; private JTextField fontStyleTextField; private JTextField fontSizeTextField; private JList<String> fontNameList; private JList<String> fontStyleList; private JList<Integer> fontSizeList; private JTextArea previewArea; private Font selectedFont; private Font defaultFont; /** * Creates a new font chooser dialog * * @param owner the {@code Frame} from which the dialog is displayed * @param modal specifies whether dialog blocks user input to other top-level * windows when shown. */ FontChooser(Frame owner, boolean modal) { super(owner, modal); messages = JLanguageTool.getMessageBundle(); initComponents(); } /** * Gets the current font value from the font chooser. * * @return the current font of the font chooser */ Font getSelectedFont() { return selectedFont; } /** * Sets the current font of the font chooser to the specified font. * * @param font the font to be set in the font chooser */ void setSelectedFont(Font font) { this.selectedFont = font; fontNameList.setSelectedValue(font.getFamily(), true); fontStyleList.setSelectedValue(getStyle(font), true); fontSizeList.setSelectedValue(font.getSize(), true); } private void initComponents() { KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(stroke, "Hide"); getRootPane().getActionMap().put("Hide", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { selectedFont = null; setVisible(false); } }); this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { selectedFont = null; setVisible(false); } }); setTitle(messages.getString("FontChooser.title")); fontStylesArray = new String[]{ messages.getString("FontChooser.style.plain"), messages.getString("FontChooser.style.bold"), messages.getString("FontChooser.style.italic"), messages.getString("FontChooser.style.bold_italic") }; String[] fontNamesArray = GraphicsEnvironment .getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); getContentPane() .setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); c.insets = new Insets(4, 4, 4, 4); JPanel fontPanel = new JPanel(new GridBagLayout()); c.gridx = 0; c.gridy = 0; c.fill = GridBagConstraints.HORIZONTAL; JLabel fontNameLabel = new JLabel(messages.getString("FontChooser.label.name")); fontPanel.add(fontNameLabel, c); c.gridx = 1; c.gridy = 0; JLabel fontStyleLabel = new JLabel(messages.getString("FontChooser.label.style")); fontPanel.add(fontStyleLabel, c); c.gridx = 2; c.gridy = 0; JLabel fontSizeLabel = new JLabel(messages.getString("FontChooser.label.size")); fontPanel.add(fontSizeLabel, c); c.gridx = 0; c.gridy = 1; c.weightx = 1.0; c.fill = GridBagConstraints.HORIZONTAL; fontNameTextField = new JTextField(); fontNameTextField.setEnabled(false); fontNameTextField.getDocument().addDocumentListener(this); fontPanel.add(fontNameTextField, c); c.weightx = 0.0; c.gridx = 1; c.gridy = 1; fontStyleTextField = new JTextField(); fontStyleTextField.setEnabled(false); fontStyleTextField.getDocument().addDocumentListener(this); fontPanel.add(fontStyleTextField, c); c.gridx = 2; c.gridy = 1; fontSizeTextField = new JTextField(); fontSizeTextField.setColumns(4); fontSizeTextField.getDocument().addDocumentListener(this); fontPanel.add(fontSizeTextField, c); c.gridx = 0; c.gridy = 2; c.weightx = 1.0; c.weighty = 1; c.fill = GridBagConstraints.BOTH; fontNameList = new JList<>(fontNamesArray); fontNameList.addListSelectionListener(this); fontNameList.setVisibleRowCount(5); fontNameList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); JScrollPane fontNameListPane = new JScrollPane(fontNameList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); fontPanel.add(fontNameListPane, c); c.gridx = 1; c.gridy = 2; c.weightx = 0.5; fontStyleList = new JList<>(fontStylesArray); fontStyleList.addListSelectionListener(this); fontStyleList.setVisibleRowCount(5); fontStyleList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); JScrollPane fontStyleListPane = new JScrollPane(fontStyleList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); fontPanel.add(fontStyleListPane, c); c.gridx = 2; c.gridy = 2; fontSizeList = new JList<>(fontSizesArray); fontSizeList.addListSelectionListener(this); fontSizeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); fontSizeList.setVisibleRowCount(5); JScrollPane fontSizeListPane = new JScrollPane(fontSizeList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); fontPanel.add(fontSizeListPane, c); c.insets = new Insets(8, 8, 4, 8); c.gridx = 0; c.gridy = 0; c.weightx = 0.0; c.weighty = 0.4; getContentPane().add(fontPanel, c); c.insets = new Insets(4, 8, 4, 8); c.gridx = 0; c.gridy = 1; c.weightx = 1.0; c.weighty = 0.6; previewArea = new JTextArea(messages.getString("FontChooser.pangram")); previewArea.setLineWrap(true); previewArea.setRows(4); JScrollPane pane = new JScrollPane(previewArea); TitledBorder border = BorderFactory.createTitledBorder( messages.getString("FontChooser.preview")); pane.setBorder(border); getContentPane().add(pane, c); JPanel buttonPanel = new JPanel(new GridBagLayout()); c.insets = new Insets(4, 4, 4, 4); c.gridx = 0; c.gridy = 0; c.weightx = 1.0; c.weighty = 0.0; c.anchor = GridBagConstraints.LINE_START; c.fill = GridBagConstraints.NONE; JButton resetButton = new JButton(Tools.getLabel( messages.getString("FontChooser.reset"))); resetButton.setMnemonic(Tools.getMnemonic( messages.getString("FontChooser.reset"))); resetButton.setActionCommand(ACTION_COMMAND_RESET); resetButton.addActionListener(this); buttonPanel.add(resetButton, c); c.gridx = 1; c.gridy = 0; c.weightx = 0.0; c.weighty = 0.0; c.anchor = GridBagConstraints.LINE_END; c.fill = GridBagConstraints.NONE; JButton cancelButton = new JButton(Tools.getLabel( messages.getString("guiCancelButton"))); cancelButton.setMnemonic(Tools.getMnemonic( messages.getString("guiCancelButton"))); cancelButton.setActionCommand(ACTION_COMMAND_CANCEL); cancelButton.addActionListener(this); buttonPanel.add(cancelButton, c); c.gridx = 2; c.gridy = 0; JButton okButton = new JButton(Tools.getLabel( messages.getString("guiOKButton"))); okButton.setMnemonic(Tools.getMnemonic( messages.getString("guiOKButton"))); okButton.setActionCommand(ACTION_COMMAND_OK); okButton.addActionListener(this); buttonPanel.add(okButton, c); c.insets = new Insets(4, 8, 8, 8); c.gridx = 0; c.gridy = 2; c.anchor = GridBagConstraints.LINE_START; c.fill = GridBagConstraints.HORIZONTAL; getContentPane().add(buttonPanel, c); this.defaultFont = previewArea.getFont(); setDefaultFont(); getRootPane().setDefaultButton(cancelButton); this.applyComponentOrientation( ComponentOrientation.getOrientation(Locale.getDefault())); pack(); } @Override public void actionPerformed(ActionEvent e) { if (ACTION_COMMAND_CANCEL.equals(e.getActionCommand())) { this.selectedFont = null; setVisible(false); } else if (ACTION_COMMAND_OK.equals(e.getActionCommand())) { setVisible(false); } else if (ACTION_COMMAND_RESET.equals(e.getActionCommand())) { setDefaultFont(); } } @Override public void valueChanged(ListSelectionEvent e) { if (e.getValueIsAdjusting()) { return; } if (e.getSource() == this.fontNameList) { String fontName = this.fontNameList.getSelectedValue(); if (fontName != null) { this.fontNameTextField.setText(fontName); } } else if (e.getSource() == this.fontStyleList) { String fontStyle = this.fontStyleList.getSelectedValue(); if (fontStyle != null) { this.fontStyleTextField.setText(fontStyle); } } else if (e.getSource() == this.fontSizeList) { Integer fontSize = this.fontSizeList.getSelectedValue(); if (fontSize != null) { this.fontSizeTextField.setText(fontSize.toString()); } } } @Override public void insertUpdate(DocumentEvent e) { updateFont(); } @Override public void removeUpdate(DocumentEvent e) { updateFont(); } @Override public void changedUpdate(DocumentEvent e) { updateFont(); } private void updateFont() { String fontName = this.fontNameTextField.getText(); String styleName = this.fontStyleTextField.getText(); Integer fontSize = null; try { fontSize = Integer.parseInt(this.fontSizeTextField.getText()); } catch (NumberFormatException ex) { } int style = Font.PLAIN; if (fontStylesArray[1].equals(styleName)) { style = Font.BOLD; } else if (fontStylesArray[2].equals(styleName)) { style = Font.ITALIC; } else if (fontStylesArray[3].equals(styleName)) { style = Font.BOLD | Font.ITALIC; } if (fontName != null && fontSize != null) { Font newFont = new Font(fontName, style, fontSize); this.selectedFont = newFont; previewArea.setFont(newFont); } } private String getStyle(Font font) { switch (font.getStyle()) { case Font.PLAIN: return fontStylesArray[0]; case Font.BOLD: return fontStylesArray[1]; case Font.ITALIC: return fontStylesArray[2]; case Font.BOLD | Font.ITALIC: return fontStylesArray[3]; default: return fontStylesArray[0]; } } private void setDefaultFont() { this.selectedFont = defaultFont; fontNameList.setSelectedValue(defaultFont.getFontName(), true); fontStyleList.setSelectedValue(getStyle(defaultFont), true); fontSizeList.setSelectedValue(defaultFont.getSize(), true); } }