001package jmri.jmrix.loconet.logixng.swing; 002 003import java.awt.Color; 004import java.awt.event.ActionEvent; 005import java.text.NumberFormat; 006import java.util.*; 007 008import javax.annotation.CheckForNull; 009import javax.annotation.Nonnull; 010import javax.swing.*; 011import javax.swing.text.NumberFormatter; 012 013import jmri.*; 014import jmri.jmrit.logixng.Base; 015import jmri.jmrit.logixng.DigitalExpressionManager; 016import jmri.jmrit.logixng.MaleSocket; 017import jmri.jmrit.logixng.expressions.swing.AbstractDigitalExpressionSwing; 018import jmri.jmrix.loconet.logixng.ExpressionSlotUsage; 019import jmri.jmrix.loconet.logixng.ExpressionSlotUsage.Has_HasNot; 020import jmri.jmrix.loconet.logixng.ExpressionSlotUsage.AdvancedState; 021import jmri.jmrix.loconet.logixng.ExpressionSlotUsage.SimpleState; 022import jmri.jmrix.loconet.logixng.ExpressionSlotUsage.Compare; 023import jmri.jmrix.loconet.logixng.ExpressionSlotUsage.PercentPieces; 024import jmri.jmrit.logixng.swing.SwingConfiguratorInterface; 025import jmri.jmrix.loconet.LocoNetSystemConnectionMemo; 026 027/** 028 * Configures an ExpressionTurnout object with a Swing JPanel. 029 * 030 * @author Daniel Bergqvist Copyright 2020 031 */ 032public class ExpressionSlotUsageSwing extends AbstractDigitalExpressionSwing { 033 034 private JButton _findNumSlotsButton; 035 private JComboBox<LocoNetConnection> _locoNetConnection; 036 private JTabbedPane _tabbedPane; 037 private JPanel _simplePanel; 038 private JPanel _advancedPanel; 039 private JComboBox<Has_HasNot> _has_HasNot_ComboBox; 040 private JComboBox<SimpleState> _simpleStateComboBox; 041 private JCheckBox _inUseCheckBox; 042 private JCheckBox _idleCheckBox; 043 private JCheckBox _commonCheckBox; 044 private JCheckBox _freeCheckBox; 045 private JComboBox<Compare> _compareComboBox; 046 private JTextField _numberField; 047 private JComboBox<PercentPieces> _percentPiecesComboBox; 048 private JTextField _totalSlotsField; 049 private JPanel _slotsPanel; 050 051 @Override 052 protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) { 053 if ((object != null) && !(object instanceof ExpressionSlotUsage)) { 054 throw new IllegalArgumentException("object must be an ExpressionSlotUsage but is a: "+object.getClass().getName()); 055 } 056 057 ExpressionSlotUsage expression = (ExpressionSlotUsage)object; 058 059 _slotsPanel = new JPanel(); 060 061 panel = new JPanel(); 062 panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); 063 064 JPanel queryPanel = new JPanel(); 065 queryPanel.setBorder(BorderFactory.createLineBorder(Color.black)); 066 067 JPanel locoNetPanel = new JPanel(); 068 locoNetPanel.add(new JLabel(Bundle.getMessage("LocoNetConnection"))); 069 070 _locoNetConnection = new JComboBox<>(); 071 List<LocoNetSystemConnectionMemo> systemConnections = 072 jmri.InstanceManager.getList(LocoNetSystemConnectionMemo.class); 073 for (LocoNetSystemConnectionMemo connection : systemConnections) { 074 LocoNetConnection c = new LocoNetConnection(connection); 075 _locoNetConnection.addItem(c); 076 if ((expression != null) && (expression.getMemo() == connection)) { 077 _locoNetConnection.setSelectedItem(c); 078 } 079 } 080 locoNetPanel.add(_locoNetConnection); 081 082 _has_HasNot_ComboBox = new JComboBox<>(); 083 for (Has_HasNot e : Has_HasNot.values()) { 084 _has_HasNot_ComboBox.addItem(e); 085 } 086 087 _simpleStateComboBox = new JComboBox<>(); 088 for (SimpleState e : SimpleState.values()) { 089 _simpleStateComboBox.addItem(e); 090 } 091 092 _tabbedPane = new JTabbedPane(); 093 _simplePanel = new javax.swing.JPanel(); 094 _advancedPanel = new javax.swing.JPanel(); 095 _advancedPanel.setLayout(new BoxLayout(_advancedPanel, BoxLayout.Y_AXIS)); 096 097 _tabbedPane.addTab(Bundle.getMessage("TabbedPaneSimple"), _simplePanel); // NOI1aa8N 098 _tabbedPane.addTab(Bundle.getMessage("TabbedPaneAdvanced"), _advancedPanel); // NOIaa18N 099 100 _simpleStateComboBox = new JComboBox<>(); 101 for (SimpleState e : SimpleState.values()) { 102 _simpleStateComboBox.addItem(e); 103 } 104 _simplePanel.add(_simpleStateComboBox); 105 106 _inUseCheckBox = new JCheckBox(Bundle.getMessage("AdvancedStateType_InUse")); 107 _idleCheckBox = new JCheckBox(Bundle.getMessage("AdvancedStateType_Idle")); 108 _commonCheckBox = new JCheckBox(Bundle.getMessage("AdvancedStateType_Common")); 109 _freeCheckBox = new JCheckBox(Bundle.getMessage("AdvancedStateType_Free")); 110 _advancedPanel.add(_inUseCheckBox); 111 _advancedPanel.add(_idleCheckBox); 112 _advancedPanel.add(_commonCheckBox); 113 _advancedPanel.add(_freeCheckBox); 114 115 _compareComboBox = new JComboBox<>(); 116 for (Compare e : Compare.values()) { 117 _compareComboBox.addItem(e); 118 } 119 120 NumberFormat format = NumberFormat.getInstance(); 121 NumberFormatter formatter = new NumberFormatter(format); 122 formatter.setValueClass(Integer.class); 123 formatter.setMinimum(0); 124 formatter.setMaximum(120); 125 formatter.setAllowsInvalid(false); 126 // If you want the value to be committed on each keystroke instead of focus lost 127 formatter.setCommitsOnValidEdit(true); 128 _numberField = new JFormattedTextField(); 129 _numberField.setColumns(3); 130 131 _percentPiecesComboBox = new JComboBox<>(); 132 for (PercentPieces e : PercentPieces.values()) { 133 _percentPiecesComboBox.addItem(e); 134 } 135/* 136 _percentPiecesComboBox.addActionListener((ActionEvent e) -> { 137 PercentPieces pp = _percentPiecesComboBox.getItemAt(_percentPiecesComboBox.getSelectedIndex()); 138 if (pp == PercentPieces.Percent) _slotsPanel.setVisible(true); 139 else _slotsPanel.setVisible(false); 140 ExpressionSlotUsageSwing.this.getFrame().pack(); 141 }); 142*/ 143 if (expression != null) { 144 if (expression.getAdvanced()) { 145 _tabbedPane.setSelectedComponent(_advancedPanel); 146 } 147 148 if (expression.getAdvancedStates().contains(AdvancedState.InUse)) { 149 _inUseCheckBox.setSelected(true); 150 } 151 if (expression.getAdvancedStates().contains(AdvancedState.Idle)) { 152 _idleCheckBox.setSelected(true); 153 } 154 if (expression.getAdvancedStates().contains(AdvancedState.Common)) { 155 _commonCheckBox.setSelected(true); 156 } 157 if (expression.getAdvancedStates().contains(AdvancedState.Free)) { 158 _freeCheckBox.setSelected(true); 159 } 160 161 _has_HasNot_ComboBox.setSelectedItem(expression.get_Has_HasNot()); 162 _simpleStateComboBox.setSelectedItem(expression.getSimpleState()); 163 _compareComboBox.setSelectedItem(expression.getCompare()); 164 _numberField.setText(Integer.toString(expression.getNumber())); 165 _percentPiecesComboBox.setSelectedItem(expression.getPercentPieces()); 166 } 167 168 panel.add(locoNetPanel); 169 170 JComponent[] components = new JComponent[]{ 171 _has_HasNot_ComboBox, 172 _tabbedPane, 173 _compareComboBox, 174 _numberField, 175 _percentPiecesComboBox 176 }; 177 178 List<JComponent> componentList = SwingConfiguratorInterface.parseMessage(Bundle.getMessage("ExpressionSlotUsage_Long"), components); 179 180 for (JComponent c : componentList) queryPanel.add(c); 181 182 panel.add(queryPanel); 183 184 _slotsPanel.setLayout(new BoxLayout(_slotsPanel, BoxLayout.Y_AXIS)); 185 _slotsPanel.add(new JLabel(Bundle.getMessage("InfoTotalSlots1"))); 186 _slotsPanel.add(new JLabel(Bundle.getMessage("InfoTotalSlots2"))); 187 _slotsPanel.add(new JLabel(Bundle.getMessage("InfoTotalSlots3"))); 188 189 JPanel numSlotsPanel = new JPanel(); 190 numSlotsPanel.add(new JLabel(Bundle.getMessage("TotalNumSlots"))); 191 format = NumberFormat.getInstance(); 192 formatter = new NumberFormatter(format); 193 formatter.setValueClass(Integer.class); 194 formatter.setMinimum(0); 195 formatter.setMaximum(120); 196 formatter.setAllowsInvalid(false); 197 // If you want the value to be committed on each keystroke instead of focus lost 198 formatter.setCommitsOnValidEdit(true); 199 _totalSlotsField = new JFormattedTextField(); 200 _totalSlotsField.setColumns(3); 201 numSlotsPanel.add(_totalSlotsField); 202 _findNumSlotsButton = new JButton(Bundle.getMessage("GetNumSlots")); 203 _findNumSlotsButton.addActionListener((ActionEvent e) -> { 204 LocoNetSystemConnectionMemo memo = 205 _locoNetConnection.getItemAt(_locoNetConnection.getSelectedIndex())._memo; 206 new GetNumSlotsDialog(memo, _totalSlotsField).initComponents(); 207 }); 208 numSlotsPanel.add(_findNumSlotsButton); 209 if (expression != null) { 210 _totalSlotsField.setText(Integer.toString(expression.getTotalSlots())); 211 } 212 _slotsPanel.add(numSlotsPanel); 213 214 panel.add(_slotsPanel); 215 } 216 217 /** {@inheritDoc} */ 218 @Override 219 public boolean validate(@Nonnull List<String> errorMessages) { 220 try { 221 Integer.parseInt(_numberField.getText()); 222 } catch (NumberFormatException e) { 223 errorMessages.add("Number is not a valid integer"); 224 return false; 225 } 226 return true; 227 } 228 229 /** {@inheritDoc} */ 230 @Override 231 public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) { 232 LocoNetSystemConnectionMemo memo = 233 _locoNetConnection.getItemAt(_locoNetConnection.getSelectedIndex())._memo; 234 235 ExpressionSlotUsage expression = new ExpressionSlotUsage(systemName, userName, memo); 236 updateObject(expression); 237 238 return InstanceManager.getDefault(DigitalExpressionManager.class).registerExpression(expression); 239 } 240 241 /** {@inheritDoc} */ 242 @Override 243 public void updateObject(@Nonnull Base object) { 244 if (! (object instanceof ExpressionSlotUsage)) { 245 throw new IllegalArgumentException("object must be an ExpressionTurnout but is a: "+object.getClass().getName()); 246 } 247 248 ExpressionSlotUsage expression = (ExpressionSlotUsage)object; 249 250 expression.setMemo(_locoNetConnection.getItemAt(_locoNetConnection.getSelectedIndex())._memo); 251 252 expression.setAdvanced(_tabbedPane.getSelectedComponent() == _advancedPanel); 253 254 Set<AdvancedState> advancedStates = new HashSet<>(); 255 if (_inUseCheckBox.isSelected()) advancedStates.add(AdvancedState.InUse); 256 if (_idleCheckBox.isSelected()) advancedStates.add(AdvancedState.Idle); 257 if (_commonCheckBox.isSelected()) advancedStates.add(AdvancedState.Common); 258 if (_freeCheckBox.isSelected()) advancedStates.add(AdvancedState.Free); 259 expression.setAdvancedStates(advancedStates); 260 261 expression.set_Has_HasNot(_has_HasNot_ComboBox.getItemAt(_has_HasNot_ComboBox.getSelectedIndex())); 262 expression.setSimpleState(_simpleStateComboBox.getItemAt(_simpleStateComboBox.getSelectedIndex())); 263 expression.setCompare(_compareComboBox.getItemAt(_compareComboBox.getSelectedIndex())); 264 expression.setNumber(Integer.parseInt(_numberField.getText())); 265 expression.setPercentPieces(_percentPiecesComboBox.getItemAt(_percentPiecesComboBox.getSelectedIndex())); 266 expression.setTotalSlots(Integer.parseInt(_totalSlotsField.getText())); 267 } 268 269 /** {@inheritDoc} */ 270 @Override 271 public String toString() { 272 return Bundle.getMessage("ExpressionSlotUsage_Short"); 273 } 274 275 @Override 276 public void dispose() { 277 } 278 279 280 281 private static class LocoNetConnection { 282 283 private LocoNetSystemConnectionMemo _memo; 284 285 public LocoNetConnection(LocoNetSystemConnectionMemo memo) { 286 _memo = memo; 287 } 288 289 @Override 290 public String toString() { 291 return _memo.getUserName(); 292 } 293 } 294 295 @Override 296 public void setDefaultValues() { 297 _numberField.setText("10"); 298 _totalSlotsField.setText("100"); 299 } 300 301// private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ExpressionSlotUsageSwing.class); 302 303}