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.Color; 025import java.awt.Component; 026import java.awt.Dimension; 027import java.awt.GridBagConstraints; 028import java.awt.GridBagLayout; 029import java.awt.Insets; 030import java.awt.event.ActionEvent; 031import java.awt.event.ItemEvent; 032import java.awt.event.ItemListener; 033 034import javax.swing.AbstractAction; 035import javax.swing.BorderFactory; 036import javax.swing.BoxLayout; 037import javax.swing.Icon; 038import javax.swing.ImageIcon; 039import javax.swing.JButton; 040import javax.swing.JColorChooser; 041import javax.swing.JComponent; 042import javax.swing.JLabel; 043import javax.swing.JOptionPane; 044import javax.swing.JPanel; 045import javax.swing.JToggleButton; 046import javax.swing.border.Border; 047import javax.swing.border.MatteBorder; 048 049import csheets.ext.style.StyleExtension; 050 051/** 052 * A component which allows the user to select a border. 053 * @author Einar Pehrson 054 */ 055@SuppressWarnings("serial") 056public class BorderChooser extends JComponent { 057 058 /** The toggle button for the top border segment */ 059 private JToggleButton topButton = new JToggleButton(new ImageIcon( 060 StyleExtension.class.getResource("res/img/border_top.gif"))); 061 062 /** The toggle button for the left border segment */ 063 private JToggleButton leftButton = new JToggleButton(new ImageIcon( 064 StyleExtension.class.getResource("res/img/border_left.gif"))); 065 066 /** The toggle button for the right border segment */ 067 private JToggleButton rightButton = new JToggleButton(new ImageIcon( 068 StyleExtension.class.getResource("res/img/border_right.gif"))); 069 070 /** The toggle button for the bottom border segment */ 071 private JToggleButton bottomButton = new JToggleButton(new ImageIcon( 072 StyleExtension.class.getResource("res/img/border_bottom.gif"))); 073 074 /** The preview label */ 075 private JLabel previewLabel = new JLabel(""); 076 077 /** The currently selected border color */ 078 private Color color = Color.black; 079 080 /** 081 * Creates a new border selection panel. 082 */ 083 public BorderChooser () { 084 this(null); 085 } 086 087 /** 088 * Creates a new border selection panel with the given initial border 089 * selected. 090 * @param initialBorder the border to select initially 091 */ 092 public BorderChooser(Border initialBorder) { 093 // Configures preview label 094 previewLabel.setPreferredSize(new Dimension(100, 80)); 095 previewLabel.setBorder( 096 BorderFactory.createCompoundBorder( 097 BorderFactory.createTitledBorder("Preview"), 098 BorderFactory.createEmptyBorder(5, 5, 5, 5) 099 )); 100 101 // Registers listener 102 PreviewLabelUpdater updater = new PreviewLabelUpdater(); 103 topButton.addItemListener(updater); 104 leftButton.addItemListener(updater); 105 rightButton.addItemListener(updater); 106 bottomButton.addItemListener(updater); 107 108 // Lays out button panel 109 JPanel buttonPanel = new JPanel(new GridBagLayout()); 110 GridBagConstraints gc = new GridBagConstraints(); 111 gc.gridwidth = gc.gridheight = 2; 112 gc.gridy = 1; 113 buttonPanel.add(leftButton, gc); 114 gc.gridx = 2; 115 gc.gridy = 0; 116 buttonPanel.add(topButton, gc); 117 gc.gridy = 2; 118 buttonPanel.add(bottomButton, gc); 119 gc.gridx = 4; 120 gc.gridy = 1; 121 buttonPanel.add(rightButton, gc); 122 buttonPanel.setBorder(BorderFactory.createTitledBorder("Border")); 123 124 // Creates color panel 125 JPanel colorPanel = new JPanel(); 126 colorPanel.setLayout(new BoxLayout(colorPanel, BoxLayout.X_AXIS)); 127 JButton colorButton = new JButton(new ColorAction()); 128 colorButton.setAlignmentY(0.5f); 129 colorPanel.add(colorButton); 130 colorPanel.setBorder(BorderFactory.createTitledBorder("Color")); 131 132 // Configures layout and adds components 133 setLayout(new BorderLayout(5, 5)); 134 add(buttonPanel, BorderLayout.CENTER); 135 add(colorPanel, BorderLayout.EAST); 136 add(previewLabel, BorderLayout.SOUTH); 137 138 // Sets the initial border 139 setSelectedBorder(initialBorder); 140 } 141 142 /** 143 * Lets the user select a border from a chooser in a standard dialog. 144 * @param parent the parent component of the dialog 145 * @param title the title of the dialog 146 * @param initialBorder the border to select initially 147 * @return the selected border or, if the user did not press OK, null 148 */ 149 public static Border showDialog(Component parent, String title, 150 Border initialBorder) { 151 BorderChooser chooser = new BorderChooser(initialBorder); 152 int returnValue = JOptionPane.showConfirmDialog( 153 parent, 154 chooser, 155 title, 156 JOptionPane.OK_CANCEL_OPTION, 157 JOptionPane.PLAIN_MESSAGE, 158 (Icon)null); 159 if (returnValue == JOptionPane.OK_OPTION) 160 return chooser.getSelectedBorder(); 161 else 162 return null; 163 } 164 165 /** 166 * Returns the currently selected border in the dialog. 167 * @return the currently selected border 168 */ 169 public Border getSelectedBorder() { 170 return BorderFactory.createMatteBorder( 171 topButton.isSelected() ? 1 : 0, 172 leftButton.isSelected() ? 1 : 0, 173 bottomButton.isSelected() ? 1 : 0, 174 rightButton.isSelected() ? 1 : 0, 175 color); 176 } 177 178 /** 179 * Sets the currently selected border in the dialog. 180 * @param border the border to select 181 */ 182 public void setSelectedBorder(Border border) { 183 if (border instanceof MatteBorder) { 184 MatteBorder matteBorder = (MatteBorder)border; 185 color = matteBorder.getMatteColor(); 186 Insets insets = matteBorder.getBorderInsets(); 187 topButton.setSelected(insets.top > 0); 188 leftButton.setSelected(insets.left > 0); 189 bottomButton.setSelected(insets.bottom > 0); 190 rightButton.setSelected(insets.right > 0); 191 } 192 } 193 194 /** 195 * Updates the border of the preview label. 196 */ 197 private void updatePreviewBorder() { 198 previewLabel.setBorder( 199 BorderFactory.createCompoundBorder( 200 BorderFactory.createTitledBorder("Preview"), 201 BorderFactory.createCompoundBorder( 202 BorderFactory.createEmptyBorder(5, 5, 5, 5), 203 getSelectedBorder()))); 204 } 205 206 /** 207 * A controller that listens to selection events on the buttons. 208 */ 209 private class PreviewLabelUpdater implements ItemListener { 210 211 /** 212 * Creates a new preview label updater. 213 */ 214 public PreviewLabelUpdater() {} 215 216 /** 217 * Updates the preview label. 218 * @param e the event that was fired 219 */ 220 public void itemStateChanged(ItemEvent e) { 221 updatePreviewBorder(); 222 } 223 } 224 225 /** 226 * An action for letting the user select a new border color from a chooser. 227 */ 228 private class ColorAction extends AbstractAction { 229 230 public ColorAction() { 231 putValue(SMALL_ICON, new ImageIcon( 232 StyleExtension.class.getResource("res/img/color_bg.gif"))); 233 } 234 235 public void actionPerformed(ActionEvent e) { 236 Color c = JColorChooser.showDialog(null, "Choose Border Color", 237 color); 238 if (c != null) { 239 color = c; 240 updatePreviewBorder(); 241 } 242 } 243 } 244}