jmri.jmrit.vsdecoder.SoundEvent.java Source code

Java tutorial

Introduction

Here is the source code for jmri.jmrit.vsdecoder.SoundEvent.java

Source

package jmri.jmrit.vsdecoder;

/*
 * <hr>
 * This file is part of JMRI.
 * <P>
 * JMRI is free software; you can redistribute it and/or modify it under 
 * the terms of version 2 of the GNU General Public License as published 
 * by the Free Software Foundation. See the "COPYING" file for a copy
 * of this license.
 * <P>
 * JMRI is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
 * for more details.
 * <P>
 *
 * @author         Mark Underwood Copyright (C) 2011
 * @version         $Revision$
 */
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.HashMap;
import java.util.Iterator;
import javax.swing.AbstractButton;
import javax.swing.JComponent;
import org.jdom2.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SoundEvent implements PropertyChangeListener {

    public enum ButtonType {

        MOMENTARY, TOGGLE, ENGINE, NONE
    }

    String name;
    String button_label;
    String event_name;
    ButtonType buttontype;

    AbstractButton button;
    EnginePane engine_pane;

    Trigger t; // used in setXml as a temporary holder for creating the
    // event listener class.
    ButtonTrigger bt; // used in setupButtonAction() as a temporary holder
    // for creating the button listeners.
    VSDecoder parent;

    protected HashMap<String, ButtonTrigger> button_trigger_list;

    protected HashMap<String, Trigger> trigger_list;
    VSDSound my_sound;

    public SoundEvent() {
        this(null, null);
    }

    public SoundEvent(String n) {
        this(n, n);
    }

    public SoundEvent(String n, String bl) {
        name = n;
        button_label = bl;
        trigger_list = new HashMap<String, Trigger>();
        button_trigger_list = new HashMap<String, ButtonTrigger>();
        button = null;
    }

    public void setName(String n) {
        name = n;
    }

    public String getName() {
        return (name);
    }

    public void setEventName(String n) {
        event_name = n;
    }

    public String getEventName() {
        return (event_name);
    }

    public ButtonType getButtonType() {
        return (buttontype);
    }

    public boolean hasButton() {
        if ((buttontype == ButtonType.NONE) || (buttontype == ButtonType.ENGINE) || (button == null)) {
            return (false);
        } else {
            return (true);
        }
    }

    public boolean hasEnginePane() {
        if ((buttontype == ButtonType.ENGINE) && (engine_pane != null)) {
            return (true);
        } else {
            return (false);
        }
    }

    public void setButton(AbstractButton b) {
        button = b;
    }

    public JComponent getButton() {
        if ((buttontype == ButtonType.NONE) || (buttontype == ButtonType.ENGINE)) {
            return (null);
        } else {
            return (button);
        }
    }

    public EnginePane getEnginePane() {
        if (buttontype == ButtonType.ENGINE) {
            return (engine_pane);
        } else {
            return (null);
        }
    }

    public void setEnginePane(EnginePane e) {
        engine_pane = e;
    }

    public void setButtonLabel(String bl) {
        button.setText(bl);
    }

    public String getButtonLabel() {
        return (button.getText());
    }

    public void addTrigger(String s, Trigger t) {
        trigger_list.put(s, t);
    }

    public Trigger getTrigger(String s) {
        return trigger_list.get(s);
    }

    public void setSound(VSDSound v) {
        my_sound = v;
    }

    public VSDSound getSound() {
        return (my_sound);
    }

    public void setParent(VSDecoder v) {
        parent = v;
    }

    public VSDecoder getParent() {
        return parent;
    }

    public void propertyChange(PropertyChangeEvent event) {
        for (Trigger t : trigger_list.values()) {
            t.propertyChange(event);
        }
    }

    // What's wrong here:
    // the anonymous MouseListeners are storing a reference to BT, which keeps getting replaced
    // each time the function is called.
    // what we need to do is (maybe) make the ButtonTrigger itself a MouseListener (and ActionListener)
    // 
    protected ButtonTrigger setupButtonAction(Element te) {
        /*
         MouseListener ml;
         bt = new ButtonTrigger(te.getAttributeValue("name"));
         button_trigger_list.put(bt.getName(), bt);
         log.debug("new ButtonTrigger " + bt.getName() + " type " + btype.toString());
         switch(btype) {
         case TOGGLE:
         this.getButton().addActionListener(bt);
         break;
         case MOMENTARY:
         default:
         this.getButton().addMouseListener(bt);
         // Just send the trigger a click.
         }
         return(bt);  // cast OK since we just instantiated it up above.
         */
        return (null); // cast OK since we just instantiated it up above.
    }

    public Element getXml() {
        Element me = new Element("SoundEvent");
        me.setAttribute("name", name);
        me.setAttribute("label", me.getText());
        for (Trigger t : trigger_list.values()) {
            me.addContent(t.getXml());
        }

        return (me);
    }

    public void setXml(Element el) {
        this.setXml(el, null);
    }

    @SuppressWarnings("cast")
    protected void addXmlTrigger(Element te, VSDFile vf) {
        String tts;
        Trigger.TriggerType tt;
        if ((tts = te.getAttributeValue("type")) != null) {
            tt = Trigger.TriggerType.valueOf(tts.toUpperCase());
        } else {
            tt = Trigger.TriggerType.NONE;
        }

        switch (tt) {
        case BUTTON:
            if (this.buttontype != SoundEvent.ButtonType.NONE) {
                t = setupButtonAction(te);
            }
            break;
        case BOOLEAN:
            t = new BoolTrigger(te.getAttributeValue("name"));
            break;
        case FLOAT:
            t = new FloatTrigger(te.getAttributeValue("name"), 0.0f, Trigger.CompareType.EQ);
            break;
        case NOTCH:
            t = new NotchTrigger(te.getAttributeValue("name"));
            break;
        case INT:
            t = new IntTrigger(te.getAttributeValue("name"));
            break;
        case STRING:
            //t = new StringTrigger(el.getAttributeValue("name"));
            log.warn("Don't have StringTriggers yet...");
            t = null;
            return;
        case THROTTLE:
            t = new ThrottleTrigger(te.getAttributeValue("name"));
            break;
        case NONE:
        default:
            break;
        }

        log.debug("Building trigger " + t.getName());
        t.setXml(te);
        trigger_list.put(te.getAttributeValue("name"), t);
        //log.debug("target name " + t.getTargetName() + " sound " + parent.getSound(t.getTargetName()));
        t.setTarget(parent.getSound(t.getTargetName()));
        //log.debug("target " + t.getTarget());

        if (t.getTarget() == null) {
            // If the target is missing, set up a do-nothing operation.
            // Protects against errors in the XML file.
            // Should probably post a warning, though.
            t.setTargetAction(Trigger.TargetAction.NOTHING);
        }
        switch (t.getTargetAction()) {
        case PLAY:
        case FADEIN:
            //log.debug("PLAY");
            t.setCallback(new TriggerListener() {
                public void takeAction() {
                    t.getTarget().play();
                }

                public void takeAction(int i) {
                }

                public void takeAction(float f) {
                } // do nothing
            });
            break;
        case LOOP:
            //log.debug("LOOP");
            t.setCallback(new TriggerListener() {
                public void takeAction() {
                    t.getTarget().loop();
                }

                public void takeAction(int i) {
                }

                public void takeAction(float f) {
                } // do nothing
            });
            break;
        case STOP:
        case FADEOUT:
            //log.debug("STOP");
            t.setCallback(new TriggerListener() {
                public void takeAction() {
                    t.getTarget().stop();
                }

                public void takeAction(int i) {
                }

                public void takeAction(float f) {
                } // do nothing
            });
            break;
        case NOTCH:
            //log.debug("NOTCH");
            log.debug("making callback t " + t + " target " + t.getTarget());
            t.setCallback(new TriggerListener() {
                public void takeAction(int i) {
                    //log.debug("Notch Trigger Listener. t = " + t + " Target = " + t.getTarget() + " notch = " + i);
                    t.getTarget().changeNotch(i);
                }

                public void takeAction() {
                }

                public void takeAction(float f) {
                } // do nothing
            });
            break;
        case CHANGE:
            //log.debug("CHANGE");
            log.debug("making callback t " + t + " target " + t.getTarget());
            t.setCallback(new TriggerListener() {
                public void takeAction() {
                } // do nothing

                public void takeAction(int i) {
                } // do nothing

                public void takeAction(float f) {
                    //log.debug("Throttle Trigger Listener. t = " + t + " Target = " + t.getTarget() + " value = " + f);
                    t.getTarget().changeThrottle(f);
                }
            });
            break;
        case NOTHING:
            // Used for when the target sound is missing.
            //log.debug("NOTHING");
            t.setCallback(new TriggerListener() {
                public void takeAction() {
                } // do nothing

                public void takeAction(int i) {
                } // do nothing

                public void takeAction(float f) {
                } // do nothing
            });
            break;
        default:
            // do nothing.
            break;
        } // end switch
    } // end function

    public void setXml(Element el, VSDFile vf) {
        Element te;
        String btv;

        // Get the SoundEvent's name.
        name = el.getAttributeValue("name");
        if ((btv = el.getAttributeValue("buttontype")) != null) {
            buttontype = SoundEvent.ButtonType.valueOf(btv.toUpperCase());
        } else {
            buttontype = SoundEvent.ButtonType.NONE;
        }

        // Get the SoundEvent's Triggers and set them up.
        Iterator<Element> itr = (el.getChildren("trigger")).iterator();
        while (itr.hasNext()) {
            te = itr.next();
            this.addXmlTrigger(te, vf);
        } // end while

    } // end setXml()

    private static final Logger log = LoggerFactory.getLogger(SoundEvent.class.getName());

}