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