Source code: com/barteo/emulator/app/ui/awt/AwtSelectDevicePanel.java
1 /*
2 * MicroEmulator
3 * Copyright (C) 2002-2003 Bartek Teodorczyk <barteo@it.pl>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 package com.barteo.emulator.app.ui.awt;
21
22 import java.awt.BorderLayout;
23 import java.awt.Button;
24 import java.awt.FileDialog;
25 import java.awt.Frame;
26 import java.awt.List;
27 import java.awt.Panel;
28 import java.awt.ScrollPane;
29 import java.awt.event.ActionEvent;
30 import java.awt.event.ActionListener;
31 import java.awt.event.ItemEvent;
32 import java.awt.event.ItemListener;
33 import java.io.File;
34 import java.io.FileInputStream;
35 import java.io.FileOutputStream;
36 import java.io.IOException;
37 import java.util.Enumeration;
38 import java.util.Vector;
39 import java.util.jar.Attributes;
40 import java.util.jar.JarFile;
41 import java.util.jar.Manifest;
42
43 import com.barteo.emulator.app.Config;
44 import com.barteo.emulator.app.util.DeviceEntry;
45 import com.barteo.emulator.app.util.ExtensionFileFilter;
46 import com.barteo.emulator.app.util.ProgressJarClassLoader;
47 import com.barteo.emulator.device.applet.AppletDevice;
48
49
50 public class AwtSelectDevicePanel extends AwtDialogPanel
51 {
52 private AwtSelectDevicePanel instance;
53
54 private ScrollPane spDevices;
55 private Button btAdd;
56 private Button btRemove;
57 private Button btDefault;
58 private List lsDevices;
59 private Vector deviceModel;
60
61 private ActionListener btAddListener = new ActionListener()
62 {
63 private FileChooser fileChooser = null;
64
65 public void actionPerformed(ActionEvent ev)
66 {
67 if (fileChooser == null) {
68 ExtensionFileFilter fileFilter = new ExtensionFileFilter("Device profile (*.dev)");
69 fileFilter.addExtension("dev");
70 fileChooser = new FileChooser(new Frame(), "Open device profile file...", FileDialog.LOAD);
71 fileChooser.setFilenameFilter(fileFilter);
72 }
73
74 ProgressJarClassLoader loader = new ProgressJarClassLoader();
75
76 fileChooser.show();
77
78 if (fileChooser.getFile() != null) {
79 String deviceClassName = null;
80 String deviceName = null;
81 try {
82 JarFile jar = new JarFile(fileChooser.getSelectedFile());
83 Manifest manifest = jar.getManifest();
84 if (manifest == null) {
85 OptionPane.showMessageDialog(instance,
86 "Missing manifest in dev file.",
87 "Error", OptionPane.ERROR_MESSAGE);
88 return;
89 }
90 Attributes attrs = manifest.getMainAttributes();
91
92 deviceName = attrs.getValue("Device-Name");
93 if (deviceName == null) {
94 OptionPane.showMessageDialog(instance,
95 "Missing Device-Name entry in jar manifest.",
96 "Error", OptionPane.ERROR_MESSAGE);
97 return;
98 }
99
100 deviceClassName = attrs.getValue("Device-Class");
101 if (deviceClassName == null) {
102 OptionPane.showMessageDialog(instance,
103 "Missing Device-Class entry in jar manifest.",
104 "Error", OptionPane.ERROR_MESSAGE);
105 return;
106 }
107
108 jar.close();
109 deviceClassName = deviceClassName.replace('.', '/');
110 if (deviceClassName.charAt(0) == '/') {
111 deviceClassName = deviceClassName.substring(1);
112 }
113 for (Enumeration e = deviceModel.elements(); e.hasMoreElements(); ) {
114 DeviceEntry entry = (DeviceEntry) e.nextElement();
115 if (deviceClassName.equals(entry.getClassName())) {
116 OptionPane.showMessageDialog(instance,
117 "Device is already added.",
118 "Info", OptionPane.INFORMATION_MESSAGE);
119 return;
120 }
121 }
122
123 loader.addRepository(fileChooser.getSelectedFile().toURL());
124 } catch (IOException ex) {
125 OptionPane.showMessageDialog(instance,
126 "Error reading " + fileChooser.getSelectedFile().getName() + " file.",
127 "Error", OptionPane.ERROR_MESSAGE);
128 return;
129 }
130
131 Class deviceClass = null;
132 try {
133 deviceClass = loader.findClass(deviceClassName);
134 } catch (ClassNotFoundException ex) {
135 OptionPane.showMessageDialog(instance,
136 "Cannot find class defined in Device-Class entry in jar manifest.",
137 "Error", OptionPane.ERROR_MESSAGE);
138 return;
139 }
140
141 if (!AppletDevice.class.isAssignableFrom(deviceClass)) {
142 OptionPane.showMessageDialog(instance,
143 "Cannot find class defined in Device-Class entry in jar manifest.",
144 "Error", OptionPane.ERROR_MESSAGE);
145 return;
146 }
147
148 try {
149 File deviceFile = File.createTempFile("dev", ".dev", Config.getConfigPath());
150 FileInputStream fis = new FileInputStream(fileChooser.getSelectedFile());
151 FileOutputStream fos = new FileOutputStream(deviceFile);
152 byte[] buf = new byte[1024];
153 int i = 0;
154 while((i=fis.read(buf))!=-1) {
155 fos.write(buf, 0, i);
156 }
157 fis.close();
158 fos.close();
159
160 DeviceEntry entry =
161 new DeviceEntry(deviceName, deviceFile.getName(), deviceClassName, false);
162 deviceModel.addElement(entry);
163 for (i = 0; i < deviceModel.size(); i++) {
164 if (deviceModel.elementAt(i) == entry) {
165 lsDevices.add(entry.getName());
166 lsDevices.select(i);
167 }
168 }
169 lsDevicesListener.itemStateChanged(null);
170 } catch (IOException ex) {
171 System.err.println(ex);
172 }
173 }
174 }
175 };
176
177 private ActionListener btRemoveListener = new ActionListener()
178 {
179 public void actionPerformed(ActionEvent ev)
180 {
181 DeviceEntry entry = (DeviceEntry) deviceModel.elementAt(lsDevices.getSelectedIndex());
182 File deviceFile = new File(Config.getConfigPath(), entry.getFileName());
183 deviceFile.delete();
184 if (entry.isDefaultDevice()) {
185 for (int i = 0; i < deviceModel.size(); i++) {
186 DeviceEntry tmp = (DeviceEntry) deviceModel.elementAt(i);
187 if (!tmp.canRemove()) {
188 tmp.setDefaultDevice(true);
189 lsDevices.replaceItem(tmp.getName() + " (default)", i);
190 break;
191 }
192 }
193 }
194 for (int i = 0; i < deviceModel.size(); i++) {
195 if (deviceModel.elementAt(i) == entry) {
196 deviceModel.removeElementAt(i);
197 lsDevices.remove(i);
198 break;
199 }
200 }
201 lsDevicesListener.itemStateChanged(null);
202 }
203 };
204
205 private ActionListener btDefaultListener = new ActionListener()
206 {
207 public void actionPerformed(ActionEvent ev)
208 {
209 DeviceEntry entry = (DeviceEntry) deviceModel.elementAt(lsDevices.getSelectedIndex());
210 for (int i = 0; i < deviceModel.size(); i++) {
211 DeviceEntry tmp = (DeviceEntry) deviceModel.elementAt(i);
212 if (tmp == entry) {
213 tmp.setDefaultDevice(true);
214 lsDevices.replaceItem(tmp.getName() + " (default)", i);
215 } else {
216 tmp.setDefaultDevice(false);
217 lsDevices.replaceItem(tmp.getName(), i);
218 }
219 }
220 lsDevices.repaint();
221 btDefault.setEnabled(false);
222 }
223 };
224
225 ItemListener lsDevicesListener = new ItemListener()
226 {
227 public void itemStateChanged(ItemEvent ev)
228 {
229 int index = lsDevices.getSelectedIndex();
230 if (index != -1) {
231 DeviceEntry entry = (DeviceEntry) deviceModel.elementAt(index);
232 if (entry.isDefaultDevice()) {
233 btDefault.setEnabled(false);
234 } else {
235 btDefault.setEnabled(true);
236 }
237 if (entry.canRemove()) {
238 btRemove.setEnabled(true);
239 } else {
240 btRemove.setEnabled(false);
241 }
242 btOk.setEnabled(true);
243 } else {
244 btDefault.setEnabled(false);
245 btRemove.setEnabled(false);
246 btOk.setEnabled(false);
247 }
248 }
249 };
250
251
252 public AwtSelectDevicePanel()
253 {
254 instance = this;
255
256 setLayout(new BorderLayout());
257
258 lsDevices = new List();
259 deviceModel = new Vector();
260 lsDevices.addItemListener(lsDevicesListener);
261 spDevices = new ScrollPane();
262 spDevices.add(lsDevices);
263 add(spDevices, BorderLayout.CENTER);
264
265 Panel panel = new Panel();
266 btAdd = new Button("Add...");
267 btAdd.addActionListener(btAddListener);
268 btRemove = new Button("Remove");
269 btRemove.addActionListener(btRemoveListener);
270 btDefault = new Button("Set as default");
271 btDefault.addActionListener(btDefaultListener);
272 panel.add(btAdd);
273 panel.add(btRemove);
274 panel.add(btDefault);
275
276 add(panel, BorderLayout.SOUTH);
277
278 Vector devs = Config.getDevices();
279 for (int i = 0; i < devs.size(); i++) {
280 DeviceEntry entry = (DeviceEntry) devs.elementAt(i);
281 deviceModel.addElement(entry);
282 if (entry.isDefaultDevice()) {
283 lsDevices.add(entry.getName() + " (default)");
284 lsDevices.select(i);
285 } else {
286 lsDevices.add(entry.getName());
287 }
288 }
289 lsDevicesListener.itemStateChanged(null);
290 }
291
292
293 public DeviceEntry getSelectedDeviceEntry()
294 {
295 return (DeviceEntry) deviceModel.elementAt(lsDevices.getSelectedIndex());
296 }
297
298
299 public void hideNotify()
300 {
301 Vector devices = Config.getDevices();
302 devices.removeAllElements();
303
304 for (Enumeration e = deviceModel.elements(); e.hasMoreElements(); ) {
305 devices.add(e.nextElement());
306 }
307
308 Config.saveConfig("config-awt.xml");
309 }
310
311 }