001 /*
002 * Copyright (c) 2005 Einar Pehrson <einar@pehrson.nu>.
003 *
004 * This file is part of
005 * CleanSheets - a spreadsheet application for the Java platform.
006 *
007 * CleanSheets is free software; you can redistribute it and/or modify
008 * it under the terms of the GNU General Public License as published by
009 * the Free Software Foundation; either version 2 of the License, or
010 * (at your option) any later version.
011 *
012 * CleanSheets is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015 * GNU General Public License for more details.
016 *
017 * You should have received a copy of the GNU General Public License
018 * along with CleanSheets; if not, write to the Free Software
019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020 */
021 package csheets.ext.style.ui;
022
023 import java.awt.BorderLayout;
024 import java.awt.Component;
025 import java.awt.Dimension;
026 import java.awt.Font;
027 import java.awt.GraphicsEnvironment;
028 import java.awt.GridLayout;
029 import java.awt.event.ActionEvent;
030 import java.awt.event.ActionListener;
031
032 import javax.swing.BorderFactory;
033 import javax.swing.DefaultListCellRenderer;
034 import javax.swing.Icon;
035 import javax.swing.JCheckBox;
036 import javax.swing.JComponent;
037 import javax.swing.JLabel;
038 import javax.swing.JList;
039 import javax.swing.JOptionPane;
040 import javax.swing.JPanel;
041 import javax.swing.JScrollPane;
042 import javax.swing.ListSelectionModel;
043 import javax.swing.event.ListSelectionEvent;
044 import javax.swing.event.ListSelectionListener;
045
046 /**
047 * A component which allows the user to select a font.
048 * @author Einar Pehrson
049 */
050 @SuppressWarnings("serial")
051 public class FontChooser extends JComponent {
052
053 /** The font sizes that can be selected */
054 private static final Integer[] SIZES = new Integer[]
055 {4, 6, 8, 9, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, 40, 48, 64};
056
057 /** The default font size, if none is selected */
058 private static final Integer DEFAULT_SIZE = 10;
059
060 /** The font family list */
061 private JList familyList;
062
063 /** The font size list */
064 private JList sizeList;
065
066 /** The checkbox that indicates whether the font is bold */
067 private JCheckBox boldBox = new JCheckBox("Bold");
068
069 /** The checkbox that indicates whether or not the font is italic */
070 private JCheckBox italicBox = new JCheckBox("Italic");
071
072 /** The preview label */
073 private JLabel previewLabel = new JLabel();
074
075 /**
076 * Creates a new font selection panel.
077 */
078 public FontChooser () {
079 this(null);
080 }
081
082 /**
083 * Creates a new font selection panel with the given initial font selected.
084 * @param initialFont the font to select initially
085 */
086 public FontChooser(Font initialFont) {
087 // Fetches the available font family names
088 String[] fontFamilyNames = GraphicsEnvironment
089 .getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
090
091 // Creates and configures lists
092 familyList = new JList(fontFamilyNames);
093 familyList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
094 familyList.setVisibleRowCount(10);
095
096 sizeList = new JList(SIZES);
097 sizeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
098 sizeList.setVisibleRowCount(6);
099 ((DefaultListCellRenderer)sizeList.getCellRenderer())
100 .setHorizontalAlignment(JLabel.RIGHT);
101
102 // Configures preview label
103 previewLabel.setBorder(BorderFactory.createTitledBorder("Preview"));
104 previewLabel.setHorizontalAlignment(JLabel.CENTER);
105 previewLabel.setPreferredSize(
106 new Dimension(getPreferredSize().width, 80));
107
108 // Creates and configures containers
109 JPanel familyPanel = new JPanel(new BorderLayout());
110 familyPanel.add(new JScrollPane(familyList));
111 familyPanel.setBorder(BorderFactory.createTitledBorder("Family"));
112
113 JPanel sizePanel = new JPanel(new BorderLayout());
114 sizePanel.add(new JScrollPane(sizeList));
115 sizePanel.setBorder(BorderFactory.createTitledBorder("Size"));
116
117 JPanel stylePanel = new JPanel(new GridLayout(2, 1));
118 stylePanel.add(boldBox);
119 stylePanel.add(italicBox);
120 stylePanel.setBorder(BorderFactory.createTitledBorder("Style"));
121
122 JPanel propPanel = new JPanel(new BorderLayout());
123 propPanel.add(sizePanel, BorderLayout.CENTER);
124 propPanel.add(stylePanel, BorderLayout.SOUTH);
125
126 // Registers listener
127 PreviewLabelUpdater updater = new PreviewLabelUpdater();
128 familyList.addListSelectionListener(updater);
129 sizeList.addListSelectionListener(updater);
130 boldBox.addActionListener(updater);
131 italicBox.addActionListener(updater);
132
133 // Configures layout and adds components
134 setLayout(new BorderLayout(5, 5));
135 add(familyPanel, BorderLayout.CENTER);
136 add(propPanel, BorderLayout.EAST);
137 add(previewLabel, BorderLayout.SOUTH);
138
139 // Sets the initial font
140 if (initialFont != null)
141 setSelectedFont(initialFont);
142 else
143 setSelectedFont(new Font(fontFamilyNames[0], Font.PLAIN, 12));
144 }
145
146 /**
147 * Lets the user select a font from a chooser in a standard dialog.
148 * @param parent the parent component of the dialog
149 * @param title the title of the dialog
150 * @param initialFont the font to select initially
151 * @return the selected font or, if the user did not press OK, null
152 */
153 public static Font showDialog(Component parent, String title,
154 Font initialFont) {
155 FontChooser chooser = new FontChooser(initialFont);
156 int returnValue = JOptionPane.showConfirmDialog(
157 parent,
158 chooser,
159 title,
160 JOptionPane.OK_CANCEL_OPTION,
161 JOptionPane.PLAIN_MESSAGE,
162 (Icon)null);
163 if (returnValue == JOptionPane.OK_OPTION)
164 return chooser.getSelectedFont();
165 else
166 return null;
167 }
168
169 /**
170 * Returns the currently selected font in the dialog.
171 * @return the currently selected font
172 */
173 public Font getSelectedFont() {
174 return new Font(
175 (String)familyList.getSelectedValue(),
176 (boldBox.isSelected() ? Font.BOLD : Font.PLAIN)
177 | (italicBox.isSelected() ? Font.ITALIC : Font.PLAIN),
178 sizeList.isSelectionEmpty() ? DEFAULT_SIZE
179 : (Integer)sizeList.getSelectedValue()
180 );
181 }
182
183 /**
184 * Sets the currently selected font in the dialog.
185 * @param font the font to select
186 */
187 public void setSelectedFont(Font font) {
188 familyList.setSelectedValue(font.getFamily(), true);
189 sizeList.setSelectedValue(font.getSize(), true);
190 boldBox.setSelected(font.isBold());
191 italicBox.setSelected(font.isItalic());
192 }
193
194 /**
195 * A controller that updates the preview label.
196 */
197 private class PreviewLabelUpdater implements ListSelectionListener, ActionListener {
198
199 /**
200 * Creates a new preview label updater.
201 */
202 public PreviewLabelUpdater() {}
203
204 /**
205 * Updates the preview label.
206 * @param e the event that was fired
207 */
208 public void actionPerformed(ActionEvent e) {
209 previewLabel.setFont(getSelectedFont());
210 }
211
212 /**
213 * Updates the preview label.
214 * @param e the event that was fired
215 */
216 public void valueChanged(ListSelectionEvent e) {
217 if (!e.getValueIsAdjusting()) {
218 Font font = getSelectedFont();
219 previewLabel.setFont(font);
220 previewLabel.setText(font.getName());
221 }
222 }
223 }
224 }