001package jmri.jmrit.logix;
002
003import java.awt.Dimension;
004import java.awt.event.ActionEvent;
005import java.awt.event.ActionListener;
006import java.awt.event.WindowAdapter;
007import java.awt.event.WindowEvent;
008import javax.swing.ButtonGroup;
009import javax.swing.JDesktopPane;
010import javax.swing.JMenu;
011import javax.swing.JMenuBar;
012import javax.swing.JMenuItem;
013import javax.swing.JRadioButtonMenuItem;
014import jmri.DccThrottle;
015import jmri.InstanceManager;
016import jmri.JmriException;
017import jmri.PowerManager;
018import jmri.SpeedStepMode;
019import jmri.jmrit.throttle.FunctionButton;
020import jmri.util.JmriJFrame;
021import org.slf4j.Logger;
022import org.slf4j.LoggerFactory;
023
024/**
025 * A JFrame to contain throttle elements such as speed control, function panel.
026 * It keeps a record of the throttle commands for playback later.
027 * <p>
028 *
029 * Modeled on package jmri.jmrit.throttle by
030 *
031 * @author Glen Oberhauser
032 * @author Bob Jacobsen Copyright 2008
033 *
034 * @author Pete Cressman Copyright 2009, 2020
035 */
036public class LearnThrottleFrame extends JmriJFrame { //implements java.beans.PropertyChangeListener {
037
038    private WarrantFrame _warrantFrame;
039    private PowerManager powerMgr = null;
040    private LearnControlPanel _controlPanel;
041    private LearnFunctionPanel _functionPanel;
042    private LearnSpeedPanel _speedPanel;
043
044    /**
045     * Default constructor
046     * @param warrantFrame caller
047     */
048    public LearnThrottleFrame(WarrantFrame warrantFrame) {
049        super(false, false);
050        _warrantFrame = warrantFrame;
051        powerMgr = InstanceManager.getNullableDefault(jmri.PowerManager.class);
052        if (powerMgr == null) {
053            log.info("No power manager instance found, panel not active");
054        }
055        initGUI();
056        setVisible(true);
057    }
058
059    /**
060     * Get notification that a throttle has been found as you requested.
061     *
062     * @param t An instantiation of the DccThrottle with the address requested.
063     */
064    public void notifyThrottleFound(DccThrottle t) {
065        if (log.isDebugEnabled()) {
066            log.debug("notifyThrottleFound address= {} class= {}",t.getLocoAddress(),t.getClass().getName());
067        }
068        _controlPanel.notifyAddressThrottleFound(t);
069        _functionPanel.notifyAddressThrottleFound(t);
070        _speedPanel.notifyAddressThrottleFound(t);
071        setSpeedSetting(0.0f);      // be sure loco is stopped.
072        setButtonForward(t.getIsForward());
073        String name = _warrantFrame.getTrainName();
074        if (name == null || name.isEmpty()) {
075            jmri.jmrit.roster.RosterEntry re = _warrantFrame._speedUtil.getRosterEntry();
076            if (re != null) {
077                name = re.getId();
078            } else {
079                name = t.getLocoAddress().toString();
080            }
081        } else {
082            name =name +" - " + t.getLocoAddress().toString();
083        }
084        setTitle(name);
085    }
086
087    private void initGUI() {
088        setTitle("Throttle");
089        this.addWindowListener(new WindowAdapter() {
090            @Override
091            public void windowClosing(WindowEvent e) {
092                _warrantFrame.close();
093                dispose();
094            }
095        });
096        initializeMenu();
097
098        _controlPanel = new LearnControlPanel(this);
099        _controlPanel.setVisible(true);
100        _controlPanel.setEnabled(false);
101        _controlPanel.setTitle(Bundle.getMessage("speed"));
102        _controlPanel.setSize(_controlPanel.getPreferredSize());
103
104        int width = 3 * (FunctionButton.getButtonWidth()) + 2 * 3 * 5 + 11;   // = 192
105        int height = 9 * (FunctionButton.getButtonHeight()) + 2 * 6 * 5 + 20; // FunctionButton.BUT_IMG_SIZE = 45
106        _functionPanel = new LearnFunctionPanel(this);
107        _functionPanel.setSize(width, height);
108        _functionPanel.setVisible(true);
109        _functionPanel.setEnabled(false);
110        _functionPanel.setTitle(Bundle.getMessage("setFunction"));
111
112        _speedPanel = new LearnSpeedPanel(_warrantFrame.getWarrant());
113        _speedPanel.setSize(_functionPanel.getWidth(), _controlPanel.getHeight() - _functionPanel.getHeight());
114        _speedPanel.setVisible(true);
115        _speedPanel.setClosable(true);
116        _speedPanel.setTitle(java.util.ResourceBundle.getBundle("jmri/jmrit/throttle/ThrottleBundle").getString("ThrottleMenuViewSpeedPanel"));
117
118        _controlPanel.setLocation(0, 0);
119        _functionPanel.setLocation(_controlPanel.getWidth(), 0);
120        _speedPanel.setLocation(_controlPanel.getWidth(), _functionPanel.getHeight());
121
122        JDesktopPane desktop = new JDesktopPane();
123        getContentPane().add(desktop);
124        desktop.add(_controlPanel);
125        desktop.add(_functionPanel);
126        desktop.add(_speedPanel);
127
128        desktop.setPreferredSize(new Dimension(
129                _controlPanel.getWidth() + _functionPanel.getWidth(), _controlPanel.getHeight()));
130
131        setResizable(false);
132        jmri.util.PlaceWindow.getDefault().nextTo(_warrantFrame, null, this);
133        pack();
134    }
135
136    /**
137     * Set up View, Edit and Power Menus
138     */
139    private void initializeMenu() {
140        JMenu speedControl = new JMenu(Bundle.getMessage("SpeedControl"));
141        ButtonGroup buttonGroup = new ButtonGroup();
142        JRadioButtonMenuItem displaySlider = new JRadioButtonMenuItem(Bundle.getMessage("ButtonDisplaySpeedSlider"));
143        displaySlider.addActionListener((ActionEvent e)->_controlPanel.setSpeedController(jmri.jmrit.throttle.ControlPanel.SLIDERDISPLAYCONTINUOUS));
144        displaySlider.setSelected(true);
145        buttonGroup.add(displaySlider);
146        speedControl.add(displaySlider);
147        JRadioButtonMenuItem displaySteps = new JRadioButtonMenuItem(Bundle.getMessage("ButtonDisplaySpeedSteps"));
148        displaySteps.addActionListener((ActionEvent e)->_controlPanel.setSpeedController(jmri.jmrit.throttle.ControlPanel.STEPDISPLAY));
149        buttonGroup.add(displaySteps);
150        speedControl.add(displaySteps);
151        this.setJMenuBar(new JMenuBar());
152        this.getJMenuBar().add(speedControl);
153
154       if (powerMgr != null) {
155            JMenu powerMenu = new JMenu(Bundle.getMessage("ThrottleMenuPower"));
156            JMenuItem powerOn = new JMenuItem(Bundle.getMessage("ThrottleMenuPowerOn"));
157            powerMenu.add(powerOn);
158            powerOn.addActionListener(new ActionListener() {
159
160                @Override
161                public void actionPerformed(ActionEvent e) {
162                    try {
163                        powerMgr.setPower(PowerManager.ON);
164                    } catch (JmriException e1) {
165                        log.error("Error when setting power", e1);
166                    }
167                }
168            });
169
170            JMenuItem powerOff = new JMenuItem(Bundle.getMessage("ThrottleMenuPowerOff"));
171            powerMenu.add(powerOff);
172            powerOff.addActionListener(new ActionListener() {
173
174                @Override
175                public void actionPerformed(ActionEvent e) {
176                    try {
177                        powerMgr.setPower(PowerManager.OFF);
178                    } catch (JmriException e1) {
179                        log.error("Error when setting power", e1);
180                    }
181                }
182            });
183
184            this.getJMenuBar().add(powerMenu);
185        }
186        // add help selection
187        addHelpMenu("package.jmri.jmrit.throttle.ThrottleFrame", true);
188    }
189
190    @Override
191    public void dispose() {
192        _controlPanel.destroy();
193        _functionPanel.destroy();
194        _speedPanel.destroy();
195        _controlPanel.dispose();
196        _functionPanel.dispose();
197        super.dispose();
198    }
199
200    /* Record throttle commands that have been sent to the throttle from ControlPanel */
201
202    protected void setSpeedSetting(float speed) {
203        _warrantFrame.setSpeedCommand(speed);
204    }
205
206    protected void setSpeedStepMode(SpeedStepMode speedStep) {
207        _warrantFrame.setThrottleCommand("SpeedStep", speedStep.name);
208    }
209
210    protected void setFunctionState(String FNum, boolean isSet) {
211        _warrantFrame.setThrottleCommand(FNum, Boolean.toString(isSet));
212    }
213
214    protected void setFunctionLock(String FMom, boolean isLockable) {
215        _warrantFrame.setThrottleCommand(FMom, Boolean.toString(isLockable));
216    }
217
218    protected void setButtonForward(boolean isForward) {
219        _warrantFrame.setThrottleCommand("Forward", Boolean.toString(isForward));
220    }
221
222    private static final Logger log = LoggerFactory.getLogger(LearnThrottleFrame.class);
223
224}