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