001package jmri.jmrit.logixng.util.swing; 002 003import java.util.List; 004import java.util.function.Predicate; 005 006import javax.annotation.CheckForNull; 007import javax.annotation.Nonnull; 008import javax.swing.*; 009 010import jmri.*; 011import jmri.jmrit.logixng.*; 012import jmri.jmrit.logixng.swing.SwingConfiguratorInterface; 013import jmri.jmrit.logixng.util.LogixNG_SelectNamedBean; 014import jmri.jmrit.logixng.util.parser.ParserException; 015import jmri.util.swing.BeanSelectPanel; 016 017/** 018 * Swing class for jmri.jmrit.logixng.util.LogixNG_SelectNamedBean. 019 * 020 * @param <E> the type of the named bean 021 * 022 * @author Daniel Bergqvist (C) 2022 023 */ 024public class LogixNG_SelectNamedBeanSwing<E extends NamedBean> { 025 026 private final @Nonnull Manager<E> _manager; 027 private final JDialog _dialog; 028 private final LogixNG_SelectTableSwing _selectTableSwing; 029 030 private boolean onlyDirectAddressing = false; 031 032 private JTabbedPane _tabbedPane; 033 private BeanSelectPanel<E> _namedBeanPanel; 034 private JPanel _panelDirect; 035 private JPanel _panelReference; 036 private JPanel _panelMemory; 037 private JPanel _panelLocalVariable; 038 private JPanel _panelFormula; 039 private JPanel _panelTable; 040 private JTextField _referenceTextField; 041 private BeanSelectPanel<Memory> _memoryPanel; 042 private JTextField _localVariableTextField; 043 private JTextField _formulaTextField; 044 045 046 public LogixNG_SelectNamedBeanSwing( 047 @Nonnull Manager<E> manager, 048 @Nonnull JDialog dialog, 049 @Nonnull SwingConfiguratorInterface swi) { 050 _manager = manager; 051 _dialog = dialog; 052 _selectTableSwing = new LogixNG_SelectTableSwing(_dialog, swi); 053 } 054 055 public JPanel createPanel( 056 @CheckForNull LogixNG_SelectNamedBean<E> selectNamedBean) { 057 return createPanel(selectNamedBean, null); 058 } 059 060 public JPanel createPanel( 061 @CheckForNull LogixNG_SelectNamedBean<E> selectNamedBean, 062 @CheckForNull Predicate<E> filter) { 063 064 onlyDirectAddressing = selectNamedBean != null 065 && selectNamedBean.getOnlyDirectAddressingAllowed(); 066 067 JPanel panel = new JPanel(); 068 069 _tabbedPane = new JTabbedPane(); 070 _panelDirect = new javax.swing.JPanel(); 071 _panelReference = new javax.swing.JPanel(); 072 _panelMemory = new JPanel(); 073 _panelLocalVariable = new javax.swing.JPanel(); 074 _panelFormula = new javax.swing.JPanel(); 075 if (selectNamedBean != null) { 076 _panelTable = _selectTableSwing.createPanel(selectNamedBean.getSelectTable()); 077 } else { 078 _panelTable = _selectTableSwing.createPanel(null); 079 } 080 081 _memoryPanel = new BeanSelectPanel<>(InstanceManager.getDefault(MemoryManager.class), null); 082 083 _panelMemory.setLayout(new BoxLayout(_panelMemory, BoxLayout.Y_AXIS)); 084 _panelMemory.add(_memoryPanel); 085 086 _tabbedPane.addTab(NamedBeanAddressing.Direct.toString(), _panelDirect); 087 _tabbedPane.addTab(NamedBeanAddressing.Reference.toString(), _panelReference); 088 _tabbedPane.addTab(NamedBeanAddressing.Memory.toString(), _panelMemory); 089 _tabbedPane.addTab(NamedBeanAddressing.LocalVariable.toString(), _panelLocalVariable); 090 _tabbedPane.addTab(NamedBeanAddressing.Formula.toString(), _panelFormula); 091 _tabbedPane.addTab(NamedBeanAddressing.Table.toString(), _panelTable); 092 093 _namedBeanPanel = new BeanSelectPanel<>(_manager, null, NamedBean.DisplayOptions.DISPLAYNAME, true, filter); 094 _panelDirect.add(_namedBeanPanel); 095 096 _referenceTextField = new JTextField(); 097 _referenceTextField.setColumns(30); 098 _panelReference.add(_referenceTextField); 099 100 _localVariableTextField = new JTextField(); 101 _localVariableTextField.setColumns(30); 102 _panelLocalVariable.add(_localVariableTextField); 103 104 _formulaTextField = new JTextField(); 105 _formulaTextField.setColumns(30); 106 _panelFormula.add(_formulaTextField); 107 108 109 if (selectNamedBean != null) { 110 switch (selectNamedBean.getAddressing()) { 111 case Direct: _tabbedPane.setSelectedComponent(_panelDirect); break; 112 case Reference: _tabbedPane.setSelectedComponent(_panelReference); break; 113 case Memory: _tabbedPane.setSelectedComponent(_panelMemory); break; 114 case LocalVariable: _tabbedPane.setSelectedComponent(_panelLocalVariable); break; 115 case Formula: _tabbedPane.setSelectedComponent(_panelFormula); break; 116 case Table: _tabbedPane.setSelectedComponent(_panelTable); break; 117 default: throw new IllegalArgumentException("invalid _addressing state: " + selectNamedBean.getAddressing().name()); 118 } 119 if (selectNamedBean.getNamedBean() != null) { 120 _namedBeanPanel.setDefaultNamedBean(selectNamedBean.getNamedBean().getBean()); 121 } 122 _referenceTextField.setText(selectNamedBean.getReference()); 123 _memoryPanel.setDefaultNamedBean(selectNamedBean.getMemory()); 124 _localVariableTextField.setText(selectNamedBean.getLocalVariable()); 125 _formulaTextField.setText(selectNamedBean.getFormula()); 126 } 127 128 if (!onlyDirectAddressing) { 129 panel.add(_tabbedPane); 130 } else { 131 panel.add(_panelDirect); 132 } 133 return panel; 134 } 135 136 public boolean validate( 137 @Nonnull LogixNG_SelectNamedBean<E> selectNamedBean, 138 @Nonnull List<String> errorMessages) { 139 try { 140 if (_tabbedPane.getSelectedComponent() == _panelReference) { 141 selectNamedBean.setReference(_referenceTextField.getText()); 142 } 143 } catch (IllegalArgumentException e) { 144 errorMessages.add(e.getMessage()); 145 return false; 146 } 147 148 try { 149 selectNamedBean.setFormula(_formulaTextField.getText()); 150 selectNamedBean.setAddressing(getAddressing()); 151 } catch (ParserException e) { 152 errorMessages.add("Cannot parse formula: " + e.getMessage()); 153 return false; 154 } 155 156 _selectTableSwing.validate(selectNamedBean.getSelectTable(), errorMessages); 157 158 return errorMessages.isEmpty(); 159 } 160 161 public void updateObject(@Nonnull LogixNG_SelectNamedBean<E> selectNamedBean) { 162 163 if (onlyDirectAddressing || _tabbedPane.getSelectedComponent() == _panelDirect) { 164 E namedBean = _namedBeanPanel.getNamedBean(); 165 if (namedBean != null) { 166 NamedBeanHandle<E> handle 167 = InstanceManager.getDefault(NamedBeanHandleManager.class) 168 .getNamedBeanHandle(namedBean.getDisplayName(), namedBean); 169 selectNamedBean.setNamedBean(handle); 170 } else { 171 selectNamedBean.removeNamedBean(); 172 } 173 } else { 174 selectNamedBean.removeNamedBean(); 175 } 176 177 try { 178 NamedBeanAddressing addressing = getAddressing(); 179 selectNamedBean.setAddressing(addressing); 180 181 switch (addressing) { 182 case Direct: 183 // Do nothing 184 break; 185 case Reference: 186 selectNamedBean.setReference(_referenceTextField.getText()); 187 break; 188 case Memory: 189 if (_memoryPanel.getNamedBean() != null) { 190 selectNamedBean.setMemory(_memoryPanel.getNamedBean()); 191 } 192 break; 193 case LocalVariable: 194 selectNamedBean.setLocalVariable(_localVariableTextField.getText()); 195 break; 196 case Formula: 197 selectNamedBean.setFormula(_formulaTextField.getText()); 198 break; 199 case Table: 200 // Do nothing 201 break; 202 default: 203 throw new IllegalArgumentException("unknown addressing: "+addressing.name()); 204 } 205 } catch (ParserException e) { 206 throw new RuntimeException("ParserException: "+e.getMessage(), e); 207 } 208 209 _selectTableSwing.updateObject(selectNamedBean.getSelectTable()); 210 } 211 212 public BeanSelectPanel<E> getBeanSelectPanel() { 213 return _namedBeanPanel; 214 } 215 216 public NamedBeanAddressing getAddressing() { 217 if (onlyDirectAddressing) { 218 return NamedBeanAddressing.Direct; 219 } 220 221 if (_tabbedPane.getSelectedComponent() == _panelDirect) { 222 return NamedBeanAddressing.Direct; 223 } else if (_tabbedPane.getSelectedComponent() == _panelReference) { 224 return NamedBeanAddressing.Reference; 225 } else if (_tabbedPane.getSelectedComponent() == _panelMemory) { 226 return NamedBeanAddressing.Memory; 227 } else if (_tabbedPane.getSelectedComponent() == _panelLocalVariable) { 228 return NamedBeanAddressing.LocalVariable; 229 } else if (_tabbedPane.getSelectedComponent() == _panelFormula) { 230 return NamedBeanAddressing.Formula; 231 } else if (_tabbedPane.getSelectedComponent() == _panelTable) { 232 return NamedBeanAddressing.Table; 233 } else { 234 throw new IllegalArgumentException("_tabbedPane has unknown selection"); 235 } 236 } 237 238 public void addAddressingListener(javax.swing.event.ChangeListener l) { 239 _tabbedPane.addChangeListener(l); 240 } 241 242 public void removeAddressingListener(javax.swing.event.ChangeListener l) { 243 _tabbedPane.removeChangeListener(l); 244 } 245 246 public E getBean() { 247 if (getAddressing() == NamedBeanAddressing.Direct) { 248 return _namedBeanPanel.getNamedBean(); 249 } else { 250 throw new IllegalArgumentException("Addressing is not Direct"); 251 } 252 } 253 254 public void dispose() { 255 if (_namedBeanPanel != null) { 256 _namedBeanPanel.dispose(); 257 } 258 _selectTableSwing.dispose(); 259 } 260 261}