Package com.cedarsoft.spring.rcp.hierarchy

Source Code of com.cedarsoft.spring.rcp.hierarchy.HierarchyDetailsModel

package com.cedarsoft.spring.rcp.hierarchy;

import com.cedarsoft.spring.SpringSupport;
import com.cedarsoft.spring.rcp.PageComponentContextAware;
import com.cedarsoft.spring.rcp.events.DetailsTreeSelectionEvent;
import com.cedarsoft.lookup.Lookup;
import com.cedarsoft.utils.Renderer;
import com.cedarsoft.utils.TypeRegistry;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.richclient.application.Application;
import org.springframework.richclient.application.ApplicationServices;
import org.springframework.richclient.application.PageComponentContext;
import org.springframework.richclient.core.DefaultMessage;
import org.springframework.richclient.dialog.TitlePane;
import org.springframework.richclient.factory.ComponentFactory;
import org.springframework.richclient.form.Form;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import java.awt.BorderLayout;
import java.awt.Component;

/**
*
*/
public class HierarchyDetailsModel implements HierarchyTree.SelectionListener, ApplicationListener {
  @NotNull
  private final TypeRegistry<HierarchyLayer<?, ?>> hierarchyLayers;

  private ApplicationListener delegatingApplicationListener;

  /**
   * Contains the top panel
   */
  @NotNull
  private final JPanel topPanel = new JPanel( new BorderLayout() );

  /**
   * The title pane that is used when *no* other content for the top panel is available
   */
  @NotNull
  private final TitlePane titlePane = new TitlePane();

  /**
   * Containst he content
   */
  @NotNull
  private final JPanel contentPanel = new JPanel( new BorderLayout() );

  private Object currentlySelectedObject;

  public HierarchyDetailsModel( @NotNull TypeRegistry<HierarchyLayer<?, ?>> hierarchyLayers ) {
    this.hierarchyLayers = hierarchyLayers;
  }

  @Override
  public void unselect( @NotNull DetailsTreeSelectionEvent event ) {
    //noinspection AssignmentToNull
    delegatingApplicationListener = null;
  }

  @Override
  public void select( @NotNull DetailsTreeSelectionEvent event ) {
    currentlySelectedObject = event.getObject();
    //noinspection unchecked
    HierarchyLayer<Object, ?> layer = ( HierarchyLayer<Object, ?> ) hierarchyLayers.getElement( currentlySelectedObject.getClass() );

    //Clean up
    contentPanel.removeAll();
    topPanel.removeAll();

    //noinspection AssignmentToNull
    delegatingApplicationListener = null;

    Renderer<Object, Object> renderer = getRenderer( layer );

    //Now fill it
    //noinspection unchecked
    DetailsProvider<Object> detailsProvider = layer.getLookup().lookup( DetailsProvider.class );
    if ( detailsProvider != null ) {
      contentPanel.add( createDetailsComponent( detailsProvider, currentlySelectedObject ), BorderLayout.CENTER );
    } else {
      contentPanel.add( new JPanel(), BorderLayout.CENTER );
    }

    //noinspection unchecked
    TitleProvider<Object> titleProvider = layer.getLookup().lookup( TitleProvider.class );
    if ( titleProvider != null ) {
      topPanel.add( createTitleComponent( titleProvider, currentlySelectedObject ) );
    } else {
      //Set the title based on the selected object
      titlePane.setTitle( renderer.render( currentlySelectedObject, null ) );
      titlePane.setMessage( new DefaultMessage( getMessage( currentlySelectedObject.getClass().getName() + ".message" ) ) );
      topPanel.add( titlePane.getControl(), BorderLayout.CENTER );
    }

    updateContentPanelBorder();
    contentPanel.validate();
    contentPanel.repaint();
    topPanel.validate();
    topPanel.repaint();
  }

  @NotNull
  protected JComponent createTitleComponent( @NotNull TitleProvider<Object> provider, @NotNull Object selectedObject ) {
    Lookup details = provider.getTitle( selectedObject );

    //Insert the component
    JComponent component;
    DetailsComponentFactory componentFactory = details.lookup( DetailsComponentFactory.class );
    if ( componentFactory != null ) {
      component = componentFactory.createComponent();
    } else {
      component = details.lookup( JComponent.class );
      if ( component == null ) {
        throw new IllegalStateException( "No componentFactory and no component provided for " + selectedObject );
      }
    }

    component.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) );
    return component;
  }

  /**
   * Returns the details component
   *
   * @param provider       the details provider
   * @param selectedObject the selected object
   * @return the details component for the given provider and selected object
   */
  @NotNull
  private Component createDetailsComponent( @NotNull DetailsProvider<Object> provider, @NotNull Object selectedObject ) {
    Lookup details = provider.getDetails( selectedObject );

    //Delegate the view
    PageComponentContextAware pageComponentContextAware = details.lookup( PageComponentContextAware.class );
    if ( pageComponentContextAware != null ) {
      pageComponentContextAware.updateContext( getContext() );
    }

    //When a form is available, set the title pane as messagable
    Form form = details.lookup( Form.class );
    if ( form != null ) {
      form.newSingleLineResultsReporter( titlePane );
    }

    //Register delegating listener
    delegatingApplicationListener = details.lookup( ApplicationListener.class );

    //Insert the component
    Component component;
    DetailsComponentFactory componentFactory = details.lookup( DetailsComponentFactory.class );
    if ( componentFactory != null ) {
      component = componentFactory.createComponent();
    } else {
      component = details.lookup( Component.class );
      if ( component == null ) {
        throw new IllegalStateException( "No componentFactory and no component provided for " + selectedObject );
      }
    }
    return component;
  }

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

  protected void updateContentPanelBorder() {
    assert contentPanel.getComponentCount() == 1;
    Component centerComponent = contentPanel.getComponent( 0 );
    if ( centerComponent instanceof JScrollPane ) {
      contentPanel.setBorder( BorderFactory.createEmptyBorder() );
    } else {
      contentPanel.setBorder( BorderFactory.createEmptyBorder( 5, 5, 5, 5 ) );
    }
  }

  @NotNull
  private final Renderer<Object, Object> fallbackRenderer = new TranslateClassNameRenderer();

  @NotNull
  protected Renderer<Object, Object> getRenderer( @NotNull HierarchyLayer<Object, ?> layer ) {
    //noinspection unchecked
    Renderer<Object, Object> renderer = layer.getLookup().lookup( Renderer.class );
    if ( renderer == null ) {
      return fallbackRenderer;
    } else {
      return renderer;
    }
  }

  @NotNull
  public JPanel getContentPanel() {
    return contentPanel;
  }

  /**
   * Returns the title pane control.
   * The title pane control is shown at the top of the details panel
   *
   * @return the title pane control
   */
  @NotNull
  public JComponent getTopPanel() {
    return topPanel;
  }

  @NotNull
  public PageComponentContext getContext() {
    if ( context == null ) {
      throw new IllegalStateException( "Context not initialized" );
    }
    return context;
  }

  public void setContext( @NotNull PageComponentContext context ) {
    if ( this.context != null ) {
      throw new IllegalStateException( "context still initialized" );
    }
    this.context = context;
  }

  @Nullable
  public Object getCurrentlySelectedObject() {
    return currentlySelectedObject;
  }

  private PageComponentContext context;


  //Spring support delegates

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

  public ComponentFactory getComponentFactory() {
    return SpringSupport.INSTANCE.getComponentFactory();
  }

  public <S> S getService( Class<S> serviceType ) {
    return SpringSupport.INSTANCE.getService( serviceType );
  }

  public ApplicationServices getApplicationServices() {
    return SpringSupport.INSTANCE.getApplicationServices();
  }

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

  public Application getApplication() {
    return SpringSupport.INSTANCE.getApplication();
  }

  public 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 );
  }
}
TOP

Related Classes of com.cedarsoft.spring.rcp.hierarchy.HierarchyDetailsModel

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.