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