/*! * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved. */ package org.pentaho.reporting.libraries.designtime.swing; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.EventListenerList; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.*; import java.util.Arrays; /** * A panel that edits the basic font properties. * <p/> * <ul> <li>Font-Family</li> <li>Font-Style (bold, italics)</li> <li>Font-Size</li> <li>underline</li> * <li>strikethrough</li> <li>aliasing</li></ul> * * @author Thomas Morgner */ public class BasicFontPropertiesPane extends JPanel { private class FontSizeUpdateHandler implements ListSelectionListener, DocumentListener { private boolean inUpdate; private FontSizeUpdateHandler() { } public void valueChanged( final ListSelectionEvent e ) { if ( inUpdate ) { return; } try { inUpdate = true; final Object value = fontSizeList.getSelectedValue(); if ( value != null ) { fontSizeTextBox.setText( String.valueOf( value ) ); } fireChangeEvent(); } finally { inUpdate = false; } } private void updateFromTextField() { if ( inUpdate ) { return; } try { inUpdate = true; final String value = fontSizeTextBox.getText(); if ( value != null && value.length() != 0 ) { try { fontSizeList.setSelectedValue( new Integer( value ), true ); } catch ( final NumberFormatException nfe ) { // ignore } fireChangeEvent(); } } finally { inUpdate = false; } } public void insertUpdate( final DocumentEvent e ) { updateFromTextField(); } public void removeUpdate( final DocumentEvent e ) { updateFromTextField(); } public void changedUpdate( final DocumentEvent e ) { updateFromTextField(); } } private class FontNameUpdateHandler implements ListSelectionListener, DocumentListener { private boolean inUpdate; private FontNameUpdateHandler() { } public void valueChanged( final ListSelectionEvent e ) { if ( inUpdate ) { return; } try { inUpdate = true; final Object value = fontFamilyList.getSelectedValue(); if ( value != null ) { fontFamilyTextBox.setText( (String) value ); fireChangeEvent(); } } finally { inUpdate = false; } } private void updateFromTextField() { if ( inUpdate ) { return; } try { inUpdate = true; final String value = fontFamilyTextBox.getText(); if ( value != null && value.length() != 0 ) { fontFamilyList.setSelectedValue( value, true ); } fireChangeEvent(); } finally { inUpdate = false; } } public void insertUpdate( final DocumentEvent e ) { updateFromTextField(); } public void removeUpdate( final DocumentEvent e ) { updateFromTextField(); } public void changedUpdate( final DocumentEvent e ) { updateFromTextField(); } } private class FontStyleUpdateHandler implements ListSelectionListener, ChangeListener { private FontStyleUpdateHandler() { } /** * Called whenever the value of the selection changes. * * @param e the event that characterizes the change. */ public void valueChanged( final ListSelectionEvent e ) { fireChangeEvent(); } /** * Invoked when the target of the listener has changed its state. * * @param e a ChangeEvent object */ public void stateChanged( final ChangeEvent e ) { fireChangeEvent(); } } private JTextField fontFamilyTextBox; private JTextField fontSizeTextBox; private JList fontFamilyList; private JList fontSizeList; private JList fontStyleList; private EventListenerList eventListenerList; private JCheckBox underlineCheckbox; private JCheckBox strikethroughCheckbox; private boolean extendedFontPropertiesShowing; public BasicFontPropertiesPane() { eventListenerList = new EventListenerList(); final FontNameUpdateHandler nameUpdateHandler = new FontNameUpdateHandler(); fontFamilyTextBox = new JTextField(); fontFamilyTextBox.getDocument().addDocumentListener( nameUpdateHandler ); fontFamilyList = new JList( createFontNameModel() ); fontFamilyList.addListSelectionListener( nameUpdateHandler ); final FontSizeUpdateHandler sizeUpdateHandler = new FontSizeUpdateHandler(); fontSizeTextBox = new JTextField(); fontSizeTextBox.getDocument().addDocumentListener( sizeUpdateHandler ); fontSizeList = new JList( createFontSizeModel() ); fontSizeList.addListSelectionListener( sizeUpdateHandler ); fontStyleList = new JList( createFontStyleModel() ); fontStyleList.getSelectionModel().addListSelectionListener( new FontStyleUpdateHandler() ); extendedFontPropertiesShowing = true; underlineCheckbox = new JCheckBox( Messages.getInstance().getString( "BasicFontPropertiesPane.Underline" ) ); underlineCheckbox.addChangeListener( new FontStyleUpdateHandler() ); strikethroughCheckbox = new JCheckBox( Messages.getInstance().getString( "BasicFontPropertiesPane.Strikethrough" ) ); strikethroughCheckbox.addChangeListener( new FontStyleUpdateHandler() ); } protected boolean isExtendedFontPropertiesShowing() { return extendedFontPropertiesShowing; } public void setExtendedFontPropertiesShowing( final boolean extendedFontPropertiesShowing ) { this.extendedFontPropertiesShowing = extendedFontPropertiesShowing; underlineCheckbox.setVisible( extendedFontPropertiesShowing ); strikethroughCheckbox.setVisible( extendedFontPropertiesShowing ); } /** * @noinspection ReuseOfLocalVariable */ public void init() { setLayout( new GridBagLayout() ); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets( 5, 5, 0, 5 ); add( new JLabel( Messages.getInstance().getString( "BasicFontPropertiesPane.FontFamily" ) ), gbc ); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 0; gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets( 5, 5, 0, 5 ); add( new JLabel( Messages.getInstance().getString( "BasicFontPropertiesPane.FontStyle" ) ), gbc ); gbc = new GridBagConstraints(); gbc.gridx = 2; gbc.gridy = 0; gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets( 5, 5, 0, 5 ); add( new JLabel( Messages.getInstance().getString( "BasicFontPropertiesPane.FontSize" ) ), gbc ); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 1; gbc.anchor = GridBagConstraints.WEST; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 1; gbc.insets = new Insets( 5, 5, 0, 5 ); add( fontFamilyTextBox, gbc ); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 2; gbc.anchor = GridBagConstraints.WEST; gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 1; gbc.weighty = 1; gbc.insets = new Insets( 0, 5, 5, 5 ); add( new JScrollPane( fontFamilyList ), gbc ); gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 1; gbc.gridheight = 2; gbc.fill = GridBagConstraints.BOTH; gbc.anchor = GridBagConstraints.WEST; gbc.weightx = 1; gbc.weighty = 1; gbc.insets = new Insets( 5, 5, 5, 5 ); add( new JScrollPane( fontStyleList ), gbc ); gbc = new GridBagConstraints(); gbc.gridx = 2; gbc.gridy = 1; gbc.anchor = GridBagConstraints.WEST; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 1; gbc.insets = new Insets( 5, 5, 0, 5 ); add( fontSizeTextBox, gbc ); gbc = new GridBagConstraints(); gbc.gridx = 2; gbc.gridy = 2; gbc.anchor = GridBagConstraints.WEST; gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 1; gbc.weighty = 1; gbc.insets = new Insets( 0, 5, 5, 5 ); add( new JScrollPane( fontSizeList ), gbc ); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 3; gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets( 0, 5, 0, 5 ); add( underlineCheckbox, gbc ); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 4; gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets( 0, 5, 0, 5 ); add( strikethroughCheckbox, gbc ); final Component aliasPane = createAliasPanel(); if ( aliasPane != null ) { gbc = new GridBagConstraints(); gbc.gridx = 1; gbc.gridy = 4; gbc.gridwidth = 2; gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets( 0, 5, 0, 5 ); add( aliasPane, gbc ); } final JComponent previewPane = createPreviewPane(); if ( previewPane != null ) { gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 5; gbc.gridwidth = 3; gbc.anchor = GridBagConstraints.WEST; gbc.weightx = 1; gbc.weighty = 1; gbc.fill = GridBagConstraints.BOTH; gbc.insets = new Insets( 5, 5, 5, 5 ); add( previewPane, gbc ); } } public String getFontFamily() { return fontFamilyTextBox.getText(); } public void setFontFamily( final String fontFamily ) { this.fontFamilyTextBox.setText( fontFamily ); } public int getFontSize() { try { return Integer.parseInt( fontSizeTextBox.getText() ); } catch ( final NumberFormatException nfe ) { // ignore exception return 10; } } public void setFontSize( final int fontSize ) { this.fontSizeTextBox.setText( String.valueOf( fontSize ) ); } public int getFontStyle() { final int index = fontStyleList.getSelectedIndex(); if ( index < 0 || index > 3 ) { return 0; } return index; } public void setFontStyle( final int fontStyle ) { if ( fontStyle < 0 || fontStyle > 3 ) { this.fontStyleList.setSelectedIndex( 0 ); } else { this.fontStyleList.setSelectedIndex( fontStyle ); } } public boolean isUnderlined() { return underlineCheckbox.isSelected(); } public void setUnderlined( final boolean underlined ) { this.underlineCheckbox.setSelected( underlined ); } public boolean isStrikeThrough() { return strikethroughCheckbox.isSelected(); } public void setStrikeThrough( final boolean strikeThrough ) { this.strikethroughCheckbox.setSelected( strikeThrough ); } protected JComponent createPreviewPane() { return null; } protected Component createAliasPanel() { return null; } public void addChangeListener( final ChangeListener changeListener ) { if ( changeListener == null ) { throw new NullPointerException(); } eventListenerList.add( ChangeListener.class, changeListener ); } public void removeChangeListener( final ChangeListener changeListener ) { if ( changeListener == null ) { throw new NullPointerException(); } eventListenerList.remove( ChangeListener.class, changeListener ); } protected void fireChangeEvent() { final ChangeEvent event = new ChangeEvent( this ); final ChangeListener[] changeListeners = eventListenerList.getListeners( ChangeListener.class ); for ( int i = 0; i < changeListeners.length; i++ ) { final ChangeListener changeListener = changeListeners[ i ]; changeListener.stateChanged( event ); } } /** * The model's item index matches the AWT-font-style flags. * * @return */ private DefaultListModel createFontStyleModel() { final DefaultListModel model = new DefaultListModel(); model.addElement( Messages.getInstance().getString( "BasicFontPropertiesPane.FontStylePlain" ) ); model.addElement( Messages.getInstance().getString( "BasicFontPropertiesPane.FontStyleBold" ) ); model.addElement( Messages.getInstance().getString( "BasicFontPropertiesPane.FontStyleItalics" ) ); model.addElement( Messages.getInstance().getString( "BasicFontPropertiesPane.FontStyleBoldItalics" ) ); return model; } private DefaultListModel createFontNameModel() { final String[] availableFontFamilyNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); Arrays.sort( availableFontFamilyNames ); final DefaultListModel retval = new DefaultListModel(); for ( int i = 0; i < availableFontFamilyNames.length; i++ ) { final String familyName = availableFontFamilyNames[ i ]; retval.addElement( familyName ); } return retval; } private DefaultListModel createFontSizeModel() { final Integer[] fontSizes = new Integer[] { 6, 8, 10, 12, 14, 16, 18, 20, 24, 28, 32, 36, 48, 72 }; final DefaultListModel retval = new DefaultListModel(); for ( int i = 0; i < fontSizes.length; i++ ) { final Integer fontSize = fontSizes[ i ]; retval.addElement( fontSize ); } return retval; } }