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.*; 010import jmri.jmrit.logixng.*; 011import jmri.jmrit.logixng.actions.ForEach; 012import jmri.jmrit.logixng.actions.CommonManager; 013import jmri.jmrit.logixng.actions.ForEach.UserSpecifiedSource; 014import jmri.jmrit.logixng.util.parser.ParserException; 015import jmri.jmrit.logixng.util.swing.LogixNG_SelectNamedBeanSwing; 016import jmri.jmrit.logixng.util.swing.LogixNG_SelectStringSwing; 017import jmri.util.swing.JComboBoxUtil; 018 019/** 020 * Configures an ForEach object with a Swing JPanel. 021 * 022 * @author Daniel Bergqvist Copyright 2021 023 */ 024public class ForEachSwing extends AbstractDigitalActionSwing { 025 026 private LogixNG_SelectStringSwing _selectVariableSwing; 027 private LogixNG_SelectNamedBeanSwing<Memory> _selectMemorySwing; 028 029 private JTabbedPane _commonOrUserSpecifiedPane; 030 private JPanel _commonPanel; 031 private JComboBox<CommonManager> _commonManagersComboBox; 032 033 private JTabbedPane _tabbedPaneUserSpecifiedSource; 034 JPanel _tabbedPaneMemoryBean; 035 JPanel _tabbedPaneVariable; 036 private JPanel _calculateFormula; 037 private JTextField _calculateFormulaTextField; 038 039 private JTextField _localVariable; 040 041 @Override 042 protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) { 043 if ((object != null) && !(object instanceof ForEach)) { 044 throw new IllegalArgumentException("object must be an ForEach but is a: "+object.getClass().getName()); 045 } 046 047 ForEach action = (ForEach)object; 048 049 _selectVariableSwing = new LogixNG_SelectStringSwing(getJDialog(), this); 050 051 _selectMemorySwing = new LogixNG_SelectNamedBeanSwing<>( 052 InstanceManager.getDefault(MemoryManager.class), getJDialog(), this); 053 054 panel = new JPanel(); 055 panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); 056 057 if (action != null) { 058 _tabbedPaneMemoryBean = _selectMemorySwing.createPanel(action.getSelectMemoryNamedBean()); 059 _tabbedPaneVariable = _selectVariableSwing.createPanel(action.getSelectVariable()); 060 } else { 061 _tabbedPaneMemoryBean = _selectMemorySwing.createPanel(null); 062 _tabbedPaneVariable = _selectVariableSwing.createPanel(null); 063 } 064 065 _commonOrUserSpecifiedPane = new JTabbedPane(); 066 067 _commonPanel = new JPanel(); 068 _commonOrUserSpecifiedPane.addTab(Bundle.getMessage("ForEachSwing_Common"), _commonPanel); 069 _commonManagersComboBox = new JComboBox<>(); 070 for (CommonManager commonManager : CommonManager.values()) { 071 _commonManagersComboBox.addItem(commonManager); 072 } 073 JComboBoxUtil.setupComboBoxMaxRows(_commonManagersComboBox); 074 075 _commonPanel.add(_commonManagersComboBox); 076 077 078 _tabbedPaneUserSpecifiedSource = new JTabbedPane(); 079 _commonOrUserSpecifiedPane.addTab(Bundle.getMessage("ForEachSwing_UserSpecified"), _tabbedPaneUserSpecifiedSource); 080 081 _calculateFormula = new JPanel(); 082 083 _tabbedPaneUserSpecifiedSource.addTab(UserSpecifiedSource.Memory.toString(), _tabbedPaneMemoryBean); 084 _tabbedPaneUserSpecifiedSource.addTab(UserSpecifiedSource.Variable.toString(), _tabbedPaneVariable); 085 _tabbedPaneUserSpecifiedSource.addTab(UserSpecifiedSource.Formula.toString(), _calculateFormula); 086 087 _calculateFormulaTextField = new JTextField(30); 088 _calculateFormula.add(_calculateFormulaTextField); 089 090 JPanel localVariablePanel = new JPanel(); 091 localVariablePanel.add(new JLabel(Bundle.getMessage("ForEachSwing_LocalVariable"))); 092 _localVariable = new JTextField(20); 093 localVariablePanel.add(_localVariable); 094 panel.add(localVariablePanel); 095 096 097 if (action != null) { 098 if (!action.isUseCommonSource()) { 099 _commonOrUserSpecifiedPane.setSelectedComponent(_tabbedPaneUserSpecifiedSource); 100 } 101 _commonManagersComboBox.setSelectedItem(action.getCommonManager()); 102 103 switch (action.getUserSpecifiedSource()) { 104 case Memory: _tabbedPaneUserSpecifiedSource.setSelectedComponent(_tabbedPaneMemoryBean); break; 105 case Variable: _tabbedPaneUserSpecifiedSource.setSelectedComponent(_tabbedPaneVariable); break; 106 case Formula: _tabbedPaneUserSpecifiedSource.setSelectedComponent(_calculateFormula); break; 107 default: throw new IllegalArgumentException("invalid _addressing state: " + action.getUserSpecifiedSource().name()); 108 } 109 _calculateFormulaTextField.setText(action.getFormula()); 110 111 _localVariable.setText(action.getLocalVariableName()); 112 } 113 114 115 panel.add(_commonOrUserSpecifiedPane); 116 panel.add(localVariablePanel); 117 } 118 119 /** {@inheritDoc} */ 120 @Override 121 public boolean validate(@Nonnull List<String> errorMessages) { 122 // Create a temporary action to test formula 123 ForEach action = new ForEach("IQDA1", null); 124 125 if (_commonOrUserSpecifiedPane.getSelectedComponent() == _tabbedPaneUserSpecifiedSource) { 126 // If using the Memory tab, validate the memory variable selection. 127 if (_tabbedPaneUserSpecifiedSource.getSelectedComponent() == _tabbedPaneMemoryBean) { 128 _selectMemorySwing.validate(action.getSelectMemoryNamedBean(), errorMessages); 129 } 130 131 // If using the Variable tab, validate the memory variable selection. 132 if (_tabbedPaneUserSpecifiedSource.getSelectedComponent() == _tabbedPaneVariable) { 133 _selectVariableSwing.validate(action.getSelectVariable(), errorMessages); 134 } 135 136 if (_tabbedPaneUserSpecifiedSource.getSelectedComponent() == _calculateFormula) { 137 try { 138 action.setUserSpecifiedSource(UserSpecifiedSource.Formula); 139 action.setFormula(_calculateFormulaTextField.getText()); 140 } catch (ParserException e) { 141 errorMessages.add(e.getMessage()); 142 } 143 } 144 } 145 146 return errorMessages.isEmpty(); 147 } 148 149 /** {@inheritDoc} */ 150 @Override 151 public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) { 152 ForEach action = new ForEach(systemName, userName); 153 updateObject(action); 154 return InstanceManager.getDefault(DigitalActionManager.class).registerAction(action); 155 } 156 157 /** {@inheritDoc} */ 158 @Override 159 public void updateObject(@Nonnull Base object) { 160 if (!(object instanceof ForEach)) { 161 throw new IllegalArgumentException("object must be an ForEach but is a: "+object.getClass().getName()); 162 } 163 164 ForEach action = (ForEach)object; 165 166 try { 167 if (_commonOrUserSpecifiedPane.getSelectedComponent() == _commonPanel) { 168 169 action.setUseCommonSource(true); 170 action.setCommonManager(_commonManagersComboBox.getItemAt( 171 _commonManagersComboBox.getSelectedIndex())); 172 173 } else if (_commonOrUserSpecifiedPane.getSelectedComponent() == _tabbedPaneUserSpecifiedSource) { 174 175 action.setUseCommonSource(false); 176 177 try { 178 if (_tabbedPaneUserSpecifiedSource.getSelectedComponent() == _tabbedPaneMemoryBean) { 179 action.setUserSpecifiedSource(UserSpecifiedSource.Memory); 180 _selectMemorySwing.updateObject(action.getSelectMemoryNamedBean()); 181 } else if (_tabbedPaneUserSpecifiedSource.getSelectedComponent() == _tabbedPaneVariable) { 182 action.setUserSpecifiedSource(UserSpecifiedSource.Variable); 183 _selectVariableSwing.updateObject(action.getSelectVariable()); 184 } else if (_tabbedPaneUserSpecifiedSource.getSelectedComponent() == _calculateFormula) { 185 action.setUserSpecifiedSource(UserSpecifiedSource.Formula); 186 action.setFormula(_calculateFormulaTextField.getText()); 187 } else { 188 throw new IllegalArgumentException("_tabbedPaneUserSpecifiedSource has unknown selection"); 189 } 190 } catch (ParserException e) { 191 throw new RuntimeException("ParserException: "+e.getMessage(), e); 192 } 193 194 } else { 195 throw new IllegalArgumentException("_tabbedPaneUserSpecifiedSource has unknown selection"); 196 } 197 } catch (ParserException e) { 198 throw new RuntimeException("ParserException: "+e.getMessage(), e); 199 } 200 201 action.setLocalVariableName(_localVariable.getText()); 202 } 203 204 /** {@inheritDoc} */ 205 @Override 206 public String toString() { 207 return Bundle.getMessage("ForEach_Short"); 208 } 209 210 @Override 211 public void dispose() { 212 } 213 214// private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ForEachSwing.class); 215 216}