001package jmri.implementation; 002 003import java.beans.PropertyChangeEvent; 004import java.util.ArrayList; 005import java.util.List; 006import jmri.Conditional; 007import jmri.NamedBeanHandle; 008import org.slf4j.Logger; 009import org.slf4j.LoggerFactory; 010 011/** 012 * A service base class for monitoring a bound property in one of the JMRI Named 013 * beans (Turnout, Sensor, etc). For use with properties that may have more than 014 * two states where the states are represented by numbers than can be cast to 015 * integers. 016 * <p> 017 * This file is part of JMRI. 018 * <p> 019 * JMRI is free software; you can redistribute it and/or modify it under the 020 * terms of version 2 of the GNU General Public License as published by the Free 021 * Software Foundation. See the "COPYING" file for a copy of this license. 022 * <p> 023 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY 024 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 025 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 026 * 027 * @author Pete Cressman Copyright (C) 2009 028 * @since 2.5.1 029 */ 030public class JmriMultiStatePropertyListener extends JmriSimplePropertyListener { 031 032 ArrayList<Integer> _states; 033 034 JmriMultiStatePropertyListener(String propName, int type, String name, Conditional.Type varType, 035 Conditional client, int state) { 036 super(propName, type, name, varType, client); 037 _states = new ArrayList<>(); 038 _states.add(Integer.valueOf(state)); 039 } 040 041 JmriMultiStatePropertyListener(String propName, int type, NamedBeanHandle<?> namedBean, Conditional.Type varType, 042 Conditional client, int state) { 043 super(propName, type, namedBean, varType, client); 044 _states = new ArrayList<>(); 045 _states.add(Integer.valueOf(state)); 046 } 047 048 public void setState(int state) { 049 _states.add(Integer.valueOf(state)); 050 } 051 052 /** 053 * Add a Conditional for the state set next by {@link #setState(int)}. 054 * Each state has its own entry in the client list, so a Conditional 055 * watching several states is listed once for each of them. 056 * 057 * @param client the Conditional to calculate 058 */ 059 @Override 060 public void addConditional(Conditional client) { 061 _clients.add(client); 062 } 063 064 @Override 065 public void propertyChange(PropertyChangeEvent evt) { 066 log.debug("\"{}\" sent PropertyChangeEvent {}, old value =\"{}\", new value =\"{}, enabled = {}", _varName, evt.getPropertyName(), evt.getOldValue(), evt.getNewValue(), _enabled); 067 if (getPropertyName().equals(evt.getPropertyName())) { 068 int newState = ((Number) evt.getNewValue()).intValue(); 069 int oldState = ((Number) evt.getOldValue()).intValue(); 070 if (newState != oldState) { 071 List<Conditional> calculated = new ArrayList<>(); 072 for (int i = 0; i < _states.size(); i++) { 073 int state = _states.get(i).intValue(); 074 if ((oldState == state || newState == state) && !calculated.contains(_clients.get(i))) { 075 // calculate each Conditional once, even if it watches both states 076 calculated.add(_clients.get(i)); 077 calculateClient(i, evt); 078 } 079 } 080 } 081 } 082 } 083 private static final Logger log = LoggerFactory.getLogger(JmriMultiStatePropertyListener.class); 084}