|      |    |  
| SR-JRC | a java richclient framework | 
      |       create a dynamically loadable application  The entrypoint of a GUI-application is SRStarter, which is part  of SRJRCFrames and is the same for all applications. You "only"  need to create the loadable part of the application.  From a thechnical point of view this means, that you won't create a  root-frame window, but use the space offered by the application frame  SRStarter. In the sense of MVC your application will be the C -  the controller.  The root window of the application is of type     To ease the creation of an application class, the framework offers the  base class  
public class SampleApp extends AbstractApplication<SampleCfg> {
} The default configuration of the application will be provided by a context-definition you write (see Configuration) and the application frame SRStarter will overwrite those settings with the values read from the users environment. Of cause, this will be performed before giving control to the instance of your application. Ingredients of a minimalistic application
 Let's look a bit closer at each point ...   To give all windows and icons of all applications the same look, neither  the menue, nor the toolbar will be defined by using  
private enum Command {
   FILE_NEW, SEP_FILE, FILE_OPEN,
   EDIT_COPY, EDIT_RELEASE, SEP_EDIT, EDIT_DELETE,
   VIEW_REFRESH
}    As the naming suggests, there's some logic in it. The actionhandler splits  the Enum-names at the "_" so the  The application frame SRStarter adds some menue entries by its own. That includes an action to close all applications, an action to switch to another applications window, to open the common preferences editor or to start the browser for the help pages. There are no restrictions on the menue callbacks, so any method is valid for menue usage.   To get a method executed at selection of a menue entry, both need to  marry - that's what's   
class SampleActionHandler extends AbstractActionHandler
                          implements ApplicationActionHandler {
   public SampleActionHandler(String name) {
      super(name);
   }
   @Override
   public void init() {
      setupAction(getName(), Command.FILE_NEW, new AbstractActionCallback() {
         @Override
         public void actionPerformed(ActionEvent ae) {
            doCreateSample(ae);
         }
      }, KeyEvent.VK_N
       , AccessMode.APP_READ);
       ...
   }
   public Enum The constructor has a name-parameter just to know for whom it is working for.      The methods  To support context menues, there's a variant of init, that takes a context object as parameter: 
@Override
public void init(Object contextObj) {
   setupAction(getName(),
               Command.FILE_OPEN,
               new AbstractActionContextCallback(contextObj) {
                   @Override
                   public void actionPerformed(ActionEvent ae) {
                      doEditSample(new ActionContextEvent(ae, getContext()));
                   }
               },
               KeyEvent.VK_O);
    ...
}
    For this usecase there's an extended callback-class   
public SampleApp() {
   super(SampleApp.class.getSimpleName());
   setActionHandler(new SampleActionHandler(getName()));
}
    A GUI application without window content doesn't make much sense. As we don't know, whether we would like to change that content one day, we don't code it in the application, but use another class: 
@Override
protected JComponent createPane() {
    if (content == null) {
       view = new AddressTableView(getInitialData(),
                                   EventSelectionModel.SINGLE_SELECTION,
                                   null);
       view.setSelectionChangedExecutor(new AbstractAction() {
          private static final long serialVersionUID = 1L;
             
             
          public void actionPerformed(ActionEvent e) {
             selectionChanged(e);
          }
       });
       view.setPopDoubleLeftExecutor(new AbstractAction() {
          private static final long serialVersionUID = 1L;
             
             
          public void actionPerformed(ActionEvent e) {
             popupDoubleLeft(e);
          }
       });
       view.setPopSingleRightExecutor(new AbstractAction() {
          private static final long serialVersionUID = 1L;
             
             
          public void actionPerformed(ActionEvent e) {
             popupSingleRight(e);
          }
       });
       content = new ApplicationPage(getName(), view.getView());
    }
    return content;
}    The instance of    The class  The    The messagepart of all  
public class SampleStatusBar extends AbstractStatusBar {
   private static final long serialVersionUID = 1L;
    
    
   @Override
   protected void checkExtends() {}
    
    
   @Override
   protected void updateExtends() {}
}  is a major design goal of SRJRCFrames, so you need a listener for the events from other applications. If you don't care about others, leave that methodbody empty ... 
@Override
public void onApplicationEvent(ApplicationEvent arg0) {
   // do nothing
}  The counterpart of the listener is the tossing of events. There's an application service for that purpose: 
if (aePublisher == null) {
   aePublisher = (ApplicationEventPublisher) 
                 ApplicationServiceProvider.getService(ApplicationEventPublisher.class);
}  When we have an instance of that service, we could inform others of our existance: 
aePublisher.publishEvent(new SampleAppStartedEvent("hello world"));  If the user selects the menue-entry "Preferences", the application frame SRStarter asks every loaded application for an edtior page and assembles a preferences dialog from that pages. The application frame adds standardpages for common use and shows all pages in a tabbed view - so each page can be randomly activated. To offer such an editor page, ... 
public JComponent getConfigPage() {
   if (cfgEdit == null)
      cfgEdit = new ConfigEditor(getAppConfig());
   return cfgEdit;
}    If your application does not have any userlevel properties, your function  may return  
class ConfigEditor extends AbstractEditor<SampleCfg> {
   private static final long serialVersionUID = 1L;
   public ConfigEditor(SampleCfg instance) {
       super(instance, false);
   }
   @Override
   protected JComponent buildPanel() {
      if (msgSource == null)
         msgSource = ApplicationServiceProvider.getService(MessageSource.class);
      FormLayout layout = new FormLayout("left:max(100dlu;pref), 3dlu, 100dlu:grow");
      DefaultFormBuilder builder = new DefaultFormBuilder(layout);
      String prefix = SampleCfg.class.getSimpleName() + ".";
      PresentationModel    Your sample application will now look like this: 
public class SampleApp extends AbstractApplication<SampleCfg> {
   private enum Command {
      FILE_NEW, SEP_FILE, FILE_OPEN,
      EDIT_COPY, EDIT_RELEASE, SEP_EDIT, EDIT_DELETE,
      VIEW_REFRESH
   }
   class SampleActionHandler extends AbstractActionHandler
                             implements ApplicationActionHandler {
      public SampleActionHandler(String name) {
         super(name);
      }
      @Override
      public void init() {
         setupAction(getName(), Command.FILE_NEW, new AbstractActionCallback() {
             @Override
             public void actionPerformed(ActionEvent ae) {
                 doCreateSample(ae);
             }
         }, KeyEvent.VK_N
         , AccessMode.APP_READ);
         ...
      }
      @Override
      public void init(Object contextObj) {
         setupAction(getName(),
                     Command.FILE_OPEN,
                     new AbstractActionContextCallback(contextObj) {
                         @Override
                         public void actionPerformed(ActionEvent ae) {
                             doEditSample(new ActionContextEvent(ae, getContext()));
                         }
                     },
                     KeyEvent.VK_O);
         ...
      }
      public Enum  |