Source code: com/barteo/emulator/app/ui/swing/SwingSelectDevicePanel.java
1 /*
2 * MicroEmulator
3 * Copyright (C) 2002 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.swing;
21
22 import java.awt.BorderLayout;
23 import java.awt.event.ActionEvent;
24 import java.awt.event.ActionListener;
25 import java.io.File;
26 import java.io.FileInputStream;
27 import java.io.FileOutputStream;
28 import java.io.IOException;
29 import java.util.Enumeration;
30 import java.util.Vector;
31 import java.util.jar.Attributes;
32 import java.util.jar.JarFile;
33 import java.util.jar.Manifest;
34
35 import javax.swing.DefaultListModel;
36 import javax.swing.JButton;
37 import javax.swing.JFileChooser;
38 import javax.swing.JList;
39 import javax.swing.JOptionPane;
40 import javax.swing.JPanel;
41 import javax.swing.JScrollPane;
42 import javax.swing.ListSelectionModel;
43 import javax.swing.border.EtchedBorder;
44 import javax.swing.border.TitledBorder;
45 import javax.swing.event.ListSelectionEvent;
46 import javax.swing.event.ListSelectionListener;
47
48 import com.barteo.emulator.app.Config;
49 import com.barteo.emulator.app.util.DeviceEntry;
50 import com.barteo.emulator.app.util.ProgressJarClassLoader;
51 import com.barteo.emulator.device.j2se.J2SEDevice;
52
53
54 public class SwingSelectDevicePanel extends SwingDialogPanel
55 {
56 private SwingSelectDevicePanel instance;
57
58 private JScrollPane spDevices;
59 private JButton btAdd;
60 private JButton btRemove;
61 private JButton btDefault;
62 private DefaultListModel lsDevicesModel;
63 private JList lsDevices;
64
65 private ActionListener btAddListener = new ActionListener()
66 {
67 private JFileChooser fileChooser = null;
68
69 public void actionPerformed(ActionEvent ev)
70 {
71 if (fileChooser == null) {
72 fileChooser = new JFileChooser();
73 ExtensionFileFilter fileFilter = new ExtensionFileFilter("Device profile (*.dev)");
74 fileFilter.addExtension("dev");
75 fileChooser.setFileFilter(fileFilter);
76 }
77
78 ProgressJarClassLoader loader = new ProgressJarClassLoader();
79
80 if (fileChooser.showOpenDialog(instance) == JFileChooser.APPROVE_OPTION) {
81 String deviceClassName = null;
82 String deviceName = null;
83 try {
84 JarFile jar = new JarFile(fileChooser.getSelectedFile());
85 Manifest manifest = jar.getManifest();
86 if (manifest == null) {
87 JOptionPane.showMessageDialog(instance,
88 "Missing manifest in dev file.",
89 "Error", JOptionPane.ERROR_MESSAGE);
90 return;
91 }
92 Attributes attrs = manifest.getMainAttributes();
93
94 deviceName = attrs.getValue("Device-Name");
95 if (deviceName == null) {
96 JOptionPane.showMessageDialog(instance,
97 "Missing Device-Name entry in jar manifest.",
98 "Error", JOptionPane.ERROR_MESSAGE);
99 return;
100 }
101
102 deviceClassName = attrs.getValue("Device-Class");
103 if (deviceClassName == null) {
104 JOptionPane.showMessageDialog(instance,
105 "Missing Device-Class entry in jar manifest.",
106 "Error", JOptionPane.ERROR_MESSAGE);
107 return;
108 }
109
110 jar.close();
111 deviceClassName = deviceClassName.replace('.', '/');
112 if (deviceClassName.charAt(0) == '/') {
113 deviceClassName = deviceClassName.substring(1);
114 }
115 for (Enumeration e = lsDevicesModel.elements(); e.hasMoreElements(); ) {
116 DeviceEntry entry = (DeviceEntry) e.nextElement();
117 if (deviceClassName.equals(entry.getClassName())) {
118 JOptionPane.showMessageDialog(instance,
119 "Device is already added.",
120 "Info", JOptionPane.INFORMATION_MESSAGE);
121 return;
122 }
123 }
124
125 loader.addRepository(fileChooser.getSelectedFile().toURL());
126 } catch (IOException ex) {
127 JOptionPane.showMessageDialog(instance,
128 "Error reading " + fileChooser.getSelectedFile().getName() + " file.",
129 "Error", JOptionPane.ERROR_MESSAGE);
130 return;
131 }
132
133 Class deviceClass = null;
134 try {
135 deviceClass = loader.findClass(deviceClassName);
136 } catch (ClassNotFoundException ex) {
137 JOptionPane.showMessageDialog(instance,
138 "Cannot find class defined in Device-Class entry in jar manifest.",
139 "Error", JOptionPane.ERROR_MESSAGE);
140 return;
141 }
142
143 if (!J2SEDevice.class.isAssignableFrom(deviceClass)) {
144 JOptionPane.showMessageDialog(instance,
145 "Cannot find class defined in Device-Class entry in jar manifest.",
146 "Error", JOptionPane.ERROR_MESSAGE);
147 return;
148 }
149
150 try {
151 File deviceFile = File.createTempFile("dev", ".dev", Config.getConfigPath());
152 FileInputStream fis = new FileInputStream(fileChooser.getSelectedFile());
153 FileOutputStream fos = new FileOutputStream(deviceFile);
154 byte[] buf = new byte[1024];
155 int i = 0;
156 while((i=fis.read(buf))!=-1) {
157 fos.write(buf, 0, i);
158 }
159 fis.close();
160 fos.close();
161
162 DeviceEntry entry =
163 new DeviceEntry(deviceName, deviceFile.getName(), deviceClassName, false);
164 lsDevicesModel.addElement(entry);
165 lsDevices.setSelectedValue(entry, true);
166 } catch (IOException ex) {
167 System.err.println(ex);
168 }
169 }
170 }
171 };
172
173 private ActionListener btRemoveListener = new ActionListener()
174 {
175 public void actionPerformed(ActionEvent ev)
176 {
177 DeviceEntry entry = (DeviceEntry) lsDevices.getSelectedValue();
178 File deviceFile = new File(Config.getConfigPath(), entry.getFileName());
179 deviceFile.delete();
180 if (entry.isDefaultDevice()) {
181 for (Enumeration en = lsDevicesModel.elements(); en.hasMoreElements(); ) {
182 DeviceEntry tmp = (DeviceEntry) en.nextElement();
183 if (!tmp.canRemove()) {
184 tmp.setDefaultDevice(true);
185 break;
186 }
187 }
188 }
189 lsDevicesModel.removeElement(entry);
190 }
191 };
192
193 private ActionListener btDefaultListener = new ActionListener()
194 {
195 public void actionPerformed(ActionEvent ev)
196 {
197 DeviceEntry entry = (DeviceEntry) lsDevices.getSelectedValue();
198 for (Enumeration en = lsDevicesModel.elements(); en.hasMoreElements(); ) {
199 DeviceEntry tmp = (DeviceEntry) en.nextElement();
200 if (tmp == entry) {
201 tmp.setDefaultDevice(true);
202 } else {
203 tmp.setDefaultDevice(false);
204 }
205 }
206 lsDevices.repaint();
207 btDefault.setEnabled(false);
208 }
209 };
210
211 ListSelectionListener listSelectionListener = new ListSelectionListener()
212 {
213 public void valueChanged(ListSelectionEvent ev)
214 {
215 DeviceEntry entry = (DeviceEntry) lsDevices.getSelectedValue();
216 if (entry != null) {
217 if (entry.isDefaultDevice()) {
218 btDefault.setEnabled(false);
219 } else {
220 btDefault.setEnabled(true);
221 }
222 if (entry.canRemove()) {
223 btRemove.setEnabled(true);
224 } else {
225 btRemove.setEnabled(false);
226 }
227 btOk.setEnabled(true);
228 } else {
229 btDefault.setEnabled(false);
230 btRemove.setEnabled(false);
231 btOk.setEnabled(false);
232 }
233 }
234 };
235
236
237 public SwingSelectDevicePanel()
238 {
239 instance = this;
240
241 setLayout(new BorderLayout());
242 setBorder(new TitledBorder(new EtchedBorder(), "Installed devices"));
243
244 lsDevicesModel = new DefaultListModel();
245 lsDevices = new JList(lsDevicesModel);
246 lsDevices.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
247 lsDevices.addListSelectionListener(listSelectionListener);
248 spDevices = new JScrollPane(lsDevices);
249 add(spDevices, BorderLayout.CENTER);
250
251 JPanel panel = new JPanel();
252 btAdd = new JButton("Add...");
253 btAdd.addActionListener(btAddListener);
254 btRemove = new JButton("Remove");
255 btRemove.addActionListener(btRemoveListener);
256 btDefault = new JButton("Set as default");
257 btDefault.addActionListener(btDefaultListener);
258 panel.add(btAdd);
259 panel.add(btRemove);
260 panel.add(btDefault);
261
262 add(panel, BorderLayout.SOUTH);
263
264 for (Enumeration e = Config.getDevices().elements(); e.hasMoreElements(); ) {
265 DeviceEntry entry = (DeviceEntry) e.nextElement();
266 lsDevicesModel.addElement(entry);
267 if (entry.isDefaultDevice()) {
268 lsDevices.setSelectedValue(entry, true);
269 }
270 }
271 }
272
273
274 public DeviceEntry getSelectedDeviceEntry()
275 {
276 return (DeviceEntry) lsDevices.getSelectedValue();
277 }
278
279
280 public void hideNotify()
281 {
282 Vector devices = Config.getDevices();
283 devices.removeAllElements();
284
285 for (Enumeration e = lsDevicesModel.elements(); e.hasMoreElements(); ) {
286 devices.add(e.nextElement());
287 }
288
289 Config.saveConfig("config.xml");
290 }
291
292 }