001package jmri.jmrit.logixng.actions.swing; 002 003import java.util.List; 004import java.util.SortedSet; 005 006import javax.annotation.CheckForNull; 007import javax.annotation.Nonnull; 008import javax.swing.*; 009 010import jmri.*; 011import jmri.jmrit.logixng.*; 012import jmri.jmrit.logixng.actions.ActionReporter; 013import jmri.jmrit.logixng.actions.ActionReporter.ReporterValue; 014import jmri.jmrit.logixng.swing.SwingConfiguratorInterface; 015import jmri.jmrit.logixng.util.parser.ParserException; 016import jmri.jmrit.logixng.util.swing.LogixNG_SelectNamedBeanSwing; 017import jmri.util.swing.BeanSelectPanel; 018import jmri.util.swing.JComboBoxUtil; 019 020/** 021 * Configures an ActionReporter object with a Swing JPanel. 022 * 023 * @author Daniel Bergqvist Copyright 2021 024 * @author Dave Sand Copyright 2021 025 */ 026public class ActionReporterSwing extends AbstractDigitalActionSwing { 027 028 private LogixNG_SelectNamedBeanSwing<Reporter> _selectNamedBeanSwing; 029 030 private JPanel _panelReporterValue; 031 private JComboBox<ReporterValue> _reporterValueComboBox; 032 033 034 private JTabbedPane _tabbedPaneData; 035 private JPanel _panelDataDirect; 036 private JPanel _panelDataReference; 037 private JPanel _panelDataLocalVariable; 038 private JPanel _panelDataFormula; 039 040 private BeanSelectPanel<Memory> _memorySelectPanel; 041 private JTextField _dataReferenceTextField; 042 private JTextField _dataLocalVariableTextField; 043 private JTextField _dataFormulaTextField; 044 045 @Override 046 protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) { 047 ActionReporter action = (ActionReporter)object; 048 049 _selectNamedBeanSwing = new LogixNG_SelectNamedBeanSwing<>( 050 InstanceManager.getDefault(ReporterManager.class), getJDialog(), this); 051 052 panel = new JPanel(); 053 054 // Left section 055 _panelReporterValue = new javax.swing.JPanel(); 056 _reporterValueComboBox = new JComboBox<>(); 057 for (ReporterValue e : ReporterValue.values()) { 058 _reporterValueComboBox.addItem(e); 059 } 060 JComboBoxUtil.setupComboBoxMaxRows(_reporterValueComboBox); 061 _panelReporterValue.add(_reporterValueComboBox); 062 063 // Center section 064 JPanel _tabbedPaneNamedBean; 065 if (action != null) { 066 _tabbedPaneNamedBean = _selectNamedBeanSwing.createPanel(action.getSelectNamedBean()); 067 } else { 068 _tabbedPaneNamedBean = _selectNamedBeanSwing.createPanel(null); 069 } 070 071 // Right section 072 _tabbedPaneData = new JTabbedPane(); 073 _panelDataDirect = new javax.swing.JPanel(); 074 _panelDataReference = new javax.swing.JPanel(); 075 _panelDataLocalVariable = new javax.swing.JPanel(); 076 _panelDataFormula = new javax.swing.JPanel(); 077 078 _tabbedPaneData.addTab(NamedBeanAddressing.Direct.toString(), _panelDataDirect); 079 _tabbedPaneData.addTab(NamedBeanAddressing.Reference.toString(), _panelDataReference); 080 _tabbedPaneData.addTab(NamedBeanAddressing.LocalVariable.toString(), _panelDataLocalVariable); 081 _tabbedPaneData.addTab(NamedBeanAddressing.Formula.toString(), _panelDataFormula); 082 083 _memorySelectPanel = new BeanSelectPanel<>(InstanceManager.getDefault(MemoryManager.class), null); 084 _panelDataDirect.add(_memorySelectPanel); 085 086 _dataReferenceTextField = new JTextField(); 087 _dataReferenceTextField.setColumns(30); 088 _panelDataReference.add(_dataReferenceTextField); 089 090 _dataLocalVariableTextField = new JTextField(); 091 _dataLocalVariableTextField.setColumns(30); 092 _panelDataLocalVariable.add(_dataLocalVariableTextField); 093 094 _dataFormulaTextField = new JTextField(); 095 _dataFormulaTextField.setColumns(30); 096 _panelDataFormula.add(_dataFormulaTextField); 097 098 099 if (action != null) { 100 _reporterValueComboBox.setSelectedItem(action.getReporterValue()); 101 102 switch (action.getDataAddressing()) { 103 case Direct: _tabbedPaneData.setSelectedComponent(_panelDataDirect); break; 104 case Reference: _tabbedPaneData.setSelectedComponent(_panelDataReference); break; 105 case LocalVariable: _tabbedPaneData.setSelectedComponent(_panelDataLocalVariable); break; 106 case Formula: _tabbedPaneData.setSelectedComponent(_panelDataFormula); break; 107 default: throw new IllegalArgumentException("invalid _addressing state: " + action.getDataAddressing().name()); 108 } 109 if (action.getSelectMemoryNamedBean().getNamedBean() != null) { 110 _memorySelectPanel.setDefaultNamedBean(action.getSelectMemoryNamedBean().getNamedBean().getBean()); 111 } 112 _dataReferenceTextField.setText(action.getDataReference()); 113 _dataLocalVariableTextField.setText(action.getDataLocalVariable()); 114 _dataFormulaTextField.setText(action.getDataFormula()); 115 } 116 117 JComponent[] components = new JComponent[]{ 118 _panelReporterValue, 119 _tabbedPaneNamedBean, 120 _tabbedPaneData}; 121 122 List<JComponent> componentList = SwingConfiguratorInterface.parseMessage( 123 Bundle.getMessage("ActionReporter_Components"), components); 124 125 for (JComponent c : componentList) panel.add(c); 126 } 127 128 /** {@inheritDoc} */ 129 @Override 130 public boolean validate(@Nonnull List<String> errorMessages) { 131 ActionReporter action = new ActionReporter("IQDA1", null); 132 _selectNamedBeanSwing.validate(action.getSelectNamedBean(), errorMessages); 133 validateDataSection(errorMessages); 134 return errorMessages.isEmpty(); 135 } 136 137 private void validateDataSection(List<String> errorMessages) { 138 // Create a temporary action to test formula 139 ActionReporter action = new ActionReporter("IQDA3", null); 140 141 try { 142 if (_tabbedPaneData.getSelectedComponent() == _panelDataReference) { 143 action.setDataReference(_dataReferenceTextField.getText()); 144 } 145 } catch (IllegalArgumentException e) { 146 errorMessages.add(e.getMessage()); 147 return; 148 } 149 150 try { 151 action.setDataFormula(_dataFormulaTextField.getText()); 152 if (_tabbedPaneData.getSelectedComponent() == _panelDataDirect) { 153 action.setDataAddressing(NamedBeanAddressing.Direct); 154 } else if (_tabbedPaneData.getSelectedComponent() == _panelDataReference) { 155 action.setDataAddressing(NamedBeanAddressing.Reference); 156 } else if (_tabbedPaneData.getSelectedComponent() == _panelDataLocalVariable) { 157 action.setDataAddressing(NamedBeanAddressing.LocalVariable); 158 } else if (_tabbedPaneData.getSelectedComponent() == _panelDataFormula) { 159 action.setDataAddressing(NamedBeanAddressing.Formula); 160 } else { 161 throw new IllegalArgumentException("_tabbedPane has unknown selection"); 162 } 163 } catch (ParserException e) { 164 errorMessages.add("Cannot parse formula: " + e.getMessage()); 165 } 166 167 if (_tabbedPaneData.getSelectedComponent() == _panelDataDirect) { 168 if (_memorySelectPanel.getNamedBean() == null) { 169 errorMessages.add(Bundle.getMessage("ActionReporter_ErrorMemory")); 170 } 171 } 172 } 173 174 /** {@inheritDoc} */ 175 @Override 176 public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) { 177 ActionReporter action = new ActionReporter(systemName, userName); 178 updateObject(action); 179 return InstanceManager.getDefault(DigitalActionManager.class).registerAction(action); 180 } 181 182 /** {@inheritDoc} */ 183 @Override 184 public void updateObject(@Nonnull Base object) { 185 if (! (object instanceof ActionReporter)) { 186 throw new IllegalArgumentException("object must be an ActionReporter but is a: "+object.getClass().getName()); 187 } 188 ActionReporter action = (ActionReporter) object; 189 _selectNamedBeanSwing.updateObject(action.getSelectNamedBean()); 190 191 try { 192 // Right section 193 action.getSelectMemoryNamedBean().removeNamedBean(); 194 if (_tabbedPaneData.getSelectedComponent() == _panelDataDirect) { 195 action.setDataAddressing(NamedBeanAddressing.Direct); 196 Memory memory = _memorySelectPanel.getNamedBean(); 197 if (memory != null) { 198 NamedBeanHandle<Memory> handle 199 = InstanceManager.getDefault(NamedBeanHandleManager.class) 200 .getNamedBeanHandle(memory.getDisplayName(), memory); 201 action.getSelectMemoryNamedBean().setNamedBean(handle); 202 } 203 } else if (_tabbedPaneData.getSelectedComponent() == _panelDataReference) { 204 action.setDataAddressing(NamedBeanAddressing.Reference); 205 action.setDataReference(_dataReferenceTextField.getText()); 206 } else if (_tabbedPaneData.getSelectedComponent() == _panelDataLocalVariable) { 207 action.setDataAddressing(NamedBeanAddressing.LocalVariable); 208 action.setDataLocalVariable(_dataLocalVariableTextField.getText()); 209 } else if (_tabbedPaneData.getSelectedComponent() == _panelDataFormula) { 210 action.setDataAddressing(NamedBeanAddressing.Formula); 211 action.setDataFormula(_dataFormulaTextField.getText()); 212 } else { 213 throw new IllegalArgumentException("_tabbedPaneBean has unknown selection"); 214 } 215 216 } catch (ParserException e) { 217 throw new RuntimeException("ParserException: "+e.getMessage(), e); 218 } 219 } 220 221 /** {@inheritDoc} */ 222 @Override 223 public String toString() { 224 return Bundle.getMessage("ActionReporter_Short"); 225 } 226 227 @Override 228 public void setDefaultValues() { 229 if (_memorySelectPanel.getNamedBean() == null) { 230 SortedSet<Memory> set = InstanceManager.getDefault(MemoryManager.class).getNamedBeanSet(); 231 if (!set.isEmpty()) { 232 Memory m = set.first(); 233 _memorySelectPanel.setDefaultNamedBean(m); 234 } else { 235 log.error("Memory manager has no memories. Can't set default values"); 236 } 237 } 238 } 239 240 @Override 241 public void dispose() { 242 if (_memorySelectPanel != null) { 243 _memorySelectPanel.dispose(); 244 } 245 } 246 247 248 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ActionReporterSwing.class); 249 250}