/* 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);
}
}