001package jmri.jmrix.can.cbus.swing.modules.base; 002 003import java.awt.*; 004 005import javax.swing.*; 006import javax.swing.event.*; 007 008import jmri.jmrix.can.cbus.node.CbusNode; 009import jmri.jmrix.can.cbus.node.CbusNodeNVTableDataModel; 010import jmri.jmrix.can.cbus.swing.modules.*; 011import static jmri.jmrix.can.cbus.swing.modules.merg.CansolPaneProvider.*; 012 013/** 014 * Node Variable edit frame for a basic 8-channel solenoid module 015 * 016 * @author Andrew Crosland Copyright (C) 2021 017 */ 018public class Sol8BaseEditNVPane extends AbstractEditNVPane { 019 020 // Number of outputs 021 public static final int OUTPUTS = 8; 022 023 // Conversion between NV and display values 024 public static final int TIME_STEP_SIZE = 10; 025 026 private final UpdateNV pulseUpdateFn = new UpdatePulse(); 027 private final UpdateNV rechargeUpdateFn = new UpdateRecharge(); 028 private final UpdateNV fireDelayUpdateFn = new UpdateFireDelay(); 029 private final UpdateNV enableDelayUpdateFn = new UpdateEnableDelay(); 030 031 private TitledSpinner pulse[] = new TitledSpinner[OUTPUTS + 1]; 032 private TitledSpinner rechargeSpinner; 033 private TitledSpinner fireDelaySpinner; 034 private TitledSpinner enableDelaySpinner; 035 036 protected Sol8BaseEditNVPane(CbusNodeNVTableDataModel dataModel, CbusNode node) { 037 super(dataModel, node); 038 initSpinners(); 039 } 040 041 private void initSpinners() { 042 043 rechargeSpinner = new TitledSpinner(Bundle.getMessage("RechargeTimeUnits"), RECHARGE_TIME, rechargeUpdateFn); 044 rechargeSpinner.setToolTip(Bundle.getMessage("RechargeTimeTt")); 045 046 fireDelaySpinner = new TitledSpinner(Bundle.getMessage("FireDelayUnits"), FIRE_DELAY, fireDelayUpdateFn); 047 fireDelaySpinner.setToolTip(Bundle.getMessage("FireDelayTt")); 048 049 enableDelaySpinner = new TitledSpinner(Bundle.getMessage("EnableDelayUnits"), ENABLE_DELAY, enableDelayUpdateFn); 050 enableDelaySpinner.setToolTip(Bundle.getMessage("EnableDelayTt")); 051 } 052 053 /** {@inheritDoc} */ 054 @Override 055 public AbstractEditNVPane getContent() { 056 057 JPanel gridPane = new JPanel(new GridBagLayout()); 058 GridBagConstraints c = new GridBagConstraints(); 059 c.fill = GridBagConstraints.HORIZONTAL; 060 c.weightx = 1; 061 c.weighty = 1; 062 c.gridy = 0; 063 064 // Four columns for the outputs 065 for (int y = 0; y < OUTPUTS/4; y++) { 066 c.gridx = 0; 067 for (int x = 0; x < 4; x++) { 068 int index = y*4 + x + 1; // NVs indexed from 1 069 pulse[index] = new TitledSpinner((Bundle.getMessage("OutputX", index)) + " " + Bundle.getMessage("PulseWidthUnits"), index, pulseUpdateFn); 070 pulse[index].setToolTip(Bundle.getMessage("CanSolOutputTt")); 071 pulse[index].init(getSelectValue8(index)*TIME_STEP_SIZE, 0, TIME_STEP_SIZE*255, TIME_STEP_SIZE); 072 gridPane.add(pulse[index], c); 073 c.gridx++; 074 } 075 c.gridy++; 076 } 077 078 c.gridx = 0; 079 080 rechargeSpinner.init(getSelectValue8(RECHARGE_TIME)*TIME_STEP_SIZE, 0, TIME_STEP_SIZE*255, TIME_STEP_SIZE); 081 082 gridPane.add(rechargeSpinner, c); 083 c.gridx++; 084 085 fireDelaySpinner.init(getSelectValue8(FIRE_DELAY)*TIME_STEP_SIZE, 0, TIME_STEP_SIZE*255, TIME_STEP_SIZE); 086 087 gridPane.add(fireDelaySpinner, c); 088 c.gridx++; 089 090 enableDelaySpinner.init(getSelectValue8(ENABLE_DELAY)*TIME_STEP_SIZE, 0, TIME_STEP_SIZE*255, TIME_STEP_SIZE); 091 092 gridPane.add(enableDelaySpinner, c); 093 094 JScrollPane scroll = new JScrollPane(gridPane); 095 add(scroll); 096 097 return this; 098 } 099 100 /** {@inheritDoc} */ 101 @Override 102 public void tableChanged(TableModelEvent e) { 103 if (e.getType() == TableModelEvent.UPDATE) { 104 int row = e.getFirstRow(); 105 int nv = row + 1; 106 int value = getSelectValue8(nv); 107 if ((nv > 0) && (nv <= 8)) { 108 //log.debug("Update NV {} to {}", nv, value); 109 pulse[nv].setValue(value*TIME_STEP_SIZE); 110 } else if (nv == 9) { 111 //log.debug("Update recharge delay to {}", value); 112 rechargeSpinner.setValue(value*TIME_STEP_SIZE); 113 } else if (nv == 10) { 114 //log.debug("Update fire delay to {}", value); 115 fireDelaySpinner.setValue(value*TIME_STEP_SIZE); 116 } else if (nv == 11) { 117 //log.debug("Update enable delay to {}", value); 118 enableDelaySpinner.setValue(value*TIME_STEP_SIZE); 119 } else { 120 // Not used, or row was -1 121// log.debug("Update unknown NV {}", nv); 122 } 123 } 124 } 125 126 /** 127 * Update the NV controlling the output pulse width 128 */ 129 protected class UpdatePulse implements UpdateNV { 130 131 /** {@inheritDoc} */ 132 @Override 133 public void setNewVal(int index) { 134 int delay = pulse[index].getIntegerValue()/TIME_STEP_SIZE; 135 // Note that changing the data model will result in tableChanged() being called, which can manipulate the buttons, etc 136 _dataModel.setValueAt(delay, index - 1, CbusNodeNVTableDataModel.NV_SELECT_COLUMN); 137 } 138 } 139 140 /** 141 * Update the NV controlling the recharge delay 142 */ 143 protected class UpdateRecharge implements UpdateNV { 144 145 /** {@inheritDoc} */ 146 @Override 147 public void setNewVal(int index) { 148 int delay = rechargeSpinner.getIntegerValue()/TIME_STEP_SIZE; 149 // Note that changing the data model will result in tableChanged() being called, which can manipulate the buttons, etc 150 _dataModel.setValueAt(delay, index - 1, CbusNodeNVTableDataModel.NV_SELECT_COLUMN); 151 } 152 } 153 154 /** 155 * Update the NV controlling the recharge delay 156 */ 157 protected class UpdateFireDelay implements UpdateNV { 158 159 /** {@inheritDoc} */ 160 @Override 161 public void setNewVal(int index) { 162 int delay = fireDelaySpinner.getIntegerValue()/TIME_STEP_SIZE; 163 // Note that changing the data model will result in tableChanged() being called, which can manipulate the buttons, etc 164 _dataModel.setValueAt(delay, index - 1, CbusNodeNVTableDataModel.NV_SELECT_COLUMN); 165 } 166 } 167 168 /** 169 * Update the NV controlling the enable delay 170 */ 171 protected class UpdateEnableDelay implements UpdateNV { 172 173 /** {@inheritDoc} */ 174 @Override 175 public void setNewVal(int index) { 176 int delay = enableDelaySpinner.getIntegerValue()/TIME_STEP_SIZE; 177 // Note that changing the data model will result in tableChanged() being called, which can manipulate the buttons, etc 178 _dataModel.setValueAt(delay, index - 1, CbusNodeNVTableDataModel.NV_SELECT_COLUMN); 179 } 180 } 181 182// private final static Logger log = LoggerFactory.getLogger(Sol8BaseEditNVPane.class); 183 184}