Updates for 0.9.5
[debian/openrocket] / src / net / sf / openrocket / gui / dialogs / ExampleDesignDialog.java
1 package net.sf.openrocket.gui.dialogs;
2
3 import java.awt.Dialog;
4 import java.awt.Window;
5 import java.awt.event.ActionEvent;
6 import java.awt.event.ActionListener;
7 import java.awt.event.MouseAdapter;
8 import java.awt.event.MouseEvent;
9 import java.io.File;
10 import java.io.FilenameFilter;
11 import java.io.IOException;
12 import java.net.MalformedURLException;
13 import java.net.URL;
14 import java.util.ArrayList;
15 import java.util.Arrays;
16 import java.util.Enumeration;
17 import java.util.jar.JarEntry;
18 import java.util.jar.JarFile;
19
20 import javax.swing.JButton;
21 import javax.swing.JDialog;
22 import javax.swing.JLabel;
23 import javax.swing.JList;
24 import javax.swing.JOptionPane;
25 import javax.swing.JPanel;
26 import javax.swing.JScrollPane;
27 import javax.swing.ListSelectionModel;
28
29 import net.miginfocom.swing.MigLayout;
30 import net.sf.openrocket.util.BugException;
31 import net.sf.openrocket.util.GUIUtil;
32 import net.sf.openrocket.util.JarUtil;
33
34 public class ExampleDesignDialog extends JDialog {
35         
36         private static final String DIRECTORY = "datafiles/examples/";
37         private static final String PATTERN = ".*\\.[oO][rR][kK]$";
38         private static final FilenameFilter FILTER = new FilenameFilter() {
39                 @Override
40                 public boolean accept(File dir, String name) {
41                         return name.matches(PATTERN);
42                 }
43         };
44         
45
46         private boolean open = false;
47         private final JList designSelection;
48         
49         private ExampleDesignDialog(ExampleDesign[] designs, Window parent) {
50                 super(parent, "Open example design", Dialog.ModalityType.APPLICATION_MODAL);
51                 
52                 JPanel panel = new JPanel(new MigLayout("fill"));
53                 
54                 panel.add(new JLabel("Select example designs to open:"), "wrap");
55                 
56                 designSelection = new JList(designs);
57                 designSelection.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
58                 designSelection.addMouseListener(new MouseAdapter() {
59                         @Override
60                         public void mouseClicked(MouseEvent e) {
61                                 if (e.getClickCount() >= 2) {
62                                         open = true;
63                                         ExampleDesignDialog.this.setVisible(false);
64                                 }
65                         }
66                 });
67                 panel.add(new JScrollPane(designSelection), "grow, wmin 300lp, wrap para");
68                 
69                 JButton openButton = new JButton("Open");
70                 openButton.addActionListener(new ActionListener() {
71                         @Override
72                         public void actionPerformed(ActionEvent e) {
73                                 open = true;
74                                 ExampleDesignDialog.this.setVisible(false);
75                         }
76                 });
77                 panel.add(openButton, "split 2, sizegroup buttons, growx");
78                 
79                 JButton cancelButton = new JButton("Cancel");
80                 cancelButton.addActionListener(new ActionListener() {
81                         @Override
82                         public void actionPerformed(ActionEvent e) {
83                                 open = false;
84                                 ExampleDesignDialog.this.setVisible(false);
85                         }
86                 });
87                 panel.add(cancelButton, "sizegroup buttons, growx");
88
89                 this.add(panel);
90                 this.pack();
91                 this.setLocationByPlatform(true);
92                 
93                 GUIUtil.setDisposableDialogOptions(this, openButton);
94         }
95         
96         
97         /**
98          * Open a dialog to allow opening the example designs.
99          * 
100          * @param parent        the parent window of the dialog.
101          * @return                      an array of URL's to open, or <code>null</code> if the operation
102          *                                      was cancelled.
103          */
104         public static URL[] selectExampleDesigns(Window parent) {
105                 
106                 ExampleDesign[] designs;
107                 
108                 designs = getJarFileNames();
109                 if (designs == null || designs.length == 0) {
110                         designs = getDirFileNames();
111                 }
112                 if (designs == null || designs.length == 0) {
113                         JOptionPane.showMessageDialog(parent, "Example designs could not be found.",
114                                         "Examples not found", JOptionPane.ERROR_MESSAGE);
115                         return null;
116                 }
117                 
118                 Arrays.sort(designs);
119                 
120                 ExampleDesignDialog dialog = new ExampleDesignDialog(designs, parent);
121                 dialog.setVisible(true);
122                 
123                 if (!dialog.open) {
124                         return null;
125                 }
126                 
127                 Object[] selected = dialog.designSelection.getSelectedValues();
128                 URL[] urls = new URL[selected.length];
129                 for (int i=0; i<selected.length; i++) {
130                         urls[i] = ((ExampleDesign)selected[i]).getURL();
131                 }
132                 return urls;
133         }
134         
135         
136         
137         
138         
139         private static ExampleDesign[] getDirFileNames() {
140                 
141                 // Try to find directory as a system resource
142                 File dir;
143                 URL url = ClassLoader.getSystemResource(DIRECTORY);
144                 
145                 try {
146                         dir = JarUtil.urlToFile(url);
147                 } catch (Exception e1) {
148                         dir = new File(DIRECTORY);
149                 }
150
151                 // Get the list of files
152                 File[] files = dir.listFiles(FILTER);
153                 if (files == null)
154                         return null;
155                 
156                 ExampleDesign[] designs = new ExampleDesign[files.length];
157                 
158                 for (int i=0; i<files.length; i++) {
159                         String name = files[i].getName();
160                         try {
161                                 designs[i] = new ExampleDesign(files[i].toURI().toURL(), 
162                                                 name.substring(0, name.length()-4));
163                         } catch (MalformedURLException e) {
164                                 throw new BugException(e);
165                         }
166                 }
167                 return designs;
168         }
169
170         
171         
172         private static ExampleDesign[] getJarFileNames() {
173                 
174                 ArrayList<ExampleDesign> list = new ArrayList<ExampleDesign>();
175                 int dirLength = DIRECTORY.length();
176
177                 // Find and open the jar file this class is contained in
178                 File file = JarUtil.getCurrentJarFile();
179                 if (file == null)
180                         return null;
181                 
182
183                 // Generate URL pointing to JAR file
184                 URL fileUrl;
185                 try {
186                         fileUrl = file.toURI().toURL();
187                 } catch (MalformedURLException e1) {
188                         e1.printStackTrace();
189                         throw new BugException(e1);
190                 }
191                 
192                 // Iterate over JAR entries searching for designs
193                 JarFile jarFile = null;
194                 try {
195                         jarFile = new JarFile(file);
196
197                         // Loop through JAR entries searching for files to load
198                         Enumeration<JarEntry> entries = jarFile.entries();
199                         while (entries.hasMoreElements()) {
200                                 JarEntry entry = entries.nextElement();
201                                 String name = entry.getName();
202                                 if (name.startsWith(DIRECTORY) && FILTER.accept(null, name)) {
203                                         String urlName = "jar:" + fileUrl + "!/" + name;
204                                         URL url = new URL(urlName);
205                                         list.add(new ExampleDesign(url, 
206                                                         name.substring(dirLength, name.length()-4)));
207                                 }
208                         }
209
210                 } catch (IOException e) {
211                         // Could be normal condition if not package in JAR
212                         return null;
213                 } finally {
214                         if (jarFile != null) {
215                                 try {
216                                         jarFile.close();
217                                 } catch (IOException e) {
218                                         e.printStackTrace();
219                                 }
220                         }
221                 }
222                 
223                 return list.toArray(new ExampleDesign[0]);
224         }
225         
226         
227         
228         /**
229          * Data holder class.
230          */
231         private static class ExampleDesign implements Comparable<ExampleDesign> {
232                 
233                 private final URL url;
234                 private final String name;
235                 
236                 public ExampleDesign(URL url, String name) {
237                         this.url = url;
238                         this.name = name;
239                 }
240                 
241                 @Override
242                 public String toString() {
243                         return name;
244                 }
245                 
246                 public URL getURL() {
247                         return url;
248                 }
249
250                 @Override
251                 public int compareTo(ExampleDesign o) {
252                         return this.name.compareTo(o.name);
253                 }
254         }
255         
256 }