nu.zoom.swing.desktop.component.stringmenu.impl.StringMenuImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of filechooser Show documentation
Show all versions of filechooser Show documentation
A zoom.nu desktop plugin that makes the stock java filechooser remember where it was the last time.
The newest version!
/*
* Copyright (C) 2006 Johan Maasing johan at zoom.nu Licensed under the Apache
* License, Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
* or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package nu.zoom.swing.desktop.component.stringmenu.impl;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.Icon;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JSeparator;
import nu.zoom.swing.action.AbstractTypedAction;
import nu.zoom.swing.desktop.Workbench;
import nu.zoom.swing.desktop.WorkbenchListener;
import nu.zoom.swing.desktop.common.BackendException;
import nu.zoom.swing.desktop.component.stringmenu.StringMenu;
import nu.zoom.swing.desktop.component.stringmenu.StringMenuItem;
import nu.zoom.swing.desktop.component.stringmenu.StringMenuListener;
import nu.zoom.swing.desktop.preferences.InvalidDataTypeException;
import nu.zoom.swing.desktop.preferences.Preferences;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class StringMenuImpl & Serializable> implements
StringMenu, WorkbenchListener {
private final Log log = LogFactory.getLog(getClass());
private final HashMap, JMenuItem> itemStringToJMenuItem = new HashMap, JMenuItem>();
private final ArrayList> listeners = new ArrayList>();
private final ArrayList> itemStrings = new ArrayList>();
private JMenu menu = null;
private final Preferences preferences;
private final String preferencesKey;
/**
* Instantiate a new menu
*
* @param preferences
* @param workbench
* @param preferencesKey
* @param menuName
*/
StringMenuImpl(Preferences preferences, Workbench workbench,
String preferencesKey) {
this.preferences = preferences;
this.preferencesKey = preferencesKey;
log.trace("New String menu is registering as workbench listener");
workbench.addWorkBenchListener(this);
}
@Override
public synchronized void addListener(StringMenuListener listener) {
if (listener == null) {
throw new IllegalArgumentException("Listener may not be null");
}
log.trace("Registering a string menu listener: " + listener);
listeners.add(listener);
}
@Override
public synchronized void removeListener(StringMenuListener listener) {
log.trace("Removing a string menu listener: " + listener);
listeners.remove(listener);
}
@Override
public synchronized JMenu getJMenu(final String menuName, final Icon icon,
final String clearName, final String clearTooltip) {
if (menu == null) {
createJMenu(menuName, icon, clearName, clearTooltip);
restoreMenu();
}
return menu;
}
@Override
public synchronized void addItem(final StringMenuItem menuItem) {
if (menuItem == null) {
log.fatal("Item may not be null");
throw new IllegalArgumentException("Item may not be null");
}
if (!EventQueue.isDispatchThread()) {
log.fatal("Must be called on the EventQueue dispatch thread");
throw new IllegalStateException(
"Must be called on the EventQueue dispatch thread");
}
if (!itemStringToJMenuItem.containsKey(menuItem)) {
log.trace("Adding item to menu");
addItemInternal(menuItem);
}
}
@Override
public synchronized void removeItem(StringMenuItem menuItem) {
if (!EventQueue.isDispatchThread()) {
log.fatal("Must be called on the EventQueue dispatch thread");
throw new IllegalStateException(
"Must be called on the EventQueue dispatch thread");
}
if (menuItem != null) {
log.trace("Looking for menu item to remove");
final JMenuItem cachedJMenuItem = itemStringToJMenuItem
.get(menuItem);
log.trace("Cache returned item: " + cachedJMenuItem);
if (cachedJMenuItem != null) {
log.trace("Removing item from JMenu");
this.menu.remove(cachedJMenuItem);
log.trace("Removing item from key list");
itemStrings.remove(menuItem);
log.trace("Removing item from cache");
itemStringToJMenuItem.remove(menuItem);
log.trace("Removing ALL action listeners from JMenuItem");
ActionListener[] listeners = cachedJMenuItem
.getActionListeners();
for (ActionListener listener : listeners) {
cachedJMenuItem.removeActionListener(listener);
}
}
}
}
private synchronized void fireMenuItemSelected(
final StringMenuItem menuItem) {
for (final StringMenuListener listener : listeners) {
EventQueue.invokeLater(new Runnable() {
public void run() {
log.trace("Informing listener:" + listener + " that item: "
+ menuItem + " was selected");
listener.menuItemSelected(menuItem);
}
});
}
}
@Override
public synchronized void close() {
try {
log.trace("Trying to serialize key list to preferences");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream outs = new ObjectOutputStream(baos);
outs.writeObject(itemStrings);
outs.flush();
preferences.setBytes(preferencesKey, baos.toByteArray());
} catch (BackendException e) {
log.warn(e);
} catch (IOException e) {
log.warn(e);
}
}
@Override
public void start() {
}
@Override
public void visible() {
}
@SuppressWarnings("unchecked")
private synchronized void restoreMenu() {
try {
log.trace("Trying to deserialize key list from preferences");
byte[] data = preferences.getBytes(preferencesKey);
if (data != null) {
ObjectInputStream ins = new ObjectInputStream(
new ByteArrayInputStream(data));
// Generates unchecked warnings but we know
ArrayList> restoredKeys = (ArrayList>) ins
.readObject();
for (final StringMenuItem item : restoredKeys) {
addItemInternal(item);
}
}
} catch (InvalidDataTypeException e) {
log.warn(e);
} catch (BackendException e) {
log.warn(e);
} catch (IOException e) {
log.warn(e);
} catch (ClassNotFoundException e) {
log.warn(e);
}
}
@Override
@SuppressWarnings("unchecked")
public void clear() {
ArrayList> keyClone = (ArrayList>) itemStrings
.clone();
for (StringMenuItem item : keyClone) {
removeItem(item);
}
}
@Override
public synchronized int getNumberOfItems() {
int numKeys = itemStrings.size();
log.trace("Getting the number of items on the menu: " + numKeys);
return numKeys;
}
private void createJMenu(final String menuName, final Icon icon,
final String clearName, final String clearTooltip) {
log.trace("Creating new JMenu with name: " + menuName);
this.menu = new JMenu(menuName);
if (icon != null) {
log.trace("Setting menu icon to " + icon);
this.menu.setIcon(icon);
}
if (clearName != null) {
this.menu.add(new ClearAction(clearName, clearTooltip));
this.menu.add(new JSeparator(JSeparator.HORIZONTAL));
}
}
private synchronized void addItemInternal(
final StringMenuItem stringMenuItem) {
log.trace("Creating JMenu item");
JMenuItem jMenuItem = createJMenuItem(stringMenuItem);
log.trace("Adding cache entry for item: " + stringMenuItem);
itemStringToJMenuItem.put(stringMenuItem, jMenuItem);
log.trace("Adding key to key list");
itemStrings.add(stringMenuItem);
log.trace("Addin JMenuItem: " + jMenuItem + " to JMenu");
this.menu.insert(jMenuItem, 2);
}
private JMenuItem createJMenuItem(final StringMenuItem stringMenuItem) {
JMenuItem jMenuItem = new JMenuItem(
stringMenuItem.getPresentationName());
jMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
fireMenuItemSelected(stringMenuItem);
}
});
return jMenuItem;
}
@SuppressWarnings("serial")
class ClearAction extends AbstractTypedAction {
public ClearAction(final String name, final String tooltip) {
super();
setName(name);
if (tooltip != null) {
setToolTip(tooltip);
}
}
@Override
public void actionPerformed(ActionEvent e) {
clear();
}
}
}