001package jmri.jmrit.throttle.buttons;
002
003import java.awt.event.ActionEvent;
004import java.beans.PropertyChangeEvent;
005import java.beans.PropertyChangeListener;
006import javax.swing.JButton;
007import jmri.InstanceManager;
008import jmri.JmriException;
009import jmri.PowerManager;
010import jmri.jmrit.catalog.NamedIcon;
011import org.slf4j.Logger;
012import org.slf4j.LoggerFactory;
013
014/**
015 * 
016 * A button handling layout power
017 * 
018 * <hr>
019 * This file is part of JMRI.
020 * <p>
021 * JMRI is free software; you can redistribute it and/or modify it under the
022 * terms of version 2 of the GNU General Public License as published by the Free
023 * Software Foundation. See the "COPYING" file for a copy of this license.
024 * <p>
025 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
026 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
027 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
028 *
029 */
030
031public abstract class PowerManagerButton extends JButton implements PropertyChangeListener {
032
033    private final PropertyChangeListener listener;
034    private Boolean fullText = true;
035    private NamedIcon powerUnknownIcon;
036    private NamedIcon powerOffIcon;
037    private NamedIcon powerOnIcon;
038    private static final Logger log = LoggerFactory.getLogger(PowerManagerButton.class);
039
040    public PowerManagerButton() {
041        this(true);
042    }
043
044    public PowerManagerButton(Boolean fullText) {
045        this.fullText = fullText;
046        this.listener = (PropertyChangeEvent evt) -> {
047            this.setPowerIcons();
048        };
049        PowerManager powerMgr = InstanceManager.getNullableDefault(PowerManager.class);
050        if (powerMgr == null) {
051            log.info("No power manager instance found, panel not active");
052        } else {
053            powerMgr.addPropertyChangeListener(this.listener);
054        }
055        super.addActionListener((ActionEvent e) -> {
056            this.setPower();
057        });
058        this.initComponentsImpl();
059    }
060
061    public void dispose() {
062        PowerManager powerMgr = InstanceManager.getNullableDefault(PowerManager.class);
063        if (powerMgr != null) {
064            powerMgr.removePropertyChangeListener(this.listener);
065        }
066    }
067
068    private void initComponentsImpl() {
069        this.initComponents();
070        this.loadIcons();
071        this.setPowerIcons();
072    }
073
074    /**
075     * Initialize any components within the button or aspects of the button
076     * itself. The default implementation does nothing.
077     */
078    protected void initComponents() {
079        // empty implementation to be overloaded if needed
080    }
081
082    /**
083     * Must be overridden to provide icons for power state indicators.
084     */
085    abstract void loadIcons();
086
087    @Override
088    public void propertyChange(PropertyChangeEvent evt) {
089        this.setPowerIcons();
090    }
091
092    protected void setPowerIcons() {
093        PowerManager powerMgr = InstanceManager.getNullableDefault(PowerManager.class);
094        if (powerMgr == null) {
095            return;
096        }
097        switch (powerMgr.getPower()) {
098            case PowerManager.ON:
099                setIcon(getPowerOnIcon());
100                setToolTipText(Bundle.getMessage("LayoutPowerOn"));
101                if (getFullText()) {
102                    setText(Bundle.getMessage("PowerStateOn"));
103                }
104                break;
105            case PowerManager.OFF:
106                setIcon(getPowerOffIcon());
107                setToolTipText(Bundle.getMessage("LayoutPowerOff"));
108                if (getFullText()) {
109                    setText(Bundle.getMessage("PowerStateOff"));
110                }
111                break;
112            case PowerManager.UNKNOWN:
113                setIcon(getPowerUnknownIcon());
114                setToolTipText(Bundle.getMessage("LayoutPowerUnknown"));
115                if (getFullText()) {
116                    setText(Bundle.getMessage("PowerStateUnknown"));
117                }
118                break;
119            default:
120                setIcon(getPowerUnknownIcon());
121                setToolTipText(Bundle.getMessage("LayoutPowerUnknown"));
122                log.error("Unexpected state value: {}", powerMgr.getPower());
123                if (getFullText()) {
124                    setText(Bundle.getMessage("PowerStateUnknown"));
125                }
126                break;
127        }
128    }
129
130    private void setPower() {
131        PowerManager powerMgr = InstanceManager.getNullableDefault(PowerManager.class);
132        if (powerMgr != null) {
133            try {
134                switch (powerMgr.getPower()) {
135                    case PowerManager.ON:
136                        powerMgr.setPower(PowerManager.OFF);
137                        break;
138                    case PowerManager.OFF:
139                        powerMgr.setPower(PowerManager.ON);
140                        break;
141                    case PowerManager.UNKNOWN:
142                    default:
143                        powerMgr.setPower(PowerManager.OFF);
144                        break;
145                }
146            } catch (JmriException ex) {
147                setIcon(getPowerUnknownIcon());
148                setToolTipText(Bundle.getMessage("LayoutPowerUnknown"));
149                if (getFullText()) {
150                    setText(Bundle.getMessage("PowerStateUnknown"));
151                }
152            }
153        }
154    }
155
156    /**
157     * @return the icon that represents an unknown power state
158     */
159    public NamedIcon getPowerUnknownIcon() {
160        return powerUnknownIcon;
161    }
162
163    /**
164     * @param powerUnknownIcon the icon that represents an unknown power state
165     */
166    public void setPowerUnknownIcon(NamedIcon powerUnknownIcon) {
167        this.powerUnknownIcon = powerUnknownIcon;
168        this.setPowerIcons();
169    }
170
171    /**
172     * @return the icon that represents a power off state
173     */
174    public NamedIcon getPowerOffIcon() {
175        return powerOffIcon;
176    }
177
178    /**
179     * @param powerOffIcon the icon that represents a power off state
180     */
181    public void setPowerOffIcon(NamedIcon powerOffIcon) {
182        this.powerOffIcon = powerOffIcon;
183        this.setPowerIcons();
184    }
185
186    /**
187     * @return the icon that represents a power on state
188     */
189    public NamedIcon getPowerOnIcon() {
190        return powerOnIcon;
191    }
192
193    /**
194     * @param powerOnIcon the icon that represents a power on state
195     */
196    public void setPowerOnIcon(NamedIcon powerOnIcon) {
197        this.powerOnIcon = powerOnIcon;
198        this.setPowerIcons();
199    }
200
201    /**
202     * @return true if text should be shown
203     */
204    protected Boolean getFullText() {
205        return fullText;
206    }
207
208    /**
209     * @param fullText true if text should be shown
210     */
211    protected void setFullText(Boolean fullText) {
212        this.fullText = fullText;
213        this.setPowerIcons();
214    }
215}