001package jmri.jmrit.logixng.actions.swing; 002 003import java.util.List; 004 005import javax.annotation.CheckForNull; 006import javax.annotation.Nonnull; 007import javax.swing.*; 008 009import jmri.InstanceManager; 010import jmri.jmrit.logixng.*; 011import jmri.jmrit.logixng.actions.ExecuteDelayed; 012import jmri.jmrit.logixng.swing.SwingConfiguratorInterface; 013import jmri.jmrit.logixng.util.TimerUnit; 014import jmri.jmrit.logixng.util.parser.ParserException; 015import jmri.util.swing.JComboBoxUtil; 016 017/** 018 * Configures an ExecuteDelayed object with a Swing JPanel. 019 * 020 * @author Daniel Bergqvist Copyright (C) 2021 021 */ 022public class ExecuteDelayedSwing extends AbstractDigitalActionSwing { 023 024 private final JLabel _unitLabel = new JLabel(Bundle.getMessage("ExecuteDelayedSwing_Unit")); 025 private JComboBox<TimerUnit> _unitComboBox; 026 private JCheckBox _resetIfAlreadyStarted; 027 private JCheckBox _useIndividualTimers; 028 029 private JTabbedPane _tabbedPaneDelay; 030 private JFormattedTextField _timerDelay; 031 private JPanel _panelDelayDirect; 032 private JPanel _panelDelayReference; 033 private JPanel _panelDelayLocalVariable; 034 private JPanel _panelDelayFormula; 035 private JTextField _delayReferenceTextField; 036 private JTextField _delayLocalVariableTextField; 037 private JTextField _delayFormulaTextField; 038 039 @Override 040 protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) { 041 if ((object != null) && !(object instanceof ExecuteDelayed)) { 042 throw new IllegalArgumentException("object must be an ExecuteDelayed but is a: "+object.getClass().getName()); 043 } 044 045 ExecuteDelayed action = (ExecuteDelayed)object; 046 047 panel = new JPanel(); 048 panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); 049 050 _tabbedPaneDelay = new JTabbedPane(); 051 _panelDelayDirect = new javax.swing.JPanel(); 052 _panelDelayReference = new javax.swing.JPanel(); 053 _panelDelayLocalVariable = new javax.swing.JPanel(); 054 _panelDelayFormula = new javax.swing.JPanel(); 055 056 _tabbedPaneDelay.addTab(NamedBeanAddressing.Direct.toString(), _panelDelayDirect); 057 _tabbedPaneDelay.addTab(NamedBeanAddressing.Reference.toString(), _panelDelayReference); 058 _tabbedPaneDelay.addTab(NamedBeanAddressing.LocalVariable.toString(), _panelDelayLocalVariable); 059 _tabbedPaneDelay.addTab(NamedBeanAddressing.Formula.toString(), _panelDelayFormula); 060 061 _timerDelay = new JFormattedTextField("0"); 062 _timerDelay.setColumns(7); 063 064 _panelDelayDirect.add(_timerDelay); 065 066 _delayReferenceTextField = new JTextField(); 067 _delayReferenceTextField.setColumns(30); 068 _panelDelayReference.add(_delayReferenceTextField); 069 070 _delayLocalVariableTextField = new JTextField(); 071 _delayLocalVariableTextField.setColumns(30); 072 _panelDelayLocalVariable.add(_delayLocalVariableTextField); 073 074 _delayFormulaTextField = new JTextField(); 075 _delayFormulaTextField.setColumns(30); 076 _panelDelayFormula.add(_delayFormulaTextField); 077 078 079 if (action != null) { 080 switch (action.getDelayAddressing()) { 081 case Direct: _tabbedPaneDelay.setSelectedComponent(_panelDelayDirect); break; 082 case Reference: _tabbedPaneDelay.setSelectedComponent(_panelDelayReference); break; 083 case LocalVariable: _tabbedPaneDelay.setSelectedComponent(_panelDelayLocalVariable); break; 084 case Formula: _tabbedPaneDelay.setSelectedComponent(_panelDelayFormula); break; 085 default: throw new IllegalArgumentException("invalid _addressing state: " + action.getDelayAddressing().name()); 086 } 087 _timerDelay.setText(Integer.toString(action.getDelay())); 088 _delayReferenceTextField.setText(action.getDelayReference()); 089 _delayLocalVariableTextField.setText(action.getDelayLocalVariable()); 090 _delayFormulaTextField.setText(action.getDelayFormula()); 091 } 092 093 JComponent[] components = new JComponent[]{ 094 _tabbedPaneDelay}; 095 096 List<JComponent> componentList = SwingConfiguratorInterface.parseMessage( 097 Bundle.getMessage("ExecuteDelayed_Components"), components); 098 099 JPanel delayPanel = new JPanel(); 100 for (JComponent c : componentList) delayPanel.add(c); 101 102 panel.add(delayPanel); 103 104 105 JPanel unitPanel = new JPanel(); 106 unitPanel.add(_unitLabel); 107 108 _unitComboBox = new JComboBox<>(); 109 for (TimerUnit u : TimerUnit.values()) _unitComboBox.addItem(u); 110 JComboBoxUtil.setupComboBoxMaxRows(_unitComboBox); 111 if (action != null) _unitComboBox.setSelectedItem(action.getUnit()); 112 unitPanel.add(_unitComboBox); 113 114 panel.add(unitPanel); 115 116 _resetIfAlreadyStarted = new JCheckBox(Bundle.getMessage("ExecuteDelayedSwing_ResetIfAlreadyStarted")); 117 if (action != null) _resetIfAlreadyStarted.setSelected(action.getResetIfAlreadyStarted()); 118 panel.add(_resetIfAlreadyStarted); 119 120 _useIndividualTimers = new JCheckBox(Bundle.getMessage("ExecuteDelayedSwing_UseIndividualTimers")); 121 if (action != null) { 122 _useIndividualTimers.setSelected(action.getUseIndividualTimers()); 123 _resetIfAlreadyStarted.setEnabled(!action.getUseIndividualTimers()); 124 } 125 _useIndividualTimers.addActionListener((evt)->{ 126 if (_useIndividualTimers.isSelected()) { 127 _resetIfAlreadyStarted.setEnabled(false); 128 _resetIfAlreadyStarted.setSelected(false); 129 } else { 130 _resetIfAlreadyStarted.setEnabled(true); 131 } 132 }); 133 panel.add(_useIndividualTimers); 134 } 135 136 /** {@inheritDoc} */ 137 @Override 138 public boolean validate(@Nonnull List<String> errorMessages) { 139 // Create a temporary action to test formula 140 ExecuteDelayed action = new ExecuteDelayed("IQDA1", null); 141 142 try { 143 if (_tabbedPaneDelay.getSelectedComponent() == _panelDelayReference) { 144 action.setDelayReference(_delayReferenceTextField.getText()); 145 } 146 } catch (IllegalArgumentException e) { 147 errorMessages.add(e.getMessage()); 148 return false; 149 } 150 151 try { 152 action.setDelayFormula(_delayFormulaTextField.getText()); 153 if (_tabbedPaneDelay.getSelectedComponent() == _panelDelayDirect) { 154 action.setDelayAddressing(NamedBeanAddressing.Direct); 155 } else if (_tabbedPaneDelay.getSelectedComponent() == _panelDelayReference) { 156 action.setDelayAddressing(NamedBeanAddressing.Reference); 157 } else if (_tabbedPaneDelay.getSelectedComponent() == _panelDelayLocalVariable) { 158 action.setDelayAddressing(NamedBeanAddressing.LocalVariable); 159 } else if (_tabbedPaneDelay.getSelectedComponent() == _panelDelayFormula) { 160 action.setDelayAddressing(NamedBeanAddressing.Formula); 161 } else { 162 throw new IllegalArgumentException("_tabbedPane has unknown selection"); 163 } 164 } catch (ParserException e) { 165 errorMessages.add("Cannot parse formula: " + e.getMessage()); 166 return false; 167 } 168 return true; 169 } 170 171 /** {@inheritDoc} */ 172 @Override 173 public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) { 174 ExecuteDelayed action = new ExecuteDelayed(systemName, userName); 175 updateObject(action); 176 return InstanceManager.getDefault(DigitalActionManager.class).registerAction(action); 177 } 178 179 /** {@inheritDoc} */ 180 @Override 181 public void updateObject(@Nonnull Base object) { 182 if (!(object instanceof ExecuteDelayed)) { 183 throw new IllegalArgumentException("object must be an ExecuteDelayed but is a: "+object.getClass().getName()); 184 } 185 186 ExecuteDelayed action = (ExecuteDelayed)object; 187 188 action.setUnit(_unitComboBox.getItemAt(_unitComboBox.getSelectedIndex())); 189 action.setResetIfAlreadyStarted(_resetIfAlreadyStarted.isSelected()); 190 action.setUseIndividualTimers(_useIndividualTimers.isSelected()); 191 192 193 194 try { 195 if (_tabbedPaneDelay.getSelectedComponent() == _panelDelayDirect) { 196 action.setDelayAddressing(NamedBeanAddressing.Direct); 197 action.setDelay(Integer.parseInt(_timerDelay.getText())); 198 } else if (_tabbedPaneDelay.getSelectedComponent() == _panelDelayReference) { 199 action.setDelayAddressing(NamedBeanAddressing.Reference); 200 action.setDelayReference(_delayReferenceTextField.getText()); 201 } else if (_tabbedPaneDelay.getSelectedComponent() == _panelDelayLocalVariable) { 202 action.setDelayAddressing(NamedBeanAddressing.LocalVariable); 203 action.setDelayLocalVariable(_delayLocalVariableTextField.getText()); 204 } else if (_tabbedPaneDelay.getSelectedComponent() == _panelDelayFormula) { 205 action.setDelayAddressing(NamedBeanAddressing.Formula); 206 action.setDelayFormula(_delayFormulaTextField.getText()); 207 } else { 208 throw new IllegalArgumentException("_tabbedPaneDelay has unknown selection"); 209 } 210 } catch (ParserException e) { 211 throw new RuntimeException("ParserException: "+e.getMessage(), e); 212 } 213 } 214 215 /** {@inheritDoc} */ 216 @Override 217 public String toString() { 218 return Bundle.getMessage("ExecuteDelayed_Short"); 219 } 220 221 @Override 222 public void dispose() { 223 } 224 225}