Introduction
LindyFrame is a desktop application framework that allows the
quick development of software that supports internationalization and a modular
plugin environment. The lindyFrame plugin tutorial documents the highlights of
creating the HTML Viewer plugin that is included with the framework.
The lindyFrame plugin architecture allows the application
to dynamically load code from the installation's sub-directory, lib/plugin,
as the program is initialized when first run. Any Java JAR file placed in that
directory will be scanned for the proper contents that can be identified as a
lindyFrame plugin. Once identified the framework will attempt to add that plugin
as one of the main tabs the user will see on the right hand side of the lindyFrame
window as shown in Figure 1. As an alternative to loading plugins automatically
from the plugin directory a user may use the Tools | Plugin Management
interface to manually load plugins that thereafter will also be available for
use. Plugins may be loaded via the local file system, LAN, or Internet.
Figure 1. lindyFrame Main Interface
LindyFrame_PluginModule
The core aspect of the lindyFrame framework plugin module architecture
is oriented around the abstract LindyFrame_PluginModule class. This class implements
the Plugin Module Interface which defines the needed routines, class methods, that
are required for loading and running a plugin module. The code for the LindyFrame_PluginModule
is provided here and shown in Listing 1. below. From this code listing we
see the LindyFrame_PluginModule class has a default no argument constructor and
several methods. All plugins which will extend this class should do no initialization
work in the constructor and just allow the default super() to be called. The key
initialization for a plugin should be allocated to the initPlugin() method. The
initPlugin() method has two argument instances of Main_Frame and String. The Main_Frame
argument instance will allow a plugin to gain access to lindyFrame's Menu commands
and the String argument, path, is the plugin's location be it local or network based.
Now from the listing one should see that the initPlugin() method is commented out
for the LindyFrame_PluginModule abstract class. This is because this will force
you as a developer to implement this method in your plugin module class.
Code Listing 1: (LindyFrame_PluginModule.java)
//=================================================================
// LindyFrame_PluginModule Class
//=================================================================
//
// This class provides the abstract framework for plugin classes
// to extends in order to properly function within the lindyFrame
// application.
//
// << LindyFrame_PluginModule.java >>
//
//=================================================================
// Copyright (C) 2013-2016 Dana M. Proctor
// Version 1.5 05/21/2016
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version
// 2 of the License, or (at your option) any later version. This
~
~
~
//=================================================================
// Version 1.0 Initial LindyFrame_PluginModule Class.
// 1.1 Cleaned Up Un-needed Methods.
// 1.2 Added Interface Method shutdown().
// 1.3 Changed the Return Types for Methods getToolBar(), getPanel(),
// getControlledToolBar(), & getControlledPanel() From JToolBar
// & JPanel to JComponent. Class Instance toolBar & panel Changed
// Accordingly.
// 1.4 Added Interface Methods start() & stop().
// 1.5 Updated Copyright.
// 1.6 Source Formatting Changes & Class Instance pathFileName Changed to
// path_FileName. Removed All getControlledXXX() Methods.
// 1.7 Returned Methods getControlledXXX().
//
//-----------------------------------------------------------------
// danap@dandymadeproductions.com
//=================================================================
package com.dandymadeproductions.lindyframe.plugin;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JMenuBar;
/**
* The LindyFrame_PluginModule class provides the abstract framework
* for plugin classes to extends in order to properly function within
* the lindyFrame application.
*
* @author Dana M. Proctor
* @version 1.7 10/03/2016
*/
public abstract class LindyFrame_PluginModule implements PluginModuleInterface
{
// Class Instances.
//protected Main_Frame parent;
protected String path_FileName;
public String name;
public String author;
protected String version;
protected String description;
protected String category;
protected int size;
protected ImageIcon tabIcon;
protected JMenuBar menuBar;
protected JComponent toolBar;
protected JComponent panel;
//===========================================================
// LindyFrame_PluginModule Constructor
//===========================================================
public LindyFrame_PluginModule()
{
// Just Initialize to a NULL condition.
path_FileName = null;
name = null;
author = null;
version = null;
description = null;
category = null;
size = 0;
tabIcon = null;
menuBar = null;
toolBar = null;
panel = null;
}
//==============================================================
// Class method to setup up your plugin.
// OVERIDE THIS METHOD!
//==============================================================
/*
public void initPlugin(Main_Frame mainFrame, String path)
{
// This is where the plugin should be initialized.
parent = mainFrame;
}
*/
//==============================================================
// Class methods to get/set the plugin's file name.
//==============================================================
public String getPath_FileName()
{
return path_FileName;
}
protected String getControlledPath_FileName()
{
return path_FileName;
}
//==============================================================
// Class method to get/set the plugin's name.
// Interface requirement.
//==============================================================
public String getName()
{
return name;
}
public String getControlledName()
{
return name;
}
//==============================================================
// Class method to get/set the plugin's author.
// Interface requirement.
//==============================================================
public String getAuthor()
{
return author;
}
public String getControlledAuthor()
{
return author;
}
//==============================================================
// Class method to obtain the plugin's version number.
// Interface requirement.
//==============================================================
public String getVersion()
{
return version;
}
public String getControlledVersion()
{
return version;
}
//==============================================================
// Class method to obtain the plugin's description.
// Interface requirement.
//==============================================================
public String getDescription()
{
return description;
}
public String getControlledDescription()
{
return description;
}
//==============================================================
// Class method to obtain the plugin's category.
// Interface requirement.
//==============================================================
public String getCategory()
{
return category;
}
public String getControlledCategory()
{
return category;
}
//==============================================================
// Class method to obtain the plugin's size.
// Interface requirement.
//==============================================================
public int getSize()
{
return size;
}
public int getControlledSize()
{
return size;
}
//==============================================================
// Class method to allow the collection of a image icon that
// will be used as an identifier in the lindyFrame tab structure.
//
// NOTE: The tab icon should be no larger than 16 x 16.
// Interface requirement.
//==============================================================
public ImageIcon getTabIcon()
{
return tabIcon;
}
public ImageIcon getControlledTabIcon()
{
return tabIcon;
}
//==============================================================
// Class method to obtain the plugin's JMenuBar that can be
// used to control various aspects of the modules functionality.
// Interface requirement.
//==============================================================
public JMenuBar getMenuBar()
{
return menuBar;
}
public JMenuBar getControlledMenuBar()
{
return menuBar;
}
//==============================================================
// Class method to allow the collection of a JToolBar to be
// used with the plugin module.
// Interface requirement.
//==============================================================
public JComponent getToolBar()
{
return toolBar;
}
public JComponent getControlledToolBar()
{
return toolBar;
}
//==============================================================
// Class method for returning a JComponent, JPanel or JFXPanel
// for inclusion in the application's main tab. Interface
// requirement.
//==============================================================
public JComponent getPanel()
{
return panel;
}
public JComponent getControlledPanel()
{
return panel;
}
//==============================================================
// Class method to allow the plugin to start activities back
// up after a stop() sequence.
// (USED FOR CONTROLLING THREADS)
//==============================================================
public void start()
{
// Do what you will to start again from stop.
}
//==============================================================
// Class method to allow the plugin to temporarily stop
// activities that may then be started again.
// (USED FOR CONTROLLING THREADS)
//==============================================================
public void stop()
{
// Do what you will to notify stop.
}
//==============================================================
// Class method to allow the plugin to close activities pending
// a closing of the application.
//==============================================================
public void shutdown()
{
// Do what you will to notify pending closing.
}
}
|
The key aspect of the initPlugin() method that a developer should know is that
it should create a custom JComponent object that lindyFrame will use to load into
its tabbed pane for your plugin. That JComponent should be a panel or pane and will
be what users will see when your plugin tab is selected from the framework's main
interface window on the right hand side. The correlated companion class method in
the LindyFrame_PluginModule class is the getPanel() method. That method should
return the JComponent component that is created in the initPlugin() method.
Other methods in the LindyFrame_PluginModule class,
allow the developer to return the name and an icon that will be used to identify
a plugin's tab. The name will appear as the tooltip for the tab and the icon
will become the insignia for the tab. The icon returned through the getTabIcon()
method should be no larger than 12 x 12 pixels. Two of the other getter methods
shown in the listing allows a plugin to create its own Menu and Toolbar that
will be used in conjunction with the module. Several other getter methods are
also provided that allow the plugin to provide various other information for
consumption via lindyFrame's Plugin Management interface.
HTML Viewer Plugin Example
The lindyFrame application comes with the pre-installed
plugin, HTMLViewer, that is loaded from the lib/plugins directory of
the installation. The source code for the HTMLViewer is available as a separate
download that includes all the source code files for the plugin. The download
may be found at the Dandy Made Productions' web site under the lindyFrame
application page,
HTML Viewer Plugin. The HTML Viewer plugin code provides the outline
of the discussion that follows. All resources for the discussion in this article
are made available via links at the end. Any classes given as part of this tutorial
are covered by the GPL and may be used in accordance with that license.
Like all plugins for lindyFrame a developer should create a new
class called PluginModule that extends the LindyFrame_PluginModule class.
The abbreviated code for the HTMLViewer plugin PluginModule class is shown below
in listing 2. The constructor for the new class should perform no work except
call the super() to the parent, LindyFrame_PluginModule. The new PluginModule class
should orientate initialization of components for the plugin in the initPlugin()
method. As can be seen from the listing the HTMLViewer initializes three instances,
pluginName, pluginAuthor, and htmlViewer. The first two will be used to identify
the name and author of the plugin and the third calls for the construction of a
new class that will handle the creation of the main JPanel component needed by
the plugin. Though not shown in the abbreviated listing the HTMLViewer PluginModule
class overrides all the methods of the LindyFrame_PluginModule class and either
returns directly or indirectly through the instance htmlViewer the requirements
for the plugin. A developer need not override all the getter methods for a PluginModule
class since the lindyFrame framework will substitute defaults for these instances,
but without a JPanel component no visibility will be given to your plugin.
NOTICE: All PLUGINS MUST FOLLOW THE BASIC INTERFACE DESCRIBED HERE FOR A
LindyFrame_PluginModule AND BE GIVEN THE CLASS NAME PluginModule. lindyFrame
WILL ONLY SEARCH FOR AND LOAD PLUGIN CLASSES GIVEN THE NAME PluginModule!
Code Listing 2: (PluginModule.java)
//=================================================================
// HTMLViewer PluginModule Class
//=================================================================
//
// This class provides the hook to incorporate a external plugin
// module into the lindyFrame framework.
//
// < PluginModule.java >
//
//=================================================================
// Copyright (C) 2013 Dana M. Proctor
// Version 1.0 07/26/2013
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
~
~
~
~
//-----------------------------------------------------------------
// danap@dandymadeproductions.com
//=================================================================
package com.dandymadeproductions.htmlviewer;
import javax.swing.ImageIcon;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import com.dandymadeproductions.lindyframe.gui.Main_Frame;
import com.dandymadeproductions.lindyframe.plugin.LindyFrame_PluginModule;
/**
* The PluginModule class provides the hook to incorporate a external plugin
* module into the lindyFrame framework.
*
* @author Dana M. Proctor
* @version 1.0 07/26/2013
*/
public class PluginModule extends LindyFrame_PluginModule
{
// Class Instances
private String pluginName, pluginAuthor;
private HTMLViewer htmlViewer;
//==============================================================
// PluginModule Constructor.
//==============================================================
public PluginModule()
{
super();
}
//==============================================================
// Class method to initialize your plugin.
//==============================================================
public void initPlugin(Main_Frame parentFrame, String path)
{
pluginName = "HTML Viewer";
pluginAuthor = "Dandy Made Productions";
htmlViewer = new HTMLViewer(parentFrame, path);
}
~
~
~
public String getName() {
return pluginName;
}
~
~
~
public String getAuthor() {
return pluginAuthor;
}
~
~
~
public JPanel getPanel() {
return htmlViewer.getPanel();
}
}
|
HTMLViewer Class
The HTMLViewer class is the main component of the HTMLViewer
plugin and was instantiated in the PluginModule class method initPlugin()
with the instance htmlViewer. The constructor for this class takes two
arguments, Main_Frame and String. More will be detailed of the Main_Frame
argument, but first lets speak more about of the path argument because it
is used to derive resources for the plugin
The path instance that is passed to plugin modules gives the URL that was derived
by lindyFrame in loading the plugin's JAR file. A developer should create resources
for a plugin with this in mind. The standard taken by the lindyFrame group is to
have a directory in this path, location of JAR file, by the same name as the plugin
and in this directory have images and other pertinent objects required by the plugin.
Please see Figure 2. below. With this in mind lets move on to the htmlViewer
object to understand the use of this path and the other argument in the instantiation
of this class.
Figure 2. Plugin Directory Structure
Though the HTMLViewer class is the core main object for
the HTMLViewer plugin it is not per say a main class. All plugins do
not have a main class, but as discussed previously just the PluginModule
class which lindyFrame initializes through the initPlugin() method and then
loads the various components needed to utilize the plugin. The main object
for plugins is always a Java JPanel or JFXPanel component that is the face of the plugin
in the lindyFrame application tab interface. So what we will see in the
HTMLViewer core class is the creation of a main Panel object and the
creation of resources and menu and toolbar objects. Listing 3. below
shows the HTMLViewer condensed class and as seen is composed of a constructor
and several methods. Three of the methods just return the objects indicated,
JPanel, JMenuBar, and JToolBar. The other three a version and description,
Strings and an ImageIcon. The constructor for the class creates each of these
objects directly or through additional classes.
Code Listing 3: (HTMLViewer Main Class HTMLViewer.java)
//=================================================================
// HTMLViewer
//=================================================================
//
// This class provides the main access point for setting up the
// requirements for the HTMLView plugin module for the lindyFrame
// framework.
//
// << HTMLViewer.java >>
//
//=================================================================
// Copyright (C) 2013-2016 Dana M. Proctor
// Version 1.5 11/07/2016
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version
// 2 of the License, or (at your option) any later version. This
~
~
~
//=================================================================
// Revision History
// Changes to the code should be documented here and reflected
// in the present version number. Author information should
// also be included with the original copyright author.
//=================================================================
// Version 1.0 07/27/2013 Initial HTMLViewer Class.
// 1.1 08/02/2013 Added History Functionality and URL Entry
// Capability.
// 1.2 08/29/2013 Resources Should NOT Use Local System File Separator
// Definition, But Rather Standard File Delimitor Forward
// Slash.
// 1.3 06/24/2016 Updated VERSION to Bring Class Into Sync With lindyFrame
// v2.5. Now Compiled to Comply With JRE7.
// 1.4 11/07/2016 Updated VERSION & Made Resources Specified in Jar.
// 1.5 11/07/2016 Used imagesDirectory Instead of path as Argument for
// Viewer_ToolBar. Updated Version.
//
//-----------------------------------------------------------------
// danap@dandymadeproductions.com
//=================================================================
package com.dandymadeproductions.htmlviewer;
import java.awt.BorderLayout;
~
~
~
import javax.swing.text.html.HTMLEditorKit;
import com.dandymadeproductions.lindyframe.LindyFrame;
import com.dandymadeproductions.lindyframe.gui.Main_Frame;
import com.dandymadeproductions.lindyframe.utilities.LindyFrame_ResourceBundle;
import com.dandymadeproductions.lindyframe.utilities.LindyFrame_Utils;
/**
* The HTMLViewer class provides the main access point for
* setting up the requirements for the HTMLView plugin module
* for the lindyFrame framework.
*
* @author Dana M. Proctor
* @version 1.5 11/07/2016
*/
class HTMLViewer implements ActionListener
{
// Class Instances
private ImageIcon tabIcon;
private GridBagLayout gridbag;
private GridBagConstraints constraints;
private JPanel mainPanel, urlEntryPanel, statusPanel;
private JButton historyBackButton, historyForwardButton, refreshButton;
private JTextField urlEntryTextField;
private LinkedList historyList;
protected HTMLEditorPane viewerPane;
private JProgressBar progressBar;
private JLabel statusLabel;
private Viewer_MenuBar menuBar;
private Viewer_ToolBar toolBar;
private LindyFrame_ResourceBundle resourceBundle;
private String loadingPageResource, pageNotFoundResource;
private int stateHistoryIndex;
private final static String VERSION = "Version 1.5";
private final static String DESCRIPTION = "The HTMLViewer plugin provides a mean to demostrate a module"
+ " example for the lindyFrame framework. The plugin is a basic"
+ " HTML viewer that displays the tutorial for creating plugins"
+ " with lindyFrame.";
private static final int STATE_HISTORY_LIMIT = 25;
//==============================================================
// HTMLViewer Constructor
//==============================================================
public HTMLViewer(Main_Frame parent, String path)
{
// Constructor Instances.
String pathDirectory, localeDirectory, imagesDirectory;
MenuActionListener pluginMenuListener;
// Setup the Main panel and the plugin's components.
mainPanel = new JPanel(new BorderLayout());
// ** NOTE: file/local network only, locale resource not in JAR **
pathDirectory = path + "/" + "HTMLViewer" + "/";
localeDirectory = "locale/";
imagesDirectory = "images/";
// ** NOTE: http/ftp locale resource in JAR **
// pathDirectory = path + "/" + "HTMLViewer.jar";
// localeDirectory = "lib/plugins/HTMLViewer/locale/";
// imagesDirectory = "lib/plugins/HTMLViewer/images/";
resourceBundle = new LindyFrame_ResourceBundle(pathDirectory, LindyFrame.getDebug());
resourceBundle.setLocaleResource(localeDirectory, "HTMLViewer", LindyFrame.getLocaleString());
tabIcon = resourceBundle.getResourceImage(imagesDirectory + "icons/htmlViewerIcon.png");
loadingPageResource = resourceBundle.getResourceString("HTMLViewer.label.LoadingPage", "Loading Page");
pageNotFoundResource = resourceBundle.getResourceString("HTMLViewer.label.PageNotFound",
"Page Not Found");
// Create the GUI components.
gridbag = new GridBagLayout();
constraints = new GridBagConstraints();
// URL Entry Panel.
initURLEntryPanel(imagesDirectory);
mainPanel.add(urlEntryPanel, BorderLayout.NORTH);
// HTML Panel.
initViewer();
mainPanel.add(new JScrollPane(viewerPane), BorderLayout.CENTER);
// Status Panel
initStatusPanel();
mainPanel.add(statusPanel, BorderLayout.SOUTH);
// Setup the MenuBar and ToolBar to be used by the plugin.
pluginMenuListener = new MenuActionListener(parent, this, resourceBundle);
menuBar = new Viewer_MenuBar(parent, resourceBundle, pluginMenuListener);
toolBar = new Viewer_ToolBar("HTMLViewer ToolBar", parent, imagesDirectory, resourceBundle,
pluginMenuListener);
loadPage("file:"
+ LindyFrame_Utils.getResourceBundle().getResourceFile(
"docs/Plugins/Tutorial/LindyFrame_PluginTutorial.html").getPath());
}
~
~
~
~
//==============================================================
// Class method to to the plugin's JMenuBar
//==============================================================
protected JMenuBar getMenuBar()
{
return menuBar;
}
//==============================================================
// Class method get the plugin's JToolBar
//==============================================================
protected JToolBar getToolBar()
{
return toolBar;
}
//==============================================================
// Class method to get the main panel associated with the plugin.
//==============================================================
protected JPanel getPanel()
{
return mainPanel;
}
//==============================================================
// Class method to get the plugin's version.
//==============================================================
protected String getVersion()
{
return VERSION;
}
//==============================================================
// Class method to get the plugin's description.
//==============================================================
protected String getDescription()
{
return DESCRIPTION;
}
//==============================================================
// Class method to get the icon that will be used in the
// lindyFrame tab.
//==============================================================
protected ImageIcon getTabIcon()
{
return tabIcon;
}
}
|
The constructor for the HTMLViewer class like most classes
is where the setup for the HTML Viewer plugin occurs. The first
thing that is done in the constructor is to create the JPanel, mainPanel.
This panel is the face of the plugin that users will see in the selected
tab for the HTMLViewer module. The mainPanel has several components
added to it in order to create the plugin and those objects are created
in the helper methods not shown, but called through initURLEntryPanel(),
initViewer(), and initStatusPanel(). Those methods are not pertinate to
the discussion here since they just serve to help create the GUI for
the HTML Viewer. Before the call to those additional methods it is noted
that we begin the derivation of a resource reference for the plugin that
is based on the path argument string in the constructor. LindyFrame has
the capability of installing a plugin locally automatically from the
lib/plugins directory or be loaded via the Plugin Management tool.
When a developer creates the plugin a decision should be made to allow
these local/remote resources to be either sourced in the JAR file of the
plugin or not. Note; All plugins that will be loaded remotely, Internet,
must store resouces in the JAR file.
In the HTMLViewer constructor we see the two ways that this may be
implemented, one commented out. The example uses resources that will NOT be
included in the JAR and uses three instances to derive the pathDirectory,
localeDirectory, & imagesDirectory from the path and layout that was
chosen by the plugin as shown in Figure 2. We then create a LindyFrame_ResourceBundle
based on the pathDirectory and set the locale for the plugin. The language
locale can be obtained directly from the LindyFrame API method getLocaleString().
That language locale string is chosen by the user when lindyFrame is first
run or by argument to the application. Though one could use the standard Java
API for a Resource object lindyFrame uses its own resource class which provides
greater flexibility, and control in organizing resources in a plugin environment.
In the constructor we now see the use of a resource object. The tabIcon is
acquired through the LindyFrame_ResourceBundle's getResourceImage(). In that
method we pass the imagesDirectory and the name of the image file. The tabIcon
will be returned through the class method getTabIcon() for the plugin module
so that it may be displayed in lindyFrame's main tab pane. Likewise we may
also use the resourceBundle object to obtain a getResourceString() that relates
to properly displaying language aspects of the GUI for the locale.
Now that all the main setup in the constructor has been
accomplished then the only activities left to do is to create the menu and
toolbar objects. The menu and toolbar objects for the plugin are created
through two separate classes Viewer_MenuBar and Viewer_ToolBar. An Action
Listener object is also created to handle the processing of events in the
plugin. The Action Listener class, MenuActionListener, is not covered in
this tutorial, but is supplied as a resource via links available at the
end of this tutorial.
Note: Any classes given as part of this tutorial are covered by the GPL
and may be used in accordance with that license.
HTMLViewer Viewer_MenuBar Class
The last aspect of this advanced lindyFrame plugin tutorial
that is to be dealt with is the creation of a custom menu bar and tool bar
components for the plugin. LindyFrame allows each plugin to share its
controls, action events, and create their own. As each plugin tab is
selected in the main interface of lindyFrame the MenuBar and ToolBar for
that plugin is activated and available for use. Since a tool bar houses
essential duplicate items in the form of buttons with icons as a menu system
we will just review the MenuBar object for the HTMLViewer plugin.
The partial Code Listing 4. shown below is of the HTMLViewer's Viewer_MenuBar
class. Though the menu systems has both a File and Edit entry all that is
needed to demonstrate the desired concepts is the creation of the File menu.
What one should note immediately about this class is it extends the Java JMenuBar
component so that its meets the needs of a standard MenuBar. The constructor
for the Viewer_MenuBar class is straight forward with the assignment of the
three passed arguments to class instances. Remember those objects were the
lindyFrame main frame, the resourceBundle, and the custom Action Listener
object. Up to this point we have not used the lindyFrame main frame object,
but we will shortly. The constructor code continues with calling two helper
methods to build the file and edit menu systems and then producing a custom
logo object. Of interest here is the use of the LindyFrame_Utils class to
obtain the icons directory and loading one of lindyFrame's own icon images
for the logo.
Code Listing 3: (HTMLViewer Viewer_MenuBar.java)
//=================================================================
// HTMLViewer Viewer_MenuBar
//=================================================================
//
// This class is used to constructed the menubar for the HTML
// Viewer plugin module.
//
// < Viewer_MenuBar.java >
//
//=================================================================
// Copyright (C) 2013 Dana M. Proctor.
// Version 1.0 07/27/2013
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
~
~
~
// Version 1.0 07/27/2013 Original Viewer_MenuBar Class.
//
//-----------------------------------------------------------------
// danap@dandymadeproductions.com
//=================================================================
package com.dandymadeproductions.htmlviewer;
import java.awt.Font;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import com.dandymadeproductions.lindyframe.LindyFrame;
import com.dandymadeproductions.lindyframe.gui.LindyFrame_MenuActionCommands;
import com.dandymadeproductions.lindyframe.gui.Main_Frame;
import com.dandymadeproductions.lindyframe.utilities.LindyFrame_ResourceBundle;
import com.dandymadeproductions.lindyframe.utilities.LindyFrame_Utils;
/**
* The Viewer_MenuBar class is used to constructed the menubar for
* the HTML Viewer plugin module.
*
* @author Dana M. Proctor
* @version 1.0 07/27/2013
*/
class Viewer_MenuBar extends JMenuBar
{
// Instance & Class Fields.
private static final long serialVersionUID = -6134364585633519070L;
private Main_Frame mainFrame;
private LindyFrame_ResourceBundle resourceBundle;
private MenuActionListener menuListener;
public static final String ACTION_FILE_OPEN = "File Open";
public static final String ACTION_EDIT_SEARCH = "Edit Search";
//==============================================================
// Viewer_MenuBar JMenuBar Constructor.
//==============================================================
protected Viewer_MenuBar(Main_Frame parent, LindyFrame_ResourceBundle resourceBundle,
MenuActionListener plugin)
{
mainFrame = parent;
this.resourceBundle = resourceBundle;
menuListener = plugin;
// Constructor Instances.
String iconsDirectory;
// JMenu Bar for the plugin.
setBorder(BorderFactory.createEtchedBorder());
// Creating the File, and Tools Menus
createFileMenu();
createEditMenu();
add(Box.createHorizontalGlue());
// Logo
iconsDirectory = LindyFrame_Utils.getIconsDirectory() + LindyFrame_Utils.getFileSeparator();
ImageIcon logoIcon = LindyFrame.getResourceBundle().getResourceImage(iconsDirectory
+ "lindyFrameIcon.gif");
JButton logoIconItem = new JButton(logoIcon);
logoIconItem.setDisabledIcon(logoIcon);
logoIconItem.setFocusPainted(false);
logoIconItem.setBorder(BorderFactory.createLoweredBevelBorder());
add(logoIconItem);
}
//==============================================================
// Helper Method to create the File Menu.
//==============================================================
private void createFileMenu()
{
// Method Instances.
String resource;
JMenu fileMenu;
JMenuItem item;
// ===========
// File Menu
resource = resourceBundle.getResourceString("Viewer_MenuBar.menu.File",
"File");
fileMenu = new JMenu(resource);
fileMenu.setFont(fileMenu.getFont().deriveFont(Font.BOLD));
// Open
resource = resourceBundle.getResourceString("Viewer_MenuBar.menu.Open",
"Open");
fileMenu.add(menuItem(resource, ACTION_FILE_OPEN));
fileMenu.addSeparator();
// Exit
resource = resourceBundle.getResourceString("Viewer_MenuBar.menu.Exit",
"Exit");
item = new JMenuItem(resource);
item.addActionListener(mainFrame);
item.setActionCommand(LindyFrame_MenuActionCommands.ACTION_EXIT);
fileMenu.add(item);
add(fileMenu);
}
//==============================================================
// Helper Method to create the Edit Menu.
//==============================================================
private void createEditMenu()
{
// Method Instances.
String resource;
JMenu editMenu;
// ===========
// Edit Menu
resource = resourceBundle.getResourceString("Viewer_MenuBar.menu.Edit",
"Edit");
editMenu = new JMenu(resource);
editMenu.setFont(editMenu.getFont().deriveFont(Font.BOLD));
// Search
resource = resourceBundle.getResourceString("Viewer_MenuBar.menu.Search",
"Search");
editMenu.add(menuItem(resource, ACTION_EDIT_SEARCH));
add(editMenu);
}
//==============================================================
// Instance method used for the creation of menu bar items.
// Helper Method.
//==============================================================
private JMenuItem menuItem(String label, String actionLabel)
{
JMenuItem item = new JMenuItem(label);
item.addActionListener(menuListener);
item.setActionCommand(actionLabel);
return item;
}
}
|
Moving forward with the menu systems for the plugin we
have the class method createFileMenu(). Here is where we will create
a File menu with sub items of File | Open, and File | Exit.
The first is basic in nature and is derived by using the resourceBundle.getResourceString()
and calling an additional helper method to create the JMenuItem. Note we
assign an ActionListener for that sub item of the custom MenuActionListener,
menuListener, in the helper method menuItem(). The last menu sub item is
slightly different from the first because it is a call to exit the application.
It is done via one of lindyFrame's own action events that is part of
main frame. We find the action event needed by making a reference to the
LindyFrame_MenuActionCommands class. In this case the action command string
is ACTION_EXIT. We complete the File menu by adding the JMenu to the classes'
own add method.
Summary
In this lindyFrame plugin tutorial we have discussed the
implementation of the HTMLViewer plugin. The HTML Viewer module was
chosen because it demonstrates advanced features that a plugin may need
in order to accomplish its purposes. Some of those advanced aspects of
plugin creation have to do with returning a version string and tab icon
image for the lindyFrame's tabbed pane. Other requirements that a plugin
may need to implement is language support. LindyFrame provides a class,
LindyFrame_ResourceBundle, and a method to return user selected locale
information via LindyFrame.getLocaleString() to accomplish this goal.
LindyFrame determines the location of resources via the path string object
that is passed to the initPlugin() method of the PluginModule class. The
final advanced features that a plugin may wish to produce is a menu and
tool bar components. The PluginModule class provides a means to return
those objects so they may be assigned to the tab interface for the plugin.
In addition lindyFrame also makes its own menu items, and action events
available to a plugin via the Main_Frame class and its corresponding
action commands in the LindyFrame_MenuActionCommands class.
Resources
LindyFrame_PluginModule Class
PluginModule Class
HTMLViewer Main Class
MenuActionListener Class
Viewer_MenuBar Class
Viewer_ToolBar Class
|