001package jmri.jmrix.nce.macro; 002 003import java.awt.Dimension; 004import java.awt.GridBagConstraints; 005import java.awt.GridBagLayout; 006 007import javax.swing.JComponent; 008import javax.swing.JLabel; 009 010import jmri.jmrix.nce.*; 011import jmri.util.swing.JmriJOptionPane; 012 013/** 014 * Pane for user input of NCE macros. 015 * 016 * @author Bob Jacobsen Copyright (C) 2001 017 * @author Dan Boudreau Copyright (C) 2007 Cloned into a Panel by 018 * @author kcameron 019 */ 020public class NceMacroGenPanel extends jmri.jmrix.nce.swing.NcePanel implements jmri.jmrix.nce.NceListener { 021 022 // member declarations 023 javax.swing.JLabel jLabel1 = new javax.swing.JLabel(Bundle.getMessage("MacroLabel")); 024 javax.swing.JLabel macroText = new javax.swing.JLabel(Bundle.getMessage("ReplyLabel")); 025 javax.swing.JLabel macroReply = new javax.swing.JLabel(); 026 javax.swing.JButton sendButton = new javax.swing.JButton(Bundle.getMessage("Send")); 027 javax.swing.JTextField packetTextField = new javax.swing.JTextField(4); 028 029 // for padding out panel 030 JLabel space1 = new JLabel(" "); 031 JLabel space3 = new JLabel(" "); 032 033 private NceTrafficController tc = null; 034 035 public NceMacroGenPanel() { 036 super(); 037 } 038 039 /** 040 * {@inheritDoc} 041 */ 042 @Override 043 public void initContext(Object context) { 044 if (context instanceof NceSystemConnectionMemo) { 045 initComponents((NceSystemConnectionMemo) context); 046 } 047 } 048 049 /** 050 * {@inheritDoc} 051 */ 052 @Override 053 public String getHelpTarget() { 054 return "package.jmri.jmrix.nce.macro.NceMacroEditFrame"; 055 } 056 057 /** 058 * {@inheritDoc} 059 */ 060 @Override 061 public String getTitle() { 062 StringBuilder x = new StringBuilder(); 063 if (memo != null) { 064 x.append(memo.getUserName()); 065 } else { 066 x.append("NCE_"); 067 } 068 x.append(": "); 069 x.append(Bundle.getMessage("TitleNceMacroGen")); 070 return x.toString(); 071 } 072 073 /** 074 * {@inheritDoc} 075 */ 076 @Override 077 public void initComponents(NceSystemConnectionMemo memo) { 078 this.memo = memo; 079 tc = memo.getNceTrafficController(); 080 // the following code sets the frame's initial state 081 082 // set initial state 083 macroReply.setText(Bundle.getMessage("unknown")); 084 085 // load tool tips 086 sendButton.setToolTipText(Bundle.getMessage("toolTipExecuteMacro")); 087 packetTextField.setToolTipText(Bundle.getMessage("toolTipEnterMacroSerial")); 088 089 packetTextField.setMaximumSize(new Dimension(packetTextField 090 .getMaximumSize().width, packetTextField.getPreferredSize().height)); 091 092 setLayout(new GridBagLayout()); 093 setPreferredSize(new Dimension(300, 100)); 094 095 addItem(jLabel1, 0, 0); 096 addItem(packetTextField, 2, 0); 097 addItem(macroText, 0, 1); 098 addItem(macroReply, 2, 1); 099 //addItem(space1, 0, 2); 100 //addItem(space2, 1, 2); 101 addItem(space3, 2, 2); 102 addItem(sendButton, 0, 3); 103 104 sendButton.addActionListener(new java.awt.event.ActionListener() { 105 @Override 106 public void actionPerformed(java.awt.event.ActionEvent e) { 107 sendButtonActionPerformed(e); 108 } 109 }); 110 } 111 112 public void sendButtonActionPerformed(java.awt.event.ActionEvent e) { 113 String input = packetTextField.getText(); 114 // TODO check input + feedback on error. Too easy to cause NPE 115 // Send Macro 116 NceMessage m = createMacroCmd(input); 117 if (m == null) { 118 macroReply.setText(Bundle.getMessage("error")); 119 JmriJOptionPane.showMessageDialog(this, 120 Bundle.getMessage("EnterMacroNumber"), 121 Bundle.getMessage("NceMacro"), 122 JmriJOptionPane.ERROR_MESSAGE); 123 return; 124 } 125 macroReply.setText(Bundle.getMessage("waiting")); 126 tc.sendNceMessage(m, this); 127 128 // Unfortunately, the new command doesn't tell us if the macro is empty 129 // so we send old command for status 130 NceMessage m2 = createOldMacroCmd(input); 131 tc.sendNceMessage(m2, this); 132 } 133 134 @Override 135 public void message(NceMessage m) { 136 } // ignore replies 137 138 @Override 139 public void reply(NceReply r) { 140 if (r.getNumDataElements() == NceMessage.REPLY_1) { 141 142 int recChar = r.getElement(0); 143 if (recChar == NceMessage.NCE_OKAY) { 144 macroReply.setText(Bundle.getMessage("okay")); 145 } 146 if (recChar == '0') { 147 macroReply.setText(Bundle.getMessage("macroEmpty")); 148 } 149 150 } else { 151 macroReply.setText(Bundle.getMessage("error")); 152 } 153 } 154 155 NceMessage createMacroCmd(String s) { 156 157 int macroNum = 0; 158 try { 159 macroNum = Integer.parseInt(s); 160 } catch (NumberFormatException e) { 161 return null; 162 } 163 164 if (macroNum < 0 || macroNum > 255) { 165 return null; 166 } 167 168 if (tc.getCommandOptions() >= NceTrafficController.OPTION_2006) { 169 170 // NCE always responds with okay (!) if macro number is in range. 171 // We need to send this version of macro command to cause turnout 172 // state to change in NCE CS 173 NceMessage m = new NceMessage(5); 174 m.setElement(0, NceMessage.SEND_ACC_SIG_MACRO_CMD); // Macro cmd 175 m.setElement(1, 0x00); // addr_h 176 m.setElement(2, 0x01); // addr_l 177 m.setElement(3, 0x01); // Macro cmd 178 m.setElement(4, macroNum); // Macro # 179 m.setBinary(true); 180 m.setReplyLen(NceMessage.REPLY_1); 181 return m; 182 183 } else { 184 185 // NCE responds with okay (!) if macro exist, (0) if not 186 NceMessage m = new NceMessage(2); 187 m.setElement(0, NceMessage.MACRO_CMD); // Macro cmd 188 m.setElement(1, macroNum); // Macro # 189 m.setBinary(true); 190 m.setReplyLen(NceMessage.REPLY_1); 191 return m; 192 } 193 } 194 195 NceMessage createOldMacroCmd(String s) { 196 197 int macroNum = 0; 198 try { 199 macroNum = Integer.parseInt(s); 200 } catch (NumberFormatException e) { 201 return null; 202 } 203 204 if (macroNum < 0 || macroNum > 255) { 205 return null; 206 } 207 208 // NCE responds with okay (!) if macro exist, ('0') if not 209 NceMessage m = new NceMessage(2); 210 m.setElement(0, NceMessage.MACRO_CMD); // Macro cmd 211 m.setElement(1, macroNum); // Macro # 212 m.setBinary(true); 213 m.setReplyLen(NceMessage.REPLY_1); 214 return m; 215 } 216 217 private void addItem(JComponent c, int x, int y) { 218 GridBagConstraints gc = new GridBagConstraints(); 219 gc.gridx = x; 220 gc.gridy = y; 221 gc.weightx = 100.0; 222 gc.weighty = 100.0; 223 add(c, gc); 224 } 225 226 /** 227 * Nested class to create one of these using old-style defaults. 228 */ 229 static public class Default extends jmri.jmrix.nce.swing.NceNamedPaneAction { 230 231 public Default() { 232 super("Open NCE Send Macro Window", 233 new jmri.util.swing.sdi.JmriJFrameInterface(), 234 NceMacroGenPanel.class.getName(), 235 jmri.InstanceManager.getDefault(NceSystemConnectionMemo.class)); 236 } 237 } 238 239}