Methods Summary |
---|
public void | appendDocumentText(java.lang.String in)Used by tools to add to the current text
setDocumentText(mainTextArea.getText() + in);
|
private void | dispatchEvent(java.awt.event.ActionEvent evt, java.lang.String tag)
SimpleEdit myFrame = null;
SimpleEditPlugin myPlugin = null;
if(evt.getSource() instanceof JComponent)
{
myFrame = (SimpleEdit)(((JComponent)evt.getSource()).getClientProperty("window"));
myPlugin = (SimpleEditPlugin)(((JComponent)evt.getSource()).getClientProperty("plugin"));
}
// If it's a plugin, hand off to the plugin to handle
if(myPlugin != null)
{
myPlugin.doAction(myFrame, evt);
return;
}
// Handle minimal required functionality.
// It could legitimately be argued that even this
// functionality should be split off into an
// overarching set of plugin functionality...
// but this is adequate for now, and reinforces
// the notion of certain "default" services.
if(tag.compareTo("New") == 0)
doNew();
if(tag.compareTo("Close") == 0)
doClose(myFrame);
if(tag.compareTo("Timestamp") == 0)
doTimestamp(myFrame);
|
private void | doClose(com.wiverson.macosbook.SimpleEdit myFrame)
myFrame.hide();
|
private void | doNew()
(new SimpleEdit()).show();
|
private void | doTimestamp(com.wiverson.macosbook.SimpleEdit myFrame)
if(myFrame != null)
myFrame.mainTextArea.setText(myFrame.mainTextArea.getText() + System.getProperty("line.separator") + new java.util.Date() + " : ");
myFrame.mainTextArea.setCaretPosition(myFrame.mainTextArea.getText().length());
myFrame.mainTextArea.requestFocus();
|
public java.lang.String | getDocumentText()Used by tools to get the current text
return this.mainTextArea.getText();
|
public javax.swing.JTextArea | getJTextArea()Used by tools to get the text actual text area.
This wouldn't generally be recommended, but in this
case it's ok.
In general, you'd want to use something to make the
interface more opaque (thereby freeing up options to
switch to a different underlying toolkit), but in this
case it would cost readability (since everyone can look
up a JTextArea).
return this.mainTextArea;
|
public void | hide()Hides the window. If no windows are visible, terminates quietly.
// Overrides the default hide to see how many windows are currently
// showing. If none are visible, quit the app.
super.hide();
openWindows--;
if(openWindows == 0)
{
try
{
System.exit(0);
} catch (java.security.AccessControlException e1)
{
// Silently fail - running in a browser or Web Start.
}
}
|
private void | init()
// Sets up and creates a new window.
if(newWindows++ < 0)
setTitle("Untitled");
else
setTitle("Untitled-" + newWindows);
initPlugins();
initComponents();
initMenuBar();
|
private void | initComponents()
this.getContentPane().setBackground(java.awt.Color.white);
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add(mainScrollPane, BorderLayout.CENTER);
this.getContentPane().add(mainToolBar, BorderLayout.NORTH);
this.getContentPane().add(mainStatusText, BorderLayout.SOUTH);
// This text field serves two purposes. It provides useful information
// to the user, and also serves as a graceful "bump" for the Mac OS
// grow box on the Mac OS platform.
mainStatusText.setText("Ready.");
mainStatusText.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
mainScrollPane.setViewportView(mainTextArea);
mainTextArea.setEditable(true);
mainTextArea.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
mainTextArea.setFont(new java.awt.Font("serif", java.awt.Font.PLAIN, 12));
// Perhaps a tool might be added later to control this dynamically?
mainTextArea.setLineWrap(true);
// Generally looks terrible on all platforms, and requires
// a fair amount of work to get it to work right.
mainToolBar.setFloatable(false);
initToolBar(mainToolBar, this);
// Determine the offset value and stagger new windows
// (with a reset every ten windows). A somewhat
// unscientific mechanism, but it works well enough.
int top_offset = 0;
if((newWindows % 10) > 0)
{
top_offset =((this.newWindows) % 10) * 20 + 20;
this.setLocation(
new Double(getLocation().getX() + top_offset - 20).intValue(),
new Double(getLocation().getY() + top_offset).intValue()
);
}
int bottom_offset = 0;
if (top_offset > 0)
bottom_offset = top_offset - 20;
// In a later chapter, we can use the JDirect and the
// Carbon API GetAvailableWindowPositioningBounds()
// to properly position this.
java.awt.Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
screensize = new java.awt.Dimension(640, screensize.height -128 - bottom_offset);
this.setSize(screensize);
|
private void | initMenuBar()
mainMenuBar = new javax.swing.JMenuBar();
menuFile = new JMenu("File");
setupMenu(menuFile, fileItems, this);
mainMenuBar.add(menuFile);
menuEdit = new JMenu("Edit");
setupMenu(menuEdit, editItems, this);
mainMenuBar.add(menuEdit);
menuTools = new JMenu("Tools");
setupMenu(menuTools, toolItems, this);
mainMenuBar.add(menuTools);
JMenuItem newMenuItem;
if(plugins != null)
if(plugins.size() > 0)
{
java.util.Enumeration e = plugins.elements();
SimpleEditPlugin currentPlugin;
while(e.hasMoreElements())
{
currentPlugin = (SimpleEditPlugin)e.nextElement();
newMenuItem = new JMenuItem();
newMenuItem.setLabel(currentPlugin.getAction());
newMenuItem.setEnabled(true);
newMenuItem.setActionCommand(currentPlugin.getAction());
newMenuItem.putClientProperty("window", this);
newMenuItem.putClientProperty("plugin", currentPlugin);
newMenuItem.addActionListener(actionListenerHandler);
menuTools.add(newMenuItem);
}
}
((JMenuItem)menuItemsHashtable.get("New")).setEnabled(true);
((JMenuItem)menuItemsHashtable.get("Timestamp")).setEnabled(true);
((JMenuItem)menuItemsHashtable.get("Close")).setEnabled(true);
setJMenuBar(mainMenuBar);
|
private void | initPlugins()
// Installs all plugins as currently defined by the
// private argsconfig.
if(plugins != null)
return;
if(argsconfig == null)
return;
if(argsconfig.length == 0)
return;
plugins = new Hashtable();
for(int i = 0; i < argsconfig.length; i++)
{
// This may very well fail, as we are going
// to be loading classes by name, which is
// prone to errors (e.g. typos, etc.)
try
{
// This requests the classloader to find a
// given class by name. We are using this to
// implement a plugin architecture, based on
// expecting classes to implement a specific
// interface (SimpleEditPlugin). If the class
// can be loaded and cast without failure,
// we are good to go.
Class myClass = Class.forName(argsconfig[i]);
SimpleEditPlugin myPlugin = (SimpleEditPlugin)myClass.getConstructor(null).newInstance(null);
// Don't add the plugin if already installed. Allows for
// eventual support for dynamically adding new plugins later.
// Calls the Plugin init if this is the first time it's being loaded.
if(plugins.containsKey(myPlugin.getAction()))
{
return;
} else
{
myPlugin.init(this);
}
// If we made it this far, the plugin has been loaded
// and initialized, so it's ok to add to the list of
// valid plugins.
plugins.put(myPlugin.getAction(), myPlugin);
}
catch(Exception e)
{
// This is not really adequate for a quality client
// application, but it's acceptable for our purposes.
System.out.println("Couldn't load Plugin: " + argsconfig[i]);
System.out.println(e.getMessage());
e.printStackTrace();
}
}
|
private void | initToolBar(javax.swing.JToolBar myToolBar, com.wiverson.macosbook.SimpleEdit myFrame)
JButton newButton;
for(int i = 0; i < toolbarItems.length; i++)
{
if(toolbarItems[i] != null)
{
// It would be nice to provide icons
// instead of just text labels.
newButton = new JButton(toolbarItems[i]);
// Used to track the targets more easily
newButton.putClientProperty("window", myFrame);
newButton.addActionListener(actionListenerHandler);
myToolBar.add(newButton);
} else
{
myToolBar.add(new javax.swing.JToolBar.Separator());
}
}
// Load all plugins into the toolbar
if(plugins != null)
if(plugins.size() > 0)
{
java.util.Enumeration e = plugins.elements();
SimpleEditPlugin currentPlugin;
while(e.hasMoreElements())
{
currentPlugin = (SimpleEditPlugin)e.nextElement();
newButton = new JButton(currentPlugin.getAction());
// We are using Swing client properties to
// track additional information without having
// to subclass - in effect, using the
// client properties mechanism as a form of
// delegation.
newButton.putClientProperty("window", myFrame);
newButton.putClientProperty("plugin", currentPlugin);
newButton.addActionListener(actionListenerHandler);
myToolBar.add(newButton);
}
}
|
public static void | main(java.lang.String[] args)
argsconfig = args;
(new SimpleEdit()).show();
|
public void | setDocumentText(java.lang.String in)Used by tools to set the current text
mainTextArea.setText(in);
mainTextArea.setCaretPosition(mainTextArea.getText().length());
mainTextArea.requestFocus();
|
public void | setStatusText(java.lang.String in)Used by tools to set the status text at the bottom
of a frame.
this.mainStatusText.setText(in);
|
private void | setupMenu(javax.swing.JMenu myMenu, java.lang.Object[][] menuconfig, com.wiverson.macosbook.SimpleEdit thisFrame)
JMenuItem currentMenuItem;
for(int i = 0; i < menuconfig.length; i++)
{
if(menuconfig[i][0] != null)
{
currentMenuItem = new JMenuItem();
currentMenuItem.setLabel((String)menuconfig[i][0]);
if(menuconfig[i][1] != null)
{
int keyCode = ((Integer)menuconfig[i][1]).intValue();
KeyStroke key = KeyStroke.getKeyStroke(keyCode, preferredMetaKey);
currentMenuItem.setAccelerator(key);
}
currentMenuItem.setEnabled(false);
currentMenuItem.setActionCommand((String)menuconfig[i][0]);
currentMenuItem.putClientProperty("window", thisFrame);
currentMenuItem.addActionListener(actionListenerHandler);
// Put the menu item into the menu hash to add handlers later
menuItemsHashtable.put((String)menuconfig[i][0], currentMenuItem);
myMenu.add(currentMenuItem);
} else
{
javax.swing.JSeparator sep = new javax.swing.JSeparator();
myMenu.add(sep);
}
}
|
public void | show()
super.show();
openWindows++;
// All ready to go, go ahead and get ready for input.
this.appendDocumentText("");
|