net.roydesign.mac.MRJEventProxy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mrjadapter Show documentation
Show all versions of mrjadapter Show documentation
MRJ Adapter is a wrapper around built in Java Virtual Machine APIs provided by Apple.
The newest version!
/*******************************************************************************
File: MRJEventProxy.java
Author: Steve Roy
Part of MRJ Adapter, a unified API for easy integration of Mac OS specific
functionality within your cross-platform Java application.
This library is open source and can be modified and/or distributed under
the terms of the Artistic License.
Change History:
03/31/03 Created this file - Steve
08/27/03 Added handling of the new Reopen Application event - Steve
09/29/03 Modified addPreferencesListener() and removePreferencesListener()
to automatically enable and disable the Preferences item - Steve
11/25/03 Added support for action commands - Steve
12/05/06 Removed uses of 'enum' variable name - Steve
*******************************************************************************/
package net.roydesign.mac;
import net.roydesign.event.ApplicationEvent;
import javax.swing.AbstractButton;
import java.awt.MenuItem;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Implementation of an abstract application event proxy that is the
* base class of MRJ4EventProxy
and {@code MRJ23EventProxy}.
* The role of the base class is to collect references to the action
* listeners and to dispatch action events to them. The subclasses are
* responsible for receiving the events native to MRJ and relaying
* them to the base class via one of the {@code fireXXX} methods.
*
* @see MRJ23EventProxy
* @see MRJ4EventProxy
*
* @version MRJ Adapter 1.2
*/
abstract class MRJEventProxy
{
/**
* The hash key used to identify the About listeners.
*/
private final String ABOUT_KEY = "about";
/**
* The hash key used to identify the Preferences listeners.
*/
private final String PREFERENCES_KEY = "preferences";
/**
* The hash key used to identify the Open Application listeners.
*/
private final String OPEN_APPLICATION_KEY = "open application";
/**
* The hash key used to identify the Quit Application listeners.
*/
private final String QUIT_APPLICATION_KEY = "quit application";
/**
* The hash key used to identify the Open Document listeners.
*/
private final String OPEN_DOCUMENT_KEY = "open document";
/**
* The hash key used to identify the Print Document listeners.
*/
private final String PRINT_DOCUMENT_KEY = "print document";
/**
* The hash key used to identify the Reopen Application listeners.
*/
private final String REOPEN_APPLICATION_KEY = "reopen application";
/**
* The various action listeners attached to each event as identified by
* the keys above. The hash table contains {@code ListenerInfo}
* objects.
*/
private final Map> listenerLists = new HashMap<>();
/**
* Add an About action listener. When the listener is called, the
* ActionEvent
received can be cast to an {@code MRJEvent}.
* @param l the action listener
* @param source the source to use when firing the event
*/
public void addAboutListener(ActionListener l, Object source)
{
addListener(l, source, ABOUT_KEY);
}
/**
* Remove an About action listener.
* @param l the action listener
*/
public void removeAboutListener(ActionListener l)
{
removeListener(l, ABOUT_KEY);
}
/**
* Add a Preferences action listener. When the listener is called, the
* ActionEvent
received can be cast to an {@code MRJEvent}.
* @param l the action listener
* @param source the source to use when firing the event
*/
public void addPreferencesListener(ActionListener l, Object source)
{
// Enable the menu item if this is the first listener
if (listenerLists.get(PREFERENCES_KEY) == null)
setPreferencesEnabled(true);
addListener(l, source, PREFERENCES_KEY);
}
/**
* Remove a Preferences action listener.
* @param l the action listener
*/
public void removePreferencesListener(ActionListener l)
{
removeListener(l, PREFERENCES_KEY);
// Disable the menu item if there is no more listener
if (listenerLists.get(PREFERENCES_KEY) == null)
setPreferencesEnabled(false);
}
/**
* Add an Open Application action listener. When the listener is called, the
* ActionEvent
received can be cast to an {@code MRJEvent}.
* @param l the action listener
* @param source the source to use when firing the event
*/
public void addOpenApplicationListener(ActionListener l, Object source)
{
addListener(l, source, OPEN_APPLICATION_KEY);
}
/**
* Remove an Open Application action listener.
* @param l the action listener
*/
public void removeOpenApplicationListener(ActionListener l)
{
removeListener(l, OPEN_APPLICATION_KEY);
}
/**
* Add a Reopen Application action listener. When the listener is called, the
* ActionEvent
received can be cast to an {@code MRJEvent}.
* @param l the action listener
* @param source the source to use when firing the event
*/
public void addReopenApplicationListener(ActionListener l, Object source)
{
addListener(l, source, REOPEN_APPLICATION_KEY);
}
/**
* Remove a Reopen Application action listener.
* @param l the action listener
*/
public void removeReopenApplicationListener(ActionListener l)
{
removeListener(l, REOPEN_APPLICATION_KEY);
}
/**
* Add a Quit Application action listener. When the listener is called, the
* ActionEvent
received can be cast to an {@code MRJEvent}.
* @param l the action listener
* @param source the source to use when firing the event
*/
public void addQuitApplicationListener(ActionListener l, Object source)
{
addListener(l, source, QUIT_APPLICATION_KEY);
}
/**
* Remove a Quit Application action listener.
* @param l the action listener
*/
public void removeQuitApplicationListener(ActionListener l)
{
removeListener(l, QUIT_APPLICATION_KEY);
}
/**
* Add an Open Document action listener. When the listener is called, the
* ActionEvent
received can be cast to an {@code MRJEvent}
* or to an {@code MRJDocumentEvent} which allows to get a reference
* to the file associated with the event.
* @param l the action listener
* @param source the source to use when firing the event
*/
public void addOpenDocumentListener(ActionListener l, Object source)
{
addListener(l, source, OPEN_DOCUMENT_KEY);
}
/**
* Remove an Open Document action listener.
* @param l the action listener
*/
public void removeOpenDocumentListener(ActionListener l)
{
removeListener(l, OPEN_DOCUMENT_KEY);
}
/**
* Add a Print Document action listener. When the listener is called, the
* ActionEvent
received can be cast to an {@code MRJEvent}
* or to an {@code MRJDocumentEvent} which allows to get a reference
* to the file associated with the event.
* @param l the action listener
* @param source the source to use when firing the event
*/
public void addPrintDocumentListener(ActionListener l, Object source)
{
addListener(l, source, PRINT_DOCUMENT_KEY);
}
/**
* Remove a Print Document action listener.
* @param l the action listener
*/
public void removePrintDocumentListener(ActionListener l)
{
removeListener(l, PRINT_DOCUMENT_KEY);
}
/**
* Register the given action listener to receive action events from
* the given source. They are added to the hash table and associated
* with the given key.
* @param l the action listener
* @param source the source to use when firing the event
* @param key the key to associate the listener with
*/
private void addListener(ActionListener l, Object source, String key)
{
// Get the hash table containing the listeners for the given key
Map ht = listenerLists.get(key);
if (ht == null)
{
// If there is none yet, create it
ht = new HashMap<>(1); // In most cases, 1 will be enough
listenerLists.put(key, ht);
}
// Don't allow the same listener to be added twice
String name = l.getClass().getName();
if (ht.containsKey(name))
return;
// Encapsulate the listener info and add it to the hash table
ListenerInfo li = new ListenerInfo();
li.setActionListener(l);
li.setSource(source != null ? source : this);
ht.put(name, li);
}
/**
* Deregister the given action listener to receive action events
* of the kind associated with the given key.
* @param l the action listener
* @param key the key to dissociate the listener with
*/
private void removeListener(ActionListener l, String key)
{
Map ht = listenerLists.get(key);
String name = l.getClass().getName();
if (ht != null && ht.remove(name) != null && ht.isEmpty())
listenerLists.remove(key);
}
/**
* Get whether the Preferences menu item is enabled or not. This menu
* item is automatically provided by the OS on Mac OS X. On classic
* Mac OS, this method always returns false.
* @return whether the Preferences menu item is enabled
*/
public abstract boolean isPreferencesEnabled();
/**
* Set whether the Preferences menu item is enabled or not. This menu
* item is automatically provided by the OS on Mac OS X. On classic
* Mac OS, this method does nothing.
* @param enabled whether the menu item is enabled
*/
public abstract void setPreferencesEnabled(boolean enabled);
/**
* Fire a menu event of the given type, as designated by the
* types {@code ApplicationEvent.ABOUT} or
* {@code ApplicationEvent.PREFERENCES}.
* @param type the type of the event
*/
protected void fireMenuEvent(int type)
{
Map ht;
switch (type)
{
case ApplicationEvent.ABOUT:
ht = listenerLists.get(ABOUT_KEY);
break;
case ApplicationEvent.PREFERENCES:
ht = listenerLists.get(PREFERENCES_KEY);
break;
default:
throw new RuntimeException("unknown event type");
}
if (ht == null)
return;
Set keys = ht.keySet();
for (String key : keys) {
ListenerInfo li = ht.get(key);
String cmd = null;
if (li.getSource() instanceof MenuItem)
cmd = ((MenuItem) li.getSource()).getActionCommand();
else if (li.getSource() instanceof AbstractButton)
cmd = ((AbstractButton) li.getSource()).getActionCommand();
ApplicationEvent e = new ApplicationEvent(li.getSource(), type, cmd);
li.getActionListener().actionPerformed(e);
}
}
/**
* Fire a document event of the given type, as designated by the
* types {@code ApplicationEvent.OPEN_DOCUMENT} or
* {@code ApplicationEvent.PRINT_DOCUMENT}.
* @param type the type of the event
* @param file the file to associate with the event
*/
protected void fireDocumentEvent(int type, File file)
{
Map ht;
switch (type)
{
case ApplicationEvent.OPEN_DOCUMENT:
ht = listenerLists.get(OPEN_DOCUMENT_KEY);
break;
case ApplicationEvent.PRINT_DOCUMENT:
ht = listenerLists.get(PRINT_DOCUMENT_KEY);
break;
default:
throw new RuntimeException("unknown event type");
}
if (ht == null)
return;
Set keys = ht.keySet();
for(String key : keys)
{
ListenerInfo li = ht.get(key);
ApplicationEvent e = new ApplicationEvent(li.getSource(), type, file);
li.getActionListener().actionPerformed(e);
}
}
/**
* Fire an application event of the given type, as designated by the
* types {@code ApplicationEvent.OPEN_APPLICATION},
* {@code ApplicationEvent.REOPEN_APPLICATION} or
* {@code ApplicationEvent.QUIT_APPLICATION}.
* @param type the type of the event
*/
protected void fireApplicationEvent(int type)
{
Map ht;
switch (type)
{
case ApplicationEvent.OPEN_APPLICATION:
ht = listenerLists.get(OPEN_APPLICATION_KEY);
break;
case ApplicationEvent.REOPEN_APPLICATION:
ht = listenerLists.get(REOPEN_APPLICATION_KEY);
break;
case ApplicationEvent.QUIT_APPLICATION:
ht = listenerLists.get(QUIT_APPLICATION_KEY);
if (ht == null)
{
System.exit(0);
return;
}
break;
default:
throw new RuntimeException("unknown event type");
}
if (ht == null)
return;
Set keys = ht.keySet();
for (String key : keys)
{
ListenerInfo li = ht.get(key);
ApplicationEvent e = new ApplicationEvent(li.getSource(), type);
li.getActionListener().actionPerformed(e);
}
}
}