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 */ 021package csheets.ext.style.ui; 022 023import java.awt.BorderLayout; 024import java.awt.Component; 025import java.awt.Dimension; 026import java.awt.Font; 027import java.awt.GraphicsEnvironment; 028import java.awt.GridLayout; 029import java.awt.event.ActionEvent; 030import java.awt.event.ActionListener; 031 032import javax.swing.BorderFactory; 033import javax.swing.DefaultListCellRenderer; 034import javax.swing.Icon; 035import javax.swing.JCheckBox; 036import javax.swing.JComponent; 037import javax.swing.JLabel; 038import javax.swing.JList; 039import javax.swing.JOptionPane; 040import javax.swing.JPanel; 041import javax.swing.JScrollPane; 042import javax.swing.ListSelectionModel; 043import javax.swing.event.ListSelectionEvent; 044import 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") 051public 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}