001package jmri.jmrix.loconet.soundloader; 002 003import java.awt.Color; 004import java.awt.FlowLayout; 005import java.io.FileNotFoundException; 006import java.io.IOException; 007 008import javax.swing.AbstractAction; 009import javax.swing.BoxLayout; 010import javax.swing.JButton; 011import javax.swing.JFileChooser; 012import javax.swing.JLabel; 013import javax.swing.JPanel; 014import javax.swing.JProgressBar; 015import javax.swing.JSeparator; 016import javax.swing.JTextField; 017 018import jmri.jmrix.loconet.spjfile.SpjFile; 019import jmri.util.FileUtil; 020import jmri.util.swing.JmriJOptionPane; 021 022/** 023 * Pane for downloading .hex files 024 * 025 * @author Bob Jacobsen Copyright (C) 2005 026 */ 027public class LoaderPane extends jmri.jmrix.loconet.swing.LnPanel { 028 029 // GUI member declarations 030 JLabel inputFileName = new JLabel(""); 031 032 JButton readButton; 033 JButton loadButton; 034 035 JTextField comment = new JTextField(32); 036 037 JProgressBar bar; 038 JLabel status = new JLabel(""); 039 String statusText = ""; 040 041 SpjFile file; 042 LoaderEngine engine; 043 044 @Override 045 public String getHelpTarget() { 046 return "package.jmri.jmrix.loconet.soundloader.LoaderFrame"; // NOI18N 047 } 048 049 @Override 050 public String getTitle() { 051 return getTitle(Bundle.getMessage("MenuItemSoundload")); 052 } 053 054 public LoaderPane() { 055 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 056 057 { 058 JPanel p = new JPanel(); 059 p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS)); 060 JButton b = new JButton(Bundle.getMessage("ButtonSelect")); // is in jmri.NBBundle 061 b.addActionListener(new AbstractAction() { 062 @Override 063 public void actionPerformed(java.awt.event.ActionEvent e) { 064 selectInputFile(); 065 } 066 }); 067 p.add(b); 068 p.add(new JLabel(Bundle.getMessage("LabelInpFile"))); 069 p.add(inputFileName); 070 071 add(p); 072 } 073 074 add(new JSeparator()); 075 076 { 077 JPanel p = new JPanel(); 078 p.setLayout(new FlowLayout()); 079 080 readButton = new JButton(Bundle.getMessage("ButtonRead")); 081 readButton.setEnabled(false); 082 readButton.setToolTipText(Bundle.getMessage("TipReadDisabled")); 083 p.add(readButton); 084 readButton.addActionListener(new AbstractAction() { 085 @Override 086 public void actionPerformed(java.awt.event.ActionEvent e) { 087 doRead(); 088 } 089 }); 090 091 add(p); 092 } 093 094 { 095 JPanel p = new JPanel(); 096 p.setLayout(new FlowLayout()); 097 098 p.add(new JLabel(Bundle.getMessage("LabelFileComment"))); 099 comment.setEditable(false); 100 p.add(comment); 101 add(p); 102 } 103 104 add(new JSeparator()); 105 106 { 107 JPanel p = new JPanel(); 108 p.setLayout(new FlowLayout()); 109 110 loadButton = new JButton(Bundle.getMessage("ButtonDownload")); 111 loadButton.setEnabled(false); 112 loadButton.setToolTipText(Bundle.getMessage("TipLoadDisabled")); 113 p.add(loadButton); 114 loadButton.addActionListener(new AbstractAction() { 115 @Override 116 public void actionPerformed(java.awt.event.ActionEvent e) { 117 doLoad(); 118 } 119 }); 120 121 add(p); 122 123 add(new JSeparator()); 124 125 bar = new JProgressBar(); 126 add(bar); 127 128 add(new JSeparator()); 129 130 { 131 p = new JPanel(); 132 p.setLayout(new FlowLayout()); 133 status.setText(Bundle.getMessage("StatusSelectFile")); 134 // layout 135 status.setAlignmentX(JLabel.LEFT_ALIGNMENT); 136 status.setFont(status.getFont().deriveFont(0.9f * inputFileName.getFont().getSize())); // a bit smaller 137 status.setForeground(Color.gray); 138 p.add(status); 139 add(p); 140 } 141 } 142 } 143 144 JFileChooser chooser; 145 146 void selectInputFile() { 147 String name = inputFileName.getText(); 148 if (name.equals("")) { 149 name = FileUtil.getUserFilesPath(); 150 } 151 if (chooser == null) { 152 chooser = new jmri.util.swing.JmriJFileChooser(name); 153 } 154 inputFileName.setText(""); // clear out in case of failure 155 int retVal = chooser.showOpenDialog(this); 156 if (retVal != JFileChooser.APPROVE_OPTION) { 157 return; // give up if no file selected 158 } 159 inputFileName.setText(chooser.getSelectedFile().getName()); 160 161 readButton.setEnabled(true); 162 readButton.setToolTipText(Bundle.getMessage("TipReadEnabled")); 163 loadButton.setEnabled(false); 164 loadButton.setToolTipText(Bundle.getMessage("TipLoadDisabled")); 165 status.setText(Bundle.getMessage("StatusReadFile")); 166 } 167 168 void doRead() { 169 if (inputFileName.getText().equals("")) { 170 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("ErrorNoInputFile"), 171 Bundle.getMessage("ErrorTitle"), 172 JmriJOptionPane.ERROR_MESSAGE); 173 return; 174 } 175 176 // force load, verify disabled in case read fails 177 loadButton.setEnabled(false); 178 loadButton.setToolTipText(Bundle.getMessage("TipLoadDisabled")); 179 180 try { 181 file = new SpjFile(chooser.getSelectedFile()); 182 file.read(); 183 } catch (FileNotFoundException f) { 184 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("ErrorFileNotFound"), 185 Bundle.getMessage("ErrorTitle"), 186 JmriJOptionPane.ERROR_MESSAGE); 187 return; 188 } catch (IOException f) { 189 JmriJOptionPane.showMessageDialog(this, Bundle.getMessage("ErrorIOError"), 190 Bundle.getMessage("ErrorTitle"), 191 JmriJOptionPane.ERROR_MESSAGE); 192 return; 193 } 194 195 // display contents 196 comment.setText(file.getComment()); 197 198 // set up for next step 199 loadButton.setEnabled(true); 200 loadButton.setToolTipText(Bundle.getMessage("TipLoadEnabled")); 201 status.setText(Bundle.getMessage("StatusDoDownload")); 202 203 } 204 205 void doLoad() { 206 status.setText(Bundle.getMessage("StatusDownloading")); 207 readButton.setEnabled(false); 208 readButton.setToolTipText(Bundle.getMessage("TipDisabledDownload")); 209 loadButton.setEnabled(false); 210 loadButton.setToolTipText(Bundle.getMessage("TipDisabledDownload")); 211 212 // Create a loader to run in a separate thread 213 // Override notify() method to do a swing-thread update of status field 214 if (engine == null) { 215 engine = new LoaderEngine(memo) { 216 @Override 217 public void notify(String s) { 218 javax.swing.SwingUtilities.invokeLater(new Notifier(s)); 219 } 220 }; 221 } 222 223 // start the download itself 224 new Thread() { 225 @Override 226 public void run() { 227 engine.runDownload(file); 228 } 229 }.start(); 230 231 } 232 233 /** 234 * Define objects to update status JLabel in pane 235 */ 236 private class Notifier implements Runnable { 237 238 public Notifier(String msg) { 239 this.msg = msg; 240 } 241 String msg; 242 243 @Override 244 public void run() { 245 status.setText(msg); 246 } 247 } 248 249 /** 250 * Get rid of any held resources 251 */ 252 @Override 253 public void dispose() { 254 if (file != null) { 255 file.dispose(); 256 } 257 file = null; // not for GC, this flags need to reinit 258 259 if (engine != null) { 260 engine.dispose(); 261 } 262 engine = null; // not for GC, this flags need to reinit 263 } 264 265}