001package jmri.jmrix.bidib.serialdriver; 002 003import java.awt.AWTEvent; 004import java.awt.Color; 005import java.awt.event.ActionEvent; 006import java.awt.event.ActionListener; 007import java.awt.event.FocusEvent; 008import java.awt.event.FocusListener; 009import java.awt.event.ItemEvent; 010import java.util.List; 011import java.util.Vector; 012import javax.swing.JCheckBox; 013import javax.swing.JComboBox; 014import javax.swing.JLabel; 015import javax.swing.JTextField; 016import org.bidib.jbidibc.messages.utils.ByteUtils; 017//import org.bidib.jbidibc.scm.ScmPortIdentifierUtils; 018import org.slf4j.Logger; 019import org.slf4j.LoggerFactory; 020 021/** 022 * Definition of objects to handle configuring a layout connection via a BiDiB 023 * SerialDriverAdapter object. 024 * 025 * @author Bob Jacobsen Copyright (C) 2001, 2003 026 * @author Eckart Meyer Copyright (C) 2019 027 */ 028public class ConnectionConfig extends jmri.jmrix.AbstractSerialConnectionConfig { 029 030 public final static String NAME = Bundle.getMessage("TypeSerial"); 031// protected JCheckBox useAutoScan = new JCheckBox(Bundle.getMessage("Use Autoscan")); 032 // TODO: use Bundle for localization of the field text 033 protected JCheckBox useAutoScan = new JCheckBox("Use Autoscan"); 034 protected JLabel rootNodeLabel = new JLabel("Root Node (hex):"); 035 protected JTextField rootNodeField = new JTextField(16); 036 protected JLabel portNameFilterLabel = new JLabel("Port Name Filter:"); 037 protected JTextField portNameFilterField = new JTextField(15); 038 039 /** 040 * Ctor for an object being created during load process; Swing init is 041 * deferred. 042 * 043 * @param p SerialPortAdapter for existing adapter 044 */ 045 public ConnectionConfig(jmri.jmrix.SerialPortAdapter p) { 046 super(p); 047 } 048 049 /** 050 * Ctor for a functional Swing object with no existing adapter 051 */ 052 public ConnectionConfig() { 053 super(); 054 } 055 056 @Override 057 public String name() { 058 return NAME; 059 } 060 061 /** 062 * {@inheritDoc} 063 */ 064 @Override 065 protected void setInstance() { 066 log.debug("BiDiB Simulator ConnectionConfig.setInstance: {}", adapter); 067 if (adapter == null) { 068 adapter = new SerialDriverAdapter(); 069 log.debug("-- adapter created: {}", adapter); 070 } 071 } 072 073 /** 074 * {@inheritDoc} 075 */ 076 @Override 077// @SuppressWarnings("UseOfObsoleteCollectionType") 078 public Vector<String> getPortNames() { 079 // used for SCM - will prepend "/dev" fpr Linux 080 Vector<String> portNameVector = new Vector<>(); 081 try { 082 List<String> portNameList = ((SerialDriverAdapter)adapter).getPortIdentifiers(); 083 for (String portName : portNameList) { 084 portNameVector.addElement(portName); 085 } 086 } 087 catch (Exception ex) { 088 log.error("Serial adapter not set: ", ex); // NOSONAR 089 } 090// List<String> portNameList = SerialDriverAdapter.getPortIdentifiers(); 091 log.trace("getPortNames done {}", portNameVector); 092 return portNameVector; 093 } 094 095 /** 096 * {@inheritDoc} 097 */ 098 @Override 099 protected void checkInitDone() { 100 super.checkInitDone(); 101 log.debug("checkInitDone"); 102 if (adapter.getSystemConnectionMemo() != null) { 103 SerialDriverAdapter a = (SerialDriverAdapter)adapter; 104 rootNodeField.setText(ByteUtils.formatHexUniqueId(a.getRootNodeUid())); 105 portNameFilterField.setText(a.getPortNameFilter()); 106 useAutoScan.setSelected(a.getUseAutoScan()); 107 if (a.getUseAutoScan()) { 108 rootNodeField.setEnabled(true); 109 portBox.setEnabled(false); 110 } 111 else { 112 rootNodeField.setEnabled(false); 113 portBox.setEnabled(true); 114 } 115 // add listeners 116 // portBox combobox 117 portBox.addActionListener(new ActionListener() { 118 @Override 119 public void actionPerformed(ActionEvent e) { 120 log.debug("portBox action!"); 121 portBoxChanged(e); 122 } 123 }); 124 // rootNode field 125 rootNodeField.addActionListener(new ActionListener() { 126 @Override 127 public void actionPerformed(ActionEvent e) { 128 log.debug("rootNodeUID action!"); 129 rootNodeUidChanged(e); 130 } 131 }); 132 rootNodeField.addFocusListener(new FocusListener() { 133 @Override 134 public void focusLost(FocusEvent e) { 135 log.debug("rootNodeUID focus lost!"); 136 rootNodeUidChanged(e); 137 } 138 @Override 139 public void focusGained(FocusEvent e) { 140 } 141 }); 142 // portNameFilter field 143 portNameFilterField.addActionListener(new ActionListener() { 144 @Override 145 public void actionPerformed(ActionEvent e) { 146 log.debug("portNameFilter action!"); 147 portNameFilterChanged(e); 148 } 149 }); 150 portNameFilterField.addFocusListener(new FocusListener() { 151 @Override 152 public void focusLost(FocusEvent e) { 153 log.debug("portNameFilter focus lost!"); 154 portNameFilterChanged(e); 155 } 156 @Override 157 public void focusGained(FocusEvent e) { 158 } 159 }); 160 // useAutoScan checkbox 161 useAutoScan.addItemListener((ItemEvent e) -> { 162 log.debug("useAutoScan changed!"); 163 a.setUseAutoScan(useAutoScan.isSelected()); 164 rootNodeField.setEnabled(useAutoScan.isSelected()); 165 portBox.setEnabled(!useAutoScan.isSelected()); 166 }); 167 168 baudBox.setEnabled(false);// Bidib SCM always tries to find the the baudrate itself, the user cannot select 169 } 170 } 171 172 @SuppressWarnings (value="unchecked") //because of the unchecked cast of the event object. but we can be sure here... 173 private void portBoxChanged(AWTEvent e) { 174 SerialDriverAdapter a = (SerialDriverAdapter)adapter; 175 String fieldtext = ((JComboBox<String>)e.getSource()).getSelectedItem().toString(); 176 log.debug("portBox selected: {}", fieldtext); 177 if (!a.getUseAutoScan()) { 178 //Long uid = SerialDriverAdapter.checkPort(fieldtext); //call static function 179 Long uid = a.checkPort(fieldtext); //call static function 180 if (uid == null) { 181 a.setRootNodeUid(null); 182 rootNodeField.setText(""); 183 } 184 else { 185 a.setRootNodeUid(uid); 186 //rootNodeField.setText(String.format("0x%X", a.getRootNodeUid() & 0xffffffffffffffL)); 187 rootNodeField.setText(ByteUtils.formatHexUniqueId(a.getRootNodeUid())); 188 } 189 } 190 } 191 192 private void rootNodeUidChanged(AWTEvent e) { 193 SerialDriverAdapter a = (SerialDriverAdapter)adapter; 194 String fieldtext = ((JTextField)e.getSource()).getText(); 195 if (fieldtext.isEmpty()) { 196 //a.setRootNodeUid(null); //don't set 197 } 198 else { 199 try { 200 if (a.getUseAutoScan()) { 201 Long uid = ByteUtils.parseHexUniqueId(fieldtext); 202 String err = a.findPortbyUniqueID(uid); 203 if (err == null) { 204 log.info("found port name for UID {} is {}", 205 ByteUtils.formatHexUniqueId(a.getRootNodeUid()), a.getCurrentPortName()); 206 a.setRootNodeUid(uid); 207 //rootNodeField.setText(String.format("0x%X", a.getRootNodeUid() & 0x0000ffffffffffL)); 208 rootNodeField.setText(ByteUtils.formatHexUniqueId(a.getRootNodeUid())); 209 // TODO set portBox 210 rootNodeField.setForeground(Color.black); 211 portBox.setSelectedItem(a.getCurrentPortName()); 212 } 213 else { 214 log.warn(err); 215 rootNodeField.setForeground(Color.red); 216 } 217 } 218 } 219 catch (NumberFormatException ex) { 220 a.setRootNodeUid(null); 221 rootNodeField.setText(""); 222 log.warn("Exception:", ex); 223 } 224 } 225 } 226 227 private void portNameFilterChanged(AWTEvent e) { 228 SerialDriverAdapter a = (SerialDriverAdapter)adapter; 229 // String s = a.getCurrentPortName(); 230 String fieldtext = ((JTextField)e.getSource()).getText(); 231 a.setPortNameFilter(fieldtext); 232 refreshPortBox(); 233 } 234 235 /** 236 * {@inheritDoc} 237 */ 238 @Override 239 protected void showAdvancedItems() { 240 super.showAdvancedItems(); // we're adding to the normal advanced items. 241 log.debug("showAdvancedItems"); 242 if (adapter.getSystemConnectionMemo() != null) { 243 cR.gridy += 2; 244 cL.gridy += 2; 245 gbLayout.setConstraints(rootNodeLabel, cL); 246 gbLayout.setConstraints(rootNodeField, cR); 247 _details.add(rootNodeLabel); 248 //rootNodeField.setEnabled(false); 249 _details.add(rootNodeField); 250 251 cR.gridy += 2; 252 cL.gridy += 2; 253 gbLayout.setConstraints(useAutoScan, cL); 254 useAutoScan.setFont(useAutoScan.getFont().deriveFont(9f)); 255 useAutoScan.setForeground(Color.blue); 256 _details.add(useAutoScan); 257 258 cR.gridy += 2; 259 cL.gridy += 2; 260 gbLayout.setConstraints(portNameFilterLabel, cL); 261 gbLayout.setConstraints(portNameFilterField, cR); 262 _details.add(portNameFilterLabel); 263 _details.add(portNameFilterField); 264 } 265 if (_details.getParent() != null) { 266 _details.getParent().revalidate(); 267 _details.getParent().repaint(); 268 } 269 } 270 271 @Override 272 public void updateAdapter() { 273 super.updateAdapter(); // we're adding more details to the connection. 274 log.debug("updateAdapter"); 275 SerialDriverAdapter a = (SerialDriverAdapter)adapter; 276 if (adapter.getSystemConnectionMemo() != null) { 277 a.setUseAutoScan(useAutoScan.isSelected()); 278 a.setRootNodeUid(ByteUtils.parseHexUniqueId(rootNodeField.getText())); 279 a.setPortNameFilter(portNameFilterField.getText()); 280 } 281 } 282 283 284 private final static Logger log = LoggerFactory.getLogger(ConnectionConfig.class); 285}