/*! * 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.designer.core.xul; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.pentaho.reporting.designer.core.DesignerContextComponent; import org.pentaho.reporting.designer.core.ReportDesignerContext; import org.pentaho.reporting.designer.core.actions.DesignerContextAction; import org.pentaho.reporting.libraries.base.util.ObjectUtilities; import org.pentaho.ui.xul.XulComponent; import org.pentaho.ui.xul.XulDomContainer; import org.pentaho.ui.xul.components.XulMenuitem; import org.pentaho.ui.xul.dom.Element; import org.pentaho.ui.xul.impl.AbstractXulComponent; import org.pentaho.ui.xul.swing.SwingElement; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; /** * Todo: Document Me * * @author Thomas Morgner */ public class ActionSwingMenuitem extends SwingElement implements DesignerContextComponent, XulMenuitem { private class InlineActionForward implements ActionListener { protected InlineActionForward() { } public void actionPerformed( final ActionEvent evt ) { final String command = getCommand(); if ( command != null ) { invoke( command ); } } } private static final Log logger = LogFactory.getLog( ActionSwingMenuitem.class ); protected class ActionChangeHandler implements PropertyChangeListener { protected ActionChangeHandler() { } /** * Receives notification of a property change event. * * @param event the property change event. */ public void propertyChange( final PropertyChangeEvent event ) { try { final String propertyName = event.getPropertyName(); final Action actionImpl = getActionImpl(); if ( "selected".equals( propertyName ) ||//NON-NLS Action.SELECTED_KEY.equals( propertyName ) ) { setSelected( Boolean.TRUE.equals( event.getNewValue() ) ); } else if ( "enabled".equals( propertyName ) )//NON-NLS { setDisabled( actionImpl.isEnabled() == false ); } else if ( "visible".equals( propertyName ) ) //NON-NLS { setVisible( Boolean.TRUE.equals( event.getNewValue() ) ); } else if ( propertyName.equals( Action.NAME ) ) { setLabel( (String) actionImpl.getValue( Action.NAME ) ); } else if ( propertyName.equals( Action.SHORT_DESCRIPTION ) ) { ActionSwingMenuitem.this.setTooltiptext( (String) actionImpl.getValue( Action.SHORT_DESCRIPTION ) ); } if ( propertyName.equals( Action.ACCELERATOR_KEY ) ) { refreshKeystroke( actionImpl ); } else if ( propertyName.equals( Action.MNEMONIC_KEY ) ) { refreshMnemonic( actionImpl ); } } catch ( Exception e ) { ActionSwingMenuitem.logger.warn( "Error on PropertyChange in ActionSwingMenuItem: ", e );//NON-NLS } } } private String image; private String onCommand; private JMenuItem menuitem; private Action action; private String actionClass; private ActionChangeHandler actionChangeHandler; private ReportDesignerContext reportDesignerContext; public static final String RADIO_MENUITEM = "radio-menuitem"; public static final String CHECKBOX_MENUITEM = "checkbox-menuitem"; public static final String MENUITEM = "menuitem"; public ActionSwingMenuitem( final Element self, final XulComponent parent, final XulDomContainer domContainer, final String tagName ) { this( tagName ); } public ActionSwingMenuitem( final String tagName ) { super( tagName ); this.actionChangeHandler = new ActionChangeHandler(); this.menuitem = createComponent( tagName ); this.menuitem.addActionListener( new InlineActionForward() ); setManagedObject( menuitem ); } protected ActionChangeHandler getActionChangeHandler() { return actionChangeHandler; } protected void setActionChangeHandler( final ActionChangeHandler actionChangeHandler ) { this.actionChangeHandler = actionChangeHandler; } protected JMenuItem createComponent( final String tagName ) { if ( RADIO_MENUITEM.equalsIgnoreCase( tagName ) ) { return new JRadioButtonMenuItem(); } else if ( CHECKBOX_MENUITEM.equalsIgnoreCase( tagName ) ) { return new JCheckBoxMenuItem(); } else { return new JMenuItem(); } } public String getAcceltext() { return String.valueOf( menuitem.getAccelerator().getKeyChar() ); } public String getAccesskey() { if ( menuitem.getDisplayedMnemonicIndex() == -1 ) { return null; } return String.valueOf( menuitem.getText().charAt( menuitem.getDisplayedMnemonicIndex() ) ); } public Action getActionImpl() { return action; } public String getAction() { return actionClass; } public void setAction( final Action action ) { if ( this.action != null ) { this.action.removePropertyChangeListener( actionChangeHandler ); uninstallAction( this.action ); } if ( action != null ) { this.actionClass = action.getClass().getName(); this.action = action; } else { this.actionClass = null; this.action = null; } if ( this.action != null ) { this.action.addPropertyChangeListener( actionChangeHandler ); installAction( this.action ); } } public void setAction( final String action ) { if ( this.action != null ) { this.action.removePropertyChangeListener( actionChangeHandler ); uninstallAction( this.action ); } this.actionClass = action; if ( this.actionClass != null ) { this.action = ObjectUtilities.loadAndInstantiate( actionClass, ActionSwingMenuitem.class, Action.class ); } if ( this.action != null ) { this.action.addPropertyChangeListener( actionChangeHandler ); installAction( this.action ); } } protected void uninstallAction( final Action oldAction ) { if ( oldAction != null ) { menuitem.removeActionListener( oldAction ); oldAction.removePropertyChangeListener( actionChangeHandler ); final Object o = oldAction.getValue( Action.ACCELERATOR_KEY ); if ( o instanceof KeyStroke ) { final KeyStroke k = (KeyStroke) o; menuitem.unregisterKeyboardAction( k ); } } } protected void installAction( final Action newAction ) { if ( newAction != null ) { menuitem.addActionListener( newAction ); newAction.addPropertyChangeListener( actionChangeHandler ); setLabel( (String) ( newAction.getValue( Action.NAME ) ) ); setTooltiptext( (String) ( newAction.getValue( Action.SHORT_DESCRIPTION ) ) ); setDisabled( this.action.isEnabled() == false ); refreshMnemonic( newAction ); refreshKeystroke( newAction ); final Object rawSelectedSwing = action.getValue( Action.SELECTED_KEY ); if ( rawSelectedSwing != null ) { setSelected( Boolean.TRUE.equals( rawSelectedSwing ) ); } else { final Object rawSelectedPrd = action.getValue( "selected" ); setSelected( Boolean.TRUE.equals( rawSelectedPrd ) ); } final Object rawVisible = action.getValue( "visible" ); if ( rawVisible != null ) { setVisible( Boolean.TRUE.equals( rawVisible ) ); } } } public void setReportDesignerContext( final ReportDesignerContext context ) { this.reportDesignerContext = context; if ( action instanceof DesignerContextAction ) { final DesignerContextAction dca = (DesignerContextAction) action; dca.setReportDesignerContext( reportDesignerContext ); } } public ReportDesignerContext getReportDesignerContext() { return reportDesignerContext; } public boolean isDisabled() { return !menuitem.isEnabled(); } public String getLabel() { return menuitem.getText(); } public void setAcceltext( final String accel ) { menuitem.setAccelerator( KeyStroke.getKeyStroke( accel ) ); } public void setAccesskey( final String accessKey ) { if ( accessKey == null || accessKey.length() == 0 ) { menuitem.setMnemonic( 0 ); } else { menuitem.setMnemonic( accessKey.charAt( 0 ) ); } } public void setDisabled( final boolean disabled ) { menuitem.setEnabled( !disabled ); } public void setDisabled( final String disabled ) { menuitem.setEnabled( !Boolean.parseBoolean( disabled ) ); } public void setVisible( final boolean visible ) { super.setVisible( visible ); menuitem.setVisible( visible ); final XulComponent parent = getParent(); if ( parent instanceof AbstractXulComponent ) { final AbstractXulComponent parentComp = (AbstractXulComponent) parent; parentComp.layout(); } } public void setLabel( final String label ) { menuitem.setText( label ); } public String getImage() { return image; } public boolean isSelected() { return menuitem.isSelected(); } public void setSelected( final boolean selected ) { menuitem.setSelected( selected ); } public void setImage( final String image ) { this.image = image; } public String getCommand() { return this.onCommand; } public void setCommand( final String command ) { this.onCommand = command; } public String toString() { return getLabel(); } private void refreshKeystroke( final Action actionImpl ) { final Object keyStroke = actionImpl.getValue( Action.ACCELERATOR_KEY ); if ( keyStroke instanceof KeyStroke == false ) { setAcceltext( null ); } else { setAcceltext( keyStroke.toString() ); } } private void refreshMnemonic( final Action actionImpl ) { final Object o = actionImpl.getValue( Action.MNEMONIC_KEY ); if ( o != null ) { if ( o instanceof Character ) { final Character c = (Character) o; setAccesskey( String.valueOf( c.charValue() ) ); } else if ( o instanceof Integer ) { final Integer c = (Integer) o; setAccesskey( String.valueOf( c.intValue() ) ); } } else { setAccesskey( "\0" ); } } }