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.ActionMemory; 012import jmri.jmrit.logixng.actions.ActionMemory.MemoryOperation; 013import jmri.jmrit.logixng.swing.SwingConfiguratorInterface; 014import jmri.jmrit.logixng.util.swing.LogixNG_SelectTableSwing; 015import jmri.jmrit.logixng.util.parser.ParserException; 016import jmri.jmrit.logixng.util.swing.LogixNG_SelectNamedBeanSwing; 017import jmri.util.swing.BeanSelectPanel; 018 019/** 020 * Configures an ActionMemory object with a Swing JPanel. 021 * 022 * @author Daniel Bergqvist Copyright 2021 023 */ 024public class ActionMemorySwing extends AbstractDigitalActionSwing { 025 026 private LogixNG_SelectTableSwing selectTableSwing; 027 028 private LogixNG_SelectNamedBeanSwing<Memory> _selectNamedBeanSwing; 029 030 private JTabbedPane _tabbedPaneMemoryOperation; 031 private BeanSelectPanel<Memory> _copyMemoryBeanPanel; 032 private JPanel _setToNull; 033 private JPanel _setToConstant; 034 private JPanel _copyMemory; 035 private JPanel _copyTableCell; 036 private JPanel _copyVariable; 037 private JPanel _calculateFormula; 038 private JTextField _setToConstantTextField; 039 private JTextField _copyLocalVariableTextField; 040 private JTextField _calculateFormulaTextField; 041 042 043 @Override 044 protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) { 045 ActionMemory action = (ActionMemory)object; 046 047 _selectNamedBeanSwing = new LogixNG_SelectNamedBeanSwing<>( 048 InstanceManager.getDefault(MemoryManager.class), getJDialog(), this); 049 050 selectTableSwing = new LogixNG_SelectTableSwing(getJDialog(), this); 051 052 panel = new JPanel(); 053 054 JPanel _tabbedPaneNamedBean; 055 if (action != null) { 056 _tabbedPaneNamedBean = _selectNamedBeanSwing.createPanel(action.getSelectNamedBean()); 057 } else { 058 _tabbedPaneNamedBean = _selectNamedBeanSwing.createPanel(null); 059 } 060 061 _tabbedPaneMemoryOperation = new JTabbedPane(); 062 063 _setToNull = new JPanel(); 064 _setToConstant = new JPanel(); 065 _copyMemory = new JPanel(); 066 if (action != null) { 067 _copyTableCell = selectTableSwing.createPanel(action.getSelectTable()); 068 } else { 069 _copyTableCell = selectTableSwing.createPanel(null); 070 } 071 _copyVariable = new JPanel(); 072 _calculateFormula = new JPanel(); 073 074 _tabbedPaneMemoryOperation.addTab(MemoryOperation.SetToNull.toString(), _setToNull); 075 _tabbedPaneMemoryOperation.addTab(MemoryOperation.SetToString.toString(), _setToConstant); 076 _tabbedPaneMemoryOperation.addTab(MemoryOperation.CopyMemoryToMemory.toString(), _copyMemory); 077 _tabbedPaneMemoryOperation.addTab(MemoryOperation.CopyTableCellToMemory.toString(), _copyTableCell); 078 _tabbedPaneMemoryOperation.addTab(MemoryOperation.CopyVariableToMemory.toString(), _copyVariable); 079 _tabbedPaneMemoryOperation.addTab(MemoryOperation.CalculateFormula.toString(), _calculateFormula); 080 081 _setToNull.add(new JLabel("Null")); // No I18N 082 083 _setToConstantTextField = new JTextField(30); 084 _setToConstant.add(_setToConstantTextField); 085 086 _copyMemoryBeanPanel = new BeanSelectPanel<>(InstanceManager.getDefault(MemoryManager.class), null); 087 _copyMemory.add(_copyMemoryBeanPanel); 088 089 _copyLocalVariableTextField = new JTextField(30); 090 _copyVariable.add(_copyLocalVariableTextField); 091 092 _calculateFormulaTextField = new JTextField(30); 093 _calculateFormula.add(_calculateFormulaTextField); 094 095 096 if (action != null) { 097 if (action.getSelectOtherMemoryNamedBean().getNamedBean() != null) { 098 _copyMemoryBeanPanel.setDefaultNamedBean(action.getSelectOtherMemoryNamedBean().getNamedBean().getBean()); 099 } 100 switch (action.getMemoryOperation()) { 101 case SetToNull: _tabbedPaneMemoryOperation.setSelectedComponent(_setToNull); break; 102 case SetToString: _tabbedPaneMemoryOperation.setSelectedComponent(_setToConstant); break; 103 case CopyMemoryToMemory: _tabbedPaneMemoryOperation.setSelectedComponent(_copyMemory); break; 104 case CopyTableCellToMemory: _tabbedPaneMemoryOperation.setSelectedComponent(_copyTableCell); break; 105 case CopyVariableToMemory: _tabbedPaneMemoryOperation.setSelectedComponent(_copyVariable); break; 106 case CalculateFormula: _tabbedPaneMemoryOperation.setSelectedComponent(_calculateFormula); break; 107 default: throw new IllegalArgumentException("invalid _addressing state: " + action.getMemoryOperation().name()); 108 } 109 _setToConstantTextField.setText(action.getConstantValue()); 110 _copyLocalVariableTextField.setText(action.getOtherLocalVariable()); 111 _calculateFormulaTextField.setText(action.getOtherFormula()); 112 } 113 114 JComponent[] components = new JComponent[]{ 115 _tabbedPaneNamedBean, 116 _tabbedPaneMemoryOperation 117 }; 118 119 List<JComponent> componentList = SwingConfiguratorInterface.parseMessage( 120 Bundle.getMessage("ActionMemory_Components"), components); 121 122 for (JComponent c : componentList) panel.add(c); 123 } 124 125 /** {@inheritDoc} */ 126 @Override 127 public boolean validate(@Nonnull List<String> errorMessages) { 128 // Create a temporary action to test formula 129 ActionMemory action = new ActionMemory("IQDA2", null); 130 131 try { 132 action.setMemoryOperation(MemoryOperation.CalculateFormula); 133 action.setOtherFormula(_calculateFormulaTextField.getText()); 134 } catch (ParserException e) { 135 errorMessages.add(e.getMessage()); 136 } 137 138 _selectNamedBeanSwing.validate(action.getSelectNamedBean(), errorMessages); 139 validateDataSection(action, errorMessages); 140 141 return errorMessages.isEmpty(); 142 } 143 144 public void validateDataSection(@Nonnull ActionMemory action, @Nonnull List<String> errorMessages) { 145 // If using the Memory tab, validate the memory variable selection. 146 if (_tabbedPaneMemoryOperation.getSelectedComponent() == _copyMemory) { 147 if (_copyMemoryBeanPanel.getNamedBean() == null) { 148 errorMessages.add(Bundle.getMessage("ActionMemory_CopyErrorMemory")); 149 } 150 } 151 152 // Validate formula parsing via setFormula and tab selection. 153 try { 154 action.setOtherFormula(_calculateFormulaTextField.getText()); 155 if (_tabbedPaneMemoryOperation.getSelectedComponent() == _calculateFormula) { 156 action.setMemoryOperation(ActionMemory.MemoryOperation.CalculateFormula); 157 } 158 } catch (ParserException e) { 159 errorMessages.add("Cannot parse formula: " + e.getMessage()); 160 } 161 162 selectTableSwing.validate(action.getSelectTable(), errorMessages); 163 } 164 165 /** {@inheritDoc} */ 166 @Override 167 public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) { 168 ActionMemory action = new ActionMemory(systemName, userName); 169 updateObject(action); 170 return InstanceManager.getDefault(DigitalActionManager.class).registerAction(action); 171 } 172 173 /** {@inheritDoc} */ 174 @Override 175 public void updateObject(@Nonnull Base object) { 176 if (! (object instanceof ActionMemory)) { 177 throw new IllegalArgumentException("object must be an ActionMemory but is a: "+object.getClass().getName()); 178 } 179 ActionMemory action = (ActionMemory)object; 180 _selectNamedBeanSwing.updateObject(action.getSelectNamedBean()); 181 182 if (_tabbedPaneMemoryOperation.getSelectedComponent() == _copyMemory) { 183 Memory otherMemory = _copyMemoryBeanPanel.getNamedBean(); 184 if (otherMemory != null) { 185 NamedBeanHandle<Memory> handle 186 = InstanceManager.getDefault(NamedBeanHandleManager.class) 187 .getNamedBeanHandle(otherMemory.getDisplayName(), otherMemory); 188 action.getSelectOtherMemoryNamedBean().setNamedBean(handle); 189 } else { 190 action.getSelectOtherMemoryNamedBean().removeNamedBean(); 191 } 192 } else { 193 action.getSelectOtherMemoryNamedBean().removeNamedBean(); 194 } 195 196 try { 197 if (_tabbedPaneMemoryOperation.getSelectedComponent() == _setToNull) { 198 action.setMemoryOperation(ActionMemory.MemoryOperation.SetToNull); 199 } else if (_tabbedPaneMemoryOperation.getSelectedComponent() == _setToConstant) { 200 action.setMemoryOperation(ActionMemory.MemoryOperation.SetToString); 201 action.setOtherConstantValue(_setToConstantTextField.getText()); 202 } else if (_tabbedPaneMemoryOperation.getSelectedComponent() == _copyMemory) { 203 action.setMemoryOperation(ActionMemory.MemoryOperation.CopyMemoryToMemory); 204 } else if (_tabbedPaneMemoryOperation.getSelectedComponent() == _copyTableCell) { 205 action.setMemoryOperation(ActionMemory.MemoryOperation.CopyTableCellToMemory); 206 } else if (_tabbedPaneMemoryOperation.getSelectedComponent() == _copyVariable) { 207 action.setMemoryOperation(ActionMemory.MemoryOperation.CopyVariableToMemory); 208 action.setOtherLocalVariable(_copyLocalVariableTextField.getText()); 209 } else if (_tabbedPaneMemoryOperation.getSelectedComponent() == _calculateFormula) { 210 action.setMemoryOperation(ActionMemory.MemoryOperation.CalculateFormula); 211 action.setOtherFormula(_calculateFormulaTextField.getText()); 212 } else { 213 throw new IllegalArgumentException("_tabbedPaneMemoryOperation has unknown selection"); 214 } 215 } catch (ParserException e) { 216 throw new RuntimeException("ParserException: "+e.getMessage(), e); 217 } 218 219 selectTableSwing.updateObject(action.getSelectTable()); 220 } 221 222 /** {@inheritDoc} */ 223 @Override 224 public String toString() { 225 return Bundle.getMessage("ActionMemory_Short"); 226 } 227 228 /** {@inheritDoc} */ 229 @Override 230 public boolean canClose() { 231 return selectTableSwing.canClose(); 232 } 233 234 @Override 235 public void dispose() { 236 selectTableSwing.dispose(); 237 } 238 239// private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ActionMemorySwing.class); 240 241}