/******************************************************************************* * Copyright (c) 2003-2005, 2013 Till Zoppke. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * * Contributors: * Till Zoppke - initial API and implementation ******************************************************************************/ /* * Created on 25.03.2004 */ package eniac.menu; import java.awt.Dimension; import java.awt.Image; import java.awt.image.ImageObserver; import java.io.IOException; import java.io.InputStream; import java.util.Hashtable; import javax.swing.Action; import javax.swing.ImageIcon; import javax.swing.JOptionPane; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import eniac.Manager; import eniac.io.IOUtil; import eniac.io.Progressor; import eniac.io.XMLUtil; import eniac.log.Log; import eniac.log.LogWords; import eniac.menu.action.EAction; import eniac.skin.Skin; import eniac.util.EProperties; import eniac.util.Status; import eniac.util.StringConverter; import eniac.window.EFrame; /** * @author zoppke */ public class ActionManager extends DefaultHandler { // constant tag and attribute names for parsing the menu xml file private enum Tag { PROPERTY, CLASS, ACTION, ACTIONS, NAME, VALUE, KEY; } // =============================== fields //================================ private EAction _currentAction = null; private Hashtable<String, Action> _actionsTable = null; // ========================== singleton stuff //============================ private static ActionManager instance = null; private ActionManager() { } public synchronized static ActionManager getInstance() { if (instance == null) { instance = new ActionManager(); instance.init(); } return instance; } private void init() { // parse actions from xml String path = EProperties.getInstance().getProperty("ACTIONS_FILE"); InputStream in = Manager.class.getClassLoader().getResourceAsStream(path); try { IOUtil.parse(in, this); } catch (IOException e) { e.printStackTrace(); } } // ========================== defaultHandler methods //===================== public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException { // System.out.println(qName); try { if (qName.equalsIgnoreCase(Tag.ACTIONS.toString())) { // create hashtable to store actions _actionsTable = new Hashtable<>(); } else if (qName.equalsIgnoreCase(Tag.ACTION.toString())) { // parse action class and name String key = XMLUtil.parseString(attrs, Tag.KEY); String className = XMLUtil.parseString(attrs, Tag.CLASS); // create action and put its key as property _currentAction = (EAction) Class.forName(className).newInstance(); _currentAction.putValue(EAction.KEY, key); // add to action hashtable _actionsTable.put(key, _currentAction); } else if (qName.equalsIgnoreCase(Tag.PROPERTY.toString())) { // parse property name and value String name = XMLUtil.parseString(attrs, Tag.NAME); String value = XMLUtil.parseString(attrs, Tag.VALUE); // set property at current action Object convertedValue = convertProperty(name, value); _currentAction.putValue(name, convertedValue); } } catch (Exception e) { // important: catch any exception and print its tree. // otherwise you won't get the error's source. e.printStackTrace(); throw new SAXException(e); } } // =========================== other methods //============================= public EAction getAction(String key) { return (EAction) _actionsTable.get(key); } private Object convertProperty(String name, String value) { if (name.equals(Action.SMALL_ICON)) { // tell progressor, that new image loaded Progressor.getInstance().incrementValue(); // load image. If image cannot be loaded, load default image. Image img = EFrame.getInstance().getResourceAsImage(value); if (img == null) { Log.log(LogWords.IMAGE_NOT_FOUND, JOptionPane.ERROR_MESSAGE, value); img = Skin.DEFAULT_IMAGE; } // scale image in case it does not fit to the icon size Dimension d = StringConverter.toDimension(EProperties.getInstance().getProperty("ICON_SIZE")); ImageObserver o = EFrame.getInstance(); if (d.width != img.getWidth(o) && d.height != img.getHeight(o)) { img = img.getScaledInstance(d.width, d.height, Image.SCALE_DEFAULT); } // return icon return new ImageIcon(img); } else if (name.equals(EAction.STATUS_PROPERTY)) { try { return Enum.valueOf(Status.class, value); } catch (IllegalArgumentException exc) { System.out.println("unknown status property: " + value); return null; // TODO: this will cause a nullpointer exception // later. any better handling? } } // property doesn't need to be converted return value; } }