001package jmri.jmrit.throttle;
002
003import java.beans.PropertyChangeEvent;
004import java.beans.PropertyChangeListener;
005
006import javax.swing.ActionMap;
007import javax.swing.ComponentInputMap;
008import javax.swing.JComponent;
009import javax.swing.KeyStroke;
010
011import jmri.DccLocoAddress;
012import jmri.InstanceManager;
013import jmri.ThrottleManager;
014import jmri.jmrit.throttle.actions.ThrottleWindowActionsFactory;
015import jmri.jmrit.throttle.actions.ThrottleWindowInputsListener;
016import jmri.jmrit.throttle.implementation.SimpleThrottlePanel;
017import jmri.jmrit.throttle.interfaces.ThrottleControllerUI;
018import jmri.jmrit.throttle.interfaces.ThrottleControllersUIContainer;
019import jmri.jmrit.throttle.preferences.ThrottlesPreferences;
020import jmri.util.JmriJFrame;
021
022/**
023 * A very simple throttle window.
024 * 
025 * <hr>
026 * This file is part of JMRI.
027 * <p>
028 * JMRI is free software; you can redistribute it and/or modify it under the
029 * terms of version 2 of the GNU General Public License as published by the Free
030 * Software Foundation. See the "COPYING" file for a copy of this license.
031 * <p>
032 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
033 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
034 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
035 *
036 * @author Lionel Jeanson 2007-2026
037 * 
038 */
039
040public class SimpleThrottleWindow extends JmriJFrame implements ThrottleControllersUIContainer, PropertyChangeListener {
041
042    private final ThrottleFrameManager throttleFrameManager = InstanceManager.getDefault(ThrottleFrameManager.class);
043    private final ThrottleWindowActionsFactory myActionFactory;
044    private SimpleThrottlePanel throttleControllerUI;
045
046    /**
047     * Default constructor
048     * 
049     * @param la the loco address to set in the throttle
050     */
051    public SimpleThrottleWindow(DccLocoAddress la) {
052        this((jmri.jmrix.ConnectionConfig) null, la);
053    }
054
055    public SimpleThrottleWindow(jmri.jmrix.ConnectionConfig connectionConfig, DccLocoAddress la) {
056        super(Bundle.getMessage("ThrottleTitle"));
057
058        ThrottleManager throttleManager;
059        if (connectionConfig != null) {
060            throttleManager = connectionConfig.getAdapter().getSystemConnectionMemo().get(jmri.ThrottleManager.class);
061        } else {
062            throttleManager = InstanceManager.getDefault(jmri.ThrottleManager.class);
063        }
064        myActionFactory = new ThrottleWindowActionsFactory(this);
065        throttleControllerUI = new SimpleThrottlePanel(this, throttleManager, true, true, true);
066        initGUI();
067        InstanceManager.getDefault(ThrottlesPreferences.class).addPropertyChangeListener(this);
068        if (la != null) {
069            throttleControllerUI.setAddress(la);
070        }        
071    }
072
073    private void initGUI() {
074        setTitle(Bundle.getMessage("ThrottleTitle") );        
075        add(throttleControllerUI);
076        pack();
077
078        // add keyboard controls
079        ActionMap am = myActionFactory.buildActionMap();
080        for (Object k : am.allKeys()) {
081            getRootPane().getActionMap().put(k, am.get(k));
082        }        
083        ThrottlesPreferences preferences = InstanceManager.getDefault(ThrottlesPreferences.class);
084        ComponentInputMap im = new ComponentInputMap(getRootPane());
085        for (Object k : this.getRootPane().getActionMap().allKeys()) {
086            KeyStroke[] kss = preferences.getThrottlesKeyboardControls().getKeyStrokes((String)k);
087            if (kss !=null) {
088                for (KeyStroke keystroke : kss) {
089                    if (keystroke != null) {
090                        im.put(keystroke, k);
091                    }
092                }
093            }
094        }
095        getRootPane().setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW,im);
096        getRootPane().setFocusable(true);
097        getRootPane().requestFocusInWindow();
098        // mouse wheel listener
099        addMouseWheelListener( new ThrottleWindowInputsListener(this) );
100    }
101
102    @Override
103    public int getNbThrottlesControllers() {
104        return 1;
105    }
106
107    @Override
108    public ThrottleControllerUI newThrottleController() {
109        return InstanceManager.getDefault(ThrottleFrameManager.class).createSimpleThrottleFrame(null, null);
110    }
111
112    @Override
113    public void addThrottleControllerAt(ThrottleControllerUI tf, int n) {
114        // create a new window with the same address as the one provided in parameter
115        InstanceManager.getDefault(ThrottleFrameManager.class).createSimpleThrottleFrame(tf.getAddress());
116    }
117
118    @Override
119    public void removeThrottleController(ThrottleControllerUI tf) {
120        // if we remove our one and only controler, we dispose ourselves
121        if (tf == throttleControllerUI) {
122            dispose();
123        }        
124    }
125
126    @Override
127    public ThrottleControllerUI getThrottleControllerAt(int n) {
128        if (n == 0) {
129            return throttleControllerUI;
130        }
131        return null;
132    }
133
134    @Override
135    public ThrottleControllerUI getCurentThrottleController() {
136        return throttleControllerUI;
137    }
138
139    @Override
140    public void emergencyStopAll() {
141        throttleControllerUI.eStop();
142    }
143
144    @Override
145    public int getNumberOfEntriesFor(DccLocoAddress la) {
146        if (throttleControllerUI.getAddress() != null && throttleControllerUI.getAddress().equals(la)) {
147            return 1;
148        }
149        return 0;
150    }
151
152    @Override
153    public void dispose() {        
154        InstanceManager.getDefault(ThrottlesPreferences.class).removePropertyChangeListener(this);
155        throttleControllerUI.dispose(); // will release the throttle
156        throttleFrameManager.requestThrottleWindowDestruction(this);
157        super.dispose();        
158    }
159
160    private void applyPreferences() {
161        ThrottlesPreferences preferences = InstanceManager.getDefault(ThrottlesPreferences.class);
162
163        ComponentInputMap im = new ComponentInputMap(getRootPane());
164        for (Object k : this.getRootPane().getActionMap().allKeys()) {
165            KeyStroke[] kss = preferences.getThrottlesKeyboardControls().getKeyStrokes((String)k);
166            if (kss !=null) {
167                for (KeyStroke keystroke : kss) {
168                    if (keystroke != null) {
169                        im.put(keystroke, k);
170                    }
171                }
172            }
173        }
174        getRootPane().setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW,im);
175    }
176
177    @Override
178    public void propertyChange(PropertyChangeEvent evt) {
179        if (ThrottlesPreferences.prefPopertyName.compareTo(evt.getPropertyName()) == 0) {
180            applyPreferences();
181        }        
182    }
183}