001package jmri.jmrit.logixng.expressions.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.expressions.ExpressionDispatcher; 012import jmri.jmrit.logixng.expressions.ExpressionDispatcher.DispatcherState; 013import jmri.jmrit.logixng.swing.SwingConfiguratorInterface; 014import jmri.jmrit.logixng.util.DispatcherActiveTrainManager; 015import jmri.jmrit.logixng.util.parser.ParserException; 016import jmri.jmrit.logixng.util.swing.LogixNG_SelectEnumSwing; 017import jmri.util.swing.JComboBoxUtil; 018 019/** 020 * Configures an ExpressionDispatcher object with a Swing JPanel. 021 * 022 * @author Daniel Bergqvist Copyright 2021 023 */ 024public class ExpressionDispatcherSwing extends AbstractDigitalExpressionSwing { 025 026 private LogixNG_SelectEnumSwing<DispatcherState> _selectEnumSwing; 027 028 private JTabbedPane _tabbedPaneDispatcher; 029 private JPanel _panelDispatcherDirect; 030 private JPanel _panelDispatcherReference; 031 private JPanel _panelDispatcherLocalVariable; 032 private JPanel _panelDispatcherFormula; 033 034 private JComboBox<String> _fileNamesComboBox; 035 private JTextField _dispatcherReferenceTextField; 036 private JTextField _dispatcherLocalVariableTextField; 037 private JTextField _dispatcherFormulaTextField; 038 039 private JComboBox<Is_IsNot_Enum> _is_IsNot_ComboBox; 040 041 042 @Override 043 protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) { 044 ExpressionDispatcher expression = (ExpressionDispatcher)object; 045 046 _selectEnumSwing = new LogixNG_SelectEnumSwing<>(getJDialog(), this); 047 048 049 JPanel _tabbedPaneEnum; 050 051 if (expression != null) { 052// _tabbedPaneNamedBean = _selectNamedBeanSwing.createPanel(expression.getSelectNamedBean()); 053 _tabbedPaneEnum = _selectEnumSwing.createPanel(expression.getSelectEnum(), DispatcherState.values()); 054 } else { 055// _tabbedPaneNamedBean = _selectNamedBeanSwing.createPanel(null); 056 _tabbedPaneEnum = _selectEnumSwing.createPanel(null, DispatcherState.values()); 057 } 058 059 060 061 panel = new JPanel(); 062 063 _tabbedPaneDispatcher = new JTabbedPane(); 064 _panelDispatcherDirect = new javax.swing.JPanel(); 065 _panelDispatcherReference = new javax.swing.JPanel(); 066 _panelDispatcherLocalVariable = new javax.swing.JPanel(); 067 _panelDispatcherFormula = new javax.swing.JPanel(); 068 069 _tabbedPaneDispatcher.addTab(NamedBeanAddressing.Direct.toString(), _panelDispatcherDirect); 070 _tabbedPaneDispatcher.addTab(NamedBeanAddressing.Reference.toString(), _panelDispatcherReference); 071 _tabbedPaneDispatcher.addTab(NamedBeanAddressing.LocalVariable.toString(), _panelDispatcherLocalVariable); 072 _tabbedPaneDispatcher.addTab(NamedBeanAddressing.Formula.toString(), _panelDispatcherFormula); 073 074 _fileNamesComboBox = new JComboBox<>(); 075 InstanceManager.getDefault(DispatcherActiveTrainManager.class).getTrainInfoFileNames().forEach(name -> { 076 _fileNamesComboBox.addItem(name); 077 }); 078 JComboBoxUtil.setupComboBoxMaxRows(_fileNamesComboBox); 079 _panelDispatcherDirect.add(_fileNamesComboBox); 080 081 _dispatcherReferenceTextField = new JTextField(); 082 _dispatcherReferenceTextField.setColumns(30); 083 _panelDispatcherReference.add(_dispatcherReferenceTextField); 084 085 _dispatcherLocalVariableTextField = new JTextField(); 086 _dispatcherLocalVariableTextField.setColumns(30); 087 _panelDispatcherLocalVariable.add(_dispatcherLocalVariableTextField); 088 089 _dispatcherFormulaTextField = new JTextField(); 090 _dispatcherFormulaTextField.setColumns(30); 091 _panelDispatcherFormula.add(_dispatcherFormulaTextField); 092 093 094 _is_IsNot_ComboBox = new JComboBox<>(); 095 for (Is_IsNot_Enum e : Is_IsNot_Enum.values()) { 096 _is_IsNot_ComboBox.addItem(e); 097 } 098 JComboBoxUtil.setupComboBoxMaxRows(_is_IsNot_ComboBox); 099 100 101 102 if (expression != null) { 103 switch (expression.getAddressing()) { 104 case Direct: _tabbedPaneDispatcher.setSelectedComponent(_panelDispatcherDirect); break; 105 case Reference: _tabbedPaneDispatcher.setSelectedComponent(_panelDispatcherReference); break; 106 case LocalVariable: _tabbedPaneDispatcher.setSelectedComponent(_panelDispatcherLocalVariable); break; 107 case Formula: _tabbedPaneDispatcher.setSelectedComponent(_panelDispatcherFormula); break; 108 default: throw new IllegalArgumentException("invalid _addressing state: " + expression.getAddressing().name()); 109 } 110 111 _fileNamesComboBox.setSelectedItem(expression.getTrainInfoFileName()); 112 _dispatcherReferenceTextField.setText(expression.getReference()); 113 _dispatcherLocalVariableTextField.setText(expression.getLocalVariable()); 114 _dispatcherFormulaTextField.setText(expression.getFormula()); 115 116 _is_IsNot_ComboBox.setSelectedItem(expression.get_Is_IsNot()); 117 } 118 119 JComponent[] components = new JComponent[]{ 120 _tabbedPaneDispatcher, 121 _is_IsNot_ComboBox, 122 _tabbedPaneEnum}; 123 124 List<JComponent> componentList = SwingConfiguratorInterface.parseMessage( 125 Bundle.getMessage("ExpressionDispatcher_Components"), components); 126 127 for (JComponent c : componentList) panel.add(c); 128 } 129 130 /** {@inheritDoc} */ 131 @Override 132 public boolean validate(@Nonnull List<String> errorMessages) { 133 if (_selectEnumSwing.getAddressing() == NamedBeanAddressing.Direct) { 134 DispatcherState state = _selectEnumSwing.getEnum(); 135 if (state.getType().equals("Separator")) { 136 errorMessages.add(Bundle.getMessage("Dispatcher_No_Status_Selected")); 137 } 138 } 139 140 // Create a temporary expression to test formula 141 ExpressionDispatcher expression = new ExpressionDispatcher("IQDE1", null); 142 143 try { 144 if (_tabbedPaneDispatcher.getSelectedComponent() == _panelDispatcherReference) { 145 expression.setReference(_dispatcherReferenceTextField.getText()); 146 } 147 } catch (IllegalArgumentException e) { 148 errorMessages.add(e.getMessage()); 149 return false; 150 } 151 152 _selectEnumSwing.validate(expression.getSelectEnum(), errorMessages); 153 154 try { 155 expression.setFormula(_dispatcherFormulaTextField.getText()); 156 if (_tabbedPaneDispatcher.getSelectedComponent() == _panelDispatcherDirect) { 157 expression.setAddressing(NamedBeanAddressing.Direct); 158 } else if (_tabbedPaneDispatcher.getSelectedComponent() == _panelDispatcherReference) { 159 expression.setAddressing(NamedBeanAddressing.Reference); 160 } else if (_tabbedPaneDispatcher.getSelectedComponent() == _panelDispatcherLocalVariable) { 161 expression.setAddressing(NamedBeanAddressing.LocalVariable); 162 } else if (_tabbedPaneDispatcher.getSelectedComponent() == _panelDispatcherFormula) { 163 expression.setAddressing(NamedBeanAddressing.Formula); 164 } else { 165 throw new IllegalArgumentException("_tabbedPane has unknown selection"); 166 } 167 } catch (ParserException e) { 168 errorMessages.add("Cannot parse formula: " + e.getMessage()); 169 } 170 171 return errorMessages.isEmpty(); 172 } 173 174 /** {@inheritDoc} */ 175 @Override 176 public String getAutoSystemName() { 177 return InstanceManager.getDefault(DigitalExpressionManager.class).getAutoSystemName(); 178 } 179 180 /** {@inheritDoc} */ 181 @Override 182 public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) { 183 ExpressionDispatcher expression = new ExpressionDispatcher(systemName, userName); 184 updateObject(expression); 185 return InstanceManager.getDefault(DigitalExpressionManager.class).registerExpression(expression); 186 } 187 188 /** {@inheritDoc} */ 189 @Override 190 public void updateObject(@Nonnull Base object) { 191 if (! (object instanceof ExpressionDispatcher)) { 192 throw new IllegalArgumentException("object must be an ExpressionDispatcher but is a: " + object.getClass().getName()); 193 } 194 ExpressionDispatcher expression = (ExpressionDispatcher)object; 195 196 try { 197 if (_tabbedPaneDispatcher.getSelectedComponent() == _panelDispatcherDirect) { 198 expression.setAddressing(NamedBeanAddressing.Direct); 199 expression.setTrainInfoFileName((String) _fileNamesComboBox.getSelectedItem()); 200 } else if (_tabbedPaneDispatcher.getSelectedComponent() == _panelDispatcherReference) { 201 expression.setAddressing(NamedBeanAddressing.Reference); 202 expression.setReference(_dispatcherReferenceTextField.getText()); 203 } else if (_tabbedPaneDispatcher.getSelectedComponent() == _panelDispatcherLocalVariable) { 204 expression.setAddressing(NamedBeanAddressing.LocalVariable); 205 expression.setLocalVariable(_dispatcherLocalVariableTextField.getText()); 206 } else if (_tabbedPaneDispatcher.getSelectedComponent() == _panelDispatcherFormula) { 207 expression.setAddressing(NamedBeanAddressing.Formula); 208 expression.setFormula(_dispatcherFormulaTextField.getText()); 209 } else { 210 throw new IllegalArgumentException("_tabbedPaneDispatcher has unknown selection"); 211 } 212 213 expression.set_Is_IsNot((Is_IsNot_Enum)_is_IsNot_ComboBox.getSelectedItem()); 214 215 _selectEnumSwing.updateObject(expression.getSelectEnum()); 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("Dispatcher_Short"); 225 } 226 227 @Override 228 public void dispose() { 229 _selectEnumSwing.dispose(); 230 } 231 232 @Override 233 public void setDefaultValues() { 234 _selectEnumSwing.setEnum(DispatcherState.Manual); 235 } 236 237// private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ExpressionDispatcherSwing.class); 238 239}