package org.pentaho.openformula.ui; import org.pentaho.reporting.libraries.formula.function.FunctionDescription; import javax.swing.*; import javax.swing.event.EventListenerList; import java.awt.*; import java.util.HashMap; public class MultiplexFunctionParameterEditor implements FunctionParameterEditor { private class ParameterUpdateHandler implements ParameterUpdateListener { private ParameterUpdateHandler() { } public void parameterUpdated( final ParameterUpdateEvent event ) { final ParameterUpdateListener[] updateListeners = listeners.getListeners( ParameterUpdateListener.class ); for ( int i = 0; i < updateListeners.length; i++ ) { final ParameterUpdateListener listener = updateListeners[ i ]; listener.parameterUpdated( event ); } } } private HashMap<String, FunctionParameterEditor> editors; private JPanel panel; private EventListenerList listeners; private FunctionParameterEditor activeEditor; private DefaultFunctionParameterEditor defaultEditor; private ParameterUpdateHandler parameterUpdateHandler; private FieldDefinition[] fieldDefinitions; public static final FieldDefinition[] EMPTY_FIELDS = new FieldDefinition[ 0 ]; private FunctionDescription selectedFunction; private int functionStartIndex; private JPanel rootPanel; public MultiplexFunctionParameterEditor() { parameterUpdateHandler = new ParameterUpdateHandler(); listeners = new EventListenerList(); fieldDefinitions = EMPTY_FIELDS; panel = new JPanel(); panel.setLayout( new BorderLayout() ); rootPanel = new JPanel(); rootPanel.setLayout( new CardLayout() ); rootPanel.add( "2", panel ); rootPanel.add( "1", Box.createRigidArea( new Dimension( 650, 250 ) ) ); editors = new HashMap<String, FunctionParameterEditor>(); defaultEditor = new DefaultFunctionParameterEditor(); } public void addParameterUpdateListener( final ParameterUpdateListener parameterUpdateListener ) { listeners.add( ParameterUpdateListener.class, parameterUpdateListener ); } public void removeParameterUpdateListener( final ParameterUpdateListener parameterUpdateListener ) { listeners.remove( ParameterUpdateListener.class, parameterUpdateListener ); } public Component getEditorComponent() { return rootPanel; } public void setFields( final FieldDefinition[] fieldDefinitions ) { this.fieldDefinitions = fieldDefinitions.clone(); if ( defaultEditor != null ) { defaultEditor.setFields( fieldDefinitions ); } if ( activeEditor != null ) { activeEditor.setFields( fieldDefinitions ); } for ( final FunctionParameterEditor functionParameterEditor : editors.values() ) { functionParameterEditor.setFields( fieldDefinitions ); } } public DefaultFunctionParameterEditor getDefaultEditor() { return defaultEditor; } public void clearSelectedFunction() { if ( activeEditor != null ) { panel.removeAll(); activeEditor.clearSelectedFunction(); activeEditor.removeParameterUpdateListener( parameterUpdateHandler ); activeEditor.setFields( EMPTY_FIELDS ); activeEditor = null; selectedFunction = null; rootPanel.invalidate(); rootPanel.revalidate(); rootPanel.repaint(); } } @Override public void setSelectedFunction( final FunctionParameterContext context ) { final FunctionDescription fnDesc = context.getFunction(); final int functionStart = context.getFunctionInformation().getFunctionOffset(); // Ensure that the parameter field editor has been initialized. This can // happen if user manually types in the whole formula in text-area. final boolean switchParameterEditor; if ( this.selectedFunction == null ) { switchParameterEditor = true; context.setSwitchParameterEditor( true ); } else { switchParameterEditor = context.isSwitchParameterEditor(); } this.selectedFunction = fnDesc; this.functionStartIndex = functionStart; final String name = fnDesc.getCanonicalName(); if ( ( activeEditor != null ) && ( switchParameterEditor == true ) ) { activeEditor.removeParameterUpdateListener( parameterUpdateHandler ); } activeEditor = getEditor( name ); if ( activeEditor == null ) { activeEditor = defaultEditor; } if ( switchParameterEditor ) { panel.removeAll(); panel.add( activeEditor.getEditorComponent() ); activeEditor.addParameterUpdateListener( parameterUpdateHandler ); activeEditor.setFields( fieldDefinitions.clone() ); activeEditor.setSelectedFunction( context ); rootPanel.invalidate(); rootPanel.revalidate(); rootPanel.repaint(); } else { activeEditor.setSelectedFunction( context ); } } public void setEditor( final String function, final FunctionParameterEditor editor ) { editors.put( function, editor ); } public FunctionParameterEditor getEditor( final String function ) { return editors.get( function ); } }