Package com.cedarsoft.spring.rcp.tbpanel

Source Code of com.cedarsoft.spring.rcp.tbpanel.ObjectTablePanel

package com.cedarsoft.spring.rcp.tbpanel;

import com.cedarsoft.spring.SpringSupport;
import com.cedarsoft.spring.rcp.ComponentProvider;
import com.cedarsoft.spring.rcp.PageComponentContextAware;
import com.cedarsoft.spring.rcp.table.ExtendedObjectTable;
import com.cedarsoft.spring.rcp.table.ObjectTable;
import com.cedarsoft.spring.rcp.tbpanel.aspects.ObjectTablePanelAspect;
import com.cedarsoft.spring.rcp.tbpanel.config.ObjectTableConfigurer;
import org.jdesktop.swingx.VerticalLayout;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.binding.value.ValueModel;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.richclient.application.PageComponentContext;
import org.springframework.richclient.application.ServiceNotFoundException;
import org.springframework.richclient.application.config.ApplicationObjectConfigurer;
import org.springframework.richclient.command.ActionCommand;
import org.springframework.richclient.command.CommandServices;
import org.springframework.richclient.command.config.CommandConfigurer;
import org.springframework.richclient.command.config.CommandFaceDescriptor;
import org.springframework.richclient.core.UIConstants;
import org.springframework.richclient.factory.ButtonFactory;
import org.springframework.richclient.factory.ComponentFactory;
import org.springframework.richclient.list.ListSelectionValueModelAdapter;

import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
* A panel that contains a table and some buttons on the right side.
* It is necessary to call {@link #setObjectTable(ObjectTable)} to fill the panel with content.
*
* @param <T> the type of the entries that are shown within the table
*/
public class ObjectTablePanel<T> extends JPanel implements PageComponentContextAware, ApplicationListener {
  @NotNull
  @NonNls
  private static final String COMMANDS_FACE_ID = "commandsBar";

  /**
   * Do not use directly. Use {@link #getObjectTable()} instead.
   */
  private ObjectTable<T> objectTable;

  @NotNull
  @NonNls
  protected final String objectId;
  @NotNull
  private final List<ObjectTableConfigurer<T>> configurers = new ArrayList<ObjectTableConfigurer<T>>();
  @NotNull
  private final List<SidePanelCommandsProvider> commandsProviders = new ArrayList<SidePanelCommandsProvider>();

  /**
   * Creates a new table based panel for the given object id
   *
   * @param objectId the object id
   */
  public ObjectTablePanel( @NotNull @NonNls String objectId ) {
    super( new BorderLayout( UIConstants.ONE_SPACE, UIConstants.ONE_SPACE ) );
    this.objectId = objectId;
  }

  /**
   * Applies the given aspect
   *
   * @param aspect the aspect that is applied
   */
  public void applyAspect( @NotNull ObjectTablePanelAspect<T> aspect ) {
    aspect.apply( this );
  }

  /**
   * Returns the object table (if set)
   *
   * @return the object table
   * @throws IllegalStateException
   */
  @NotNull
  public final ObjectTable<T> getObjectTable() throws IllegalStateException {
    if ( objectTable == null ) {
      throw new IllegalStateException( "Set the objectTable first" );
    }
    return objectTable;
  }

  /**
   * Sets the object table
   *
   * @param objectTable the table
   */
  public final void setObjectTable( @NotNull ObjectTable<T> objectTable ) {
    //noinspection InstanceVariableUsedBeforeInitialized
    if ( this.objectTable != null ) {
      throw new IllegalStateException( "Table still has been set!" );
    }
    this.objectTable = objectTable;

    configureTablePreShow();
    addComponents();
    configureTablePostShow();
  }

  /**
   * This method is called from {@link #setObjectTable(ObjectTable)}.
   * It creates and adds all components.
   */
  private void addComponents() {
    //add the header component
    addHeadComponent();

    //add the tail component
    addTailComponent();

    //And now add the objectTable --> this must be added last, since the head component could add some filters
    addTableComponent();

    //Now add the commands --> they depend on the final list of the object table
    addCommands();
  }

  //Add the tail component
  private void addTailComponent() {
    if ( !tailComponentProviders.isEmpty() ) {
      add( createProvidersPanel( tailComponentProviders ), BorderLayout.SOUTH );
    }
  }

  /**
   * Creates a vertical panel that contains all components created by the given providers
   *
   * @param providers the providers that are used to create the panel
   * @return a panel containing all panels created by the providers
   */
  @NotNull
  private JPanel createProvidersPanel( @NotNull List<? extends ComponentProvider> providers ) {
    if ( providers.isEmpty() ) {
      throw new IllegalArgumentException( "Need at least one provider" );
    }

    JPanel panel = getComponentFactory().createPanel( new VerticalLayout( UIConstants.ONE_SPACE ) );

    for ( ComponentProvider provider : providers ) {
      panel.add( provider.createComponent() );
    }
    return panel;
  }

  /**
   * Add the head component
   */
  private void addHeadComponent() {
    if ( !headComponentProviders.isEmpty() ) {
      List<ComponentProvider> providers = new ArrayList<ComponentProvider>( headComponentProviders );
      Collections.reverse( providers );
      add( createProvidersPanel( providers ), BorderLayout.NORTH );
    }
  }

  /**
   * Adds the commands
   */
  private void addCommands() {
    List<Collection<? extends ActionCommand>> commands = getCommands( new ListSelectionValueModelAdapter( getObjectTable().getSelectionModel() ) );

    if ( commands.isEmpty() ) {
      //No commands --> exit fast
      return;
    }

    //todo fix spring
    CommandConfigurer commandConfigurer = getService( CommandConfigurer.class );
    ApplicationObjectConfigurer configurer = getService( ApplicationObjectConfigurer.class );
    ButtonFactory bf = getToolBarButtonFactory();
    CommandsBarButtonConfigurer commandsBarButtonConfigurer = new CommandsBarButtonConfigurer();


    //Now create the button panel
    //    JPanel buttonPanel = getComponentFactory().createPanel( new VerticalLayout( UIConstants.ONE_SPACE ) );
    JPanel buttonPanel = getComponentFactory().createPanel( new VerticalLayout() );
    for ( Iterator<Collection<? extends ActionCommand>> it = commands.iterator(); it.hasNext(); ) {
      Collection<? extends ActionCommand> commandsCollection = it.next();
      for ( ActionCommand command : commandsCollection ) {
        commandConfigurer.configure( command );

        CommandFaceDescriptor face = new CommandFaceDescriptor();
        configurer.configure( face, command.getId() + '.' + COMMANDS_FACE_ID );
        command.setFaceDescriptor( COMMANDS_FACE_ID, face );

        buttonPanel.add( command.createButton( COMMANDS_FACE_ID, bf, commandsBarButtonConfigurer ) );
      }

      if ( it.hasNext() ) {
        JPanel spacer = new JPanel();
        spacer.setPreferredSize( new Dimension( 2, 2 ) );
        buttonPanel.add( spacer );
      }
    }

    add( buttonPanel, BorderLayout.EAST );
  }

  /**
   * Returns the commands that are shown in the button bar on the right side of the table
   *
   * @param selectionHolder the selection holder
   * @return the command shown on the right side of the table
   */
  @NotNull
  private List<Collection<? extends ActionCommand>> getCommands( @NotNull ListSelectionValueModelAdapter selectionHolder ) {
    List<Collection<? extends ActionCommand>> commands = new ArrayList<Collection<? extends ActionCommand>>();
    for ( SidePanelCommandsProvider commandsProvider : commandsProviders ) {
      Collection<? extends ActionCommand> commandsForProvider = commandsProvider.getCommands( selectionHolder );
      if ( commandsForProvider.isEmpty() ) {
        continue;
      }
      commands.add( commandsForProvider );
    }
    return commands;
  }

  @NotNull
  protected ButtonFactory getToolBarButtonFactory() {
    CommandServices commandServices = getService( CommandServices.class );
    return commandServices.getToolBarButtonFactory();
  }

  /**
   * Adds the table compoennt
   */
  private void addTableComponent() {
    add( getComponentFactory().createScrollPane( getObjectTable().getControl() ), BorderLayout.CENTER );
  }

  /**
   * Configures the table. This method is called from {@link #setObjectTable(ObjectTable)}.
   */
  private void configureTablePreShow() {
    for ( ObjectTableConfigurer<T> configurer : configurers ) {
      configurer.configurePreShow( objectTable );
    }
  }

  private void configureTablePostShow() {
    for ( ObjectTableConfigurer<T> configurer : configurers ) {
      configurer.configurePostShow( objectTable );
    }
  }

  @Override
  public void onApplicationEvent( ApplicationEvent event ) {
    if ( objectTable != null ) {
      objectTable.onApplicationEvent( event );
    }
  }

  @Nullable
  public List<? extends ObjectTableConfigurer<T>> getConfigurers() {
    return Collections.unmodifiableList( configurers );
  }

  public final void addConfigurer( @NotNull ObjectTableConfigurer<T> configurer ) {
    //noinspection InstanceVariableUsedBeforeInitialized
    if ( this.objectTable != null ) {
      throw new IllegalStateException( "Configurer should only be set if the object table is null" );
    }
    configurers.add( configurer );
  }

  @NotNull
  public List<? extends SidePanelCommandsProvider> getCommandProviders() {
    return Collections.unmodifiableList( commandsProviders );
  }

  /**
   * Adds a command provider for the given panel
   *
   * @param commandsProvider the command provider that is added
   */
  public final void addCommandProvider( @NotNull SidePanelCommandsProvider commandsProvider ) {
    //noinspection InstanceVariableUsedBeforeInitialized
    if ( this.objectTable != null ) {
      throw new IllegalStateException( "SidePanelCommandsProvider should only be set if the object table is null" );
    }
    commandsProviders.add( commandsProvider );
  }

  /**
   * Updates the page component context
   *
   * @param context the context
   */
  @Override
  public void updateContext( @NotNull PageComponentContext context ) {
    if ( objectTable != null ) {
      getObjectTable().setStatusBar( context.getWindow().getStatusBar() );
    }

    for ( SidePanelCommandsProvider commandsProvider : commandsProviders ) {
      commandsProvider.registerLocalCommandExecutors( context );
    }

    registerLocalCommandExecutors( context );
    contextUpdated( context );
  }

  /**
   * This method is called when the context has been updated
   *
   * @param context the new context
   */
  @Deprecated
  protected void contextUpdated( @NotNull PageComponentContext context ) {
  }

  /**
   * @param context
   * @deprecated the commands providers are automatically called
   */
  @Deprecated
  protected void registerLocalCommandExecutors( @NotNull PageComponentContext context ) {
  }

  @NotNull
  private List<ComponentProvider> headComponentProviders = new ArrayList<ComponentProvider>();

  @NotNull
  public List<? extends ComponentProvider> getHeadComponentProviders() {
    return Collections.unmodifiableList( headComponentProviders );
  }

  @Deprecated
  @Nullable
  public ComponentProvider getHeadComponentProvider() {
    if ( headComponentProviders.isEmpty() ) {
      return null;
    } else {
      return headComponentProviders.get( 0 );
    }
  }

  /**
   * Adds a head component provider.
   * Those providers are added in reversed order!
   * This means the component created by the first added provider is added at the *bottom* of the
   * head component.
   *
   * @param headComponentProvider the provider
   */
  public void addHeadComponentProvider( @Nullable ComponentProvider headComponentProvider ) {
    this.headComponentProviders.add( headComponentProvider );
  }

  @Deprecated
  public void setHeadComponentProvider( @Nullable ComponentProvider headComponentProvider ) {
    addHeadComponentProvider( headComponentProvider );
  }

  @NotNull
  private List<ComponentProvider> tailComponentProviders = new ArrayList<ComponentProvider>();

  @NotNull
  public List<? extends ComponentProvider> getTailComponentProviders() {
    return Collections.unmodifiableList( tailComponentProviders );
  }

  @Deprecated
  @Nullable
  public ComponentProvider getTailComponentProvider() {
    if ( tailComponentProviders.isEmpty() ) {
      return null;
    } else {
      return tailComponentProviders.get( 0 );
    }
  }

  @Deprecated
  public void setTailComponentProvider( @Nullable ComponentProvider tailComponentProvider ) {
    addTailComponentProvider( tailComponentProvider );
  }

  public void addTailComponentProvider( @Nullable ComponentProvider tailComponentProvider ) {
    this.tailComponentProviders.add( tailComponentProvider );
  }


  //// SPRING DELEGATES ////


  @NotNull
  protected String getMessage( @NotNull @NonNls String messageCode ) {
    return SpringSupport.INSTANCE.getMessage( messageCode );
  }

  @NotNull
  protected String getMessage( @NotNull @NonNls String messageCode, @NonNls Object... objects ) {
    return SpringSupport.INSTANCE.getMessage( messageCode, objects );
  }

  @NotNull
  protected ApplicationContext getApplicationContext() {
    return SpringSupport.INSTANCE.getApplicationContext();
  }

  public void publishEvent( @NotNull ApplicationEvent event ) {
    SpringSupport.INSTANCE.publishEvent( event );
  }

  public void publishCreated( @NotNull Object object ) {
    SpringSupport.INSTANCE.publishCreated( object );
  }

  public void publishDeleted( @NotNull Object object ) {
    SpringSupport.INSTANCE.publishDeleted( object );
  }

  public void publishModified( @NotNull Object object ) {
    SpringSupport.INSTANCE.publishModified( object );
  }

  @NotNull
  protected ComponentFactory getComponentFactory() throws ServiceNotFoundException {
    return getService( ComponentFactory.class );
  }

  @NotNull
  protected <T> T getService( @NotNull Class<T> serviceType ) throws ServiceNotFoundException {
    return SpringSupport.INSTANCE.getService( serviceType );
  }
}
TOP

Related Classes of com.cedarsoft.spring.rcp.tbpanel.ObjectTablePanel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.