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