1 package tim.prune.function;
3 import java.awt.BorderLayout;
4 import java.awt.Component;
5 import java.awt.Dimension;
6 import java.awt.FlowLayout;
8 import java.awt.GridBagConstraints;
9 import java.awt.GridBagLayout;
10 import java.awt.event.ActionEvent;
11 import java.awt.event.ActionListener;
12 import java.awt.event.KeyEvent;
13 import java.awt.event.KeyListener;
14 import java.io.ByteArrayOutputStream;
16 import java.io.FileInputStream;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.util.zip.GZIPInputStream;
21 import javax.swing.BorderFactory;
22 import javax.swing.BoxLayout;
23 import javax.swing.JButton;
24 import javax.swing.JDialog;
25 import javax.swing.JEditorPane;
26 import javax.swing.JLabel;
27 import javax.swing.JPanel;
28 import javax.swing.JScrollPane;
29 import javax.swing.JTabbedPane;
30 import javax.swing.JTextArea;
33 import tim.prune.ExternalTools;
34 import tim.prune.GenericFunction;
35 import tim.prune.GpsPrune;
36 import tim.prune.I18nManager;
37 import tim.prune.threedee.WindowFactory;
40 * Class to represent the "About" popup window
42 public class AboutScreen extends GenericFunction
44 private JDialog _dialog = null;
45 private JTabbedPane _tabs = null;
46 private JButton _okButton = null;
47 private JTextArea _aboutTextArea = null;
48 /** Labels for whether tools installed or not */
49 private JLabel[] _installedLabels = null;
54 * @param inApp app object
56 public AboutScreen(App inApp)
62 * Return the name key for this function
64 public String getNameKey()
66 return "function.about";
70 * @return the contents of the window as a Component
72 private Component makeContents()
74 JPanel mainPanel = new JPanel();
75 mainPanel.setLayout(new BorderLayout());
77 _tabs = new JTabbedPane();
78 mainPanel.add(_tabs, BorderLayout.CENTER);
80 JPanel aboutPanel = new JPanel();
81 aboutPanel.setLayout(new BoxLayout(aboutPanel, BoxLayout.Y_AXIS));
82 aboutPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
83 JLabel titleLabel = new JLabel("GpsPrune");
84 titleLabel.setFont(new Font("SansSerif", Font.BOLD, 24));
85 titleLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
86 aboutPanel.add(titleLabel);
87 JLabel versionLabel = new JLabel(I18nManager.getText("dialog.about.version") + ": " + GpsPrune.VERSION_NUMBER);
88 versionLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
89 aboutPanel.add(versionLabel);
90 JLabel buildLabel = new JLabel(I18nManager.getText("dialog.about.build") + ": " + GpsPrune.BUILD_NUMBER);
91 buildLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
92 aboutPanel.add(buildLabel);
93 aboutPanel.add(new JLabel(" "));
94 StringBuffer descBuffer = new StringBuffer();
95 descBuffer.append("<p>").append(I18nManager.getText("dialog.about.summarytext1")).append("</p>");
96 descBuffer.append("<p>").append(I18nManager.getText("dialog.about.summarytext2")).append("</p>");
97 descBuffer.append("<p>").append(I18nManager.getText("dialog.about.summarytext3")).append("</p>");
98 descBuffer.append("<p>").append(I18nManager.getText("dialog.about.languages")).append(" : ")
99 .append("afrikaans, \u010de\u0161tina, deutsch, english, espa\u00F1ol, fran\u00E7ais, italiano,<br>" +
100 " magyar, nederlands, polski, portugu\u00EAs, rom\u00E2n\u0103, suomi, \u0440\u0443\u0441\u0441\u043a\u0438\u0439 (russian),<br>" +
101 " \u4e2d\u6587 (chinese), \u65E5\u672C\u8A9E (japanese), \uD55C\uAD6D\uC5B4/\uC870\uC120\uB9D0 (korean), schwiizerd\u00FC\u00FCtsch, ukrainian</p>");
102 descBuffer.append("<p>").append(I18nManager.getText("dialog.about.translatedby")).append("</p>");
103 JEditorPane descPane = new JEditorPane("text/html", descBuffer.toString());
104 descPane.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
105 descPane.setEditable(false);
106 descPane.setOpaque(false);
107 descPane.setAlignmentX(JEditorPane.CENTER_ALIGNMENT);
109 aboutPanel.add(descPane);
110 aboutPanel.add(new JLabel(" "));
111 _tabs.add(I18nManager.getText("function.about"), aboutPanel);
113 // Second pane for system info
114 JPanel sysInfoPanel = new JPanel();
115 GridBagLayout gridBag = new GridBagLayout();
116 sysInfoPanel.setLayout(gridBag);
117 GridBagConstraints constraints = new GridBagConstraints();
118 constraints.weightx = 0.0; constraints.weighty = 0.0;
119 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
120 new JLabel(I18nManager.getText("dialog.about.systeminfo.os") + " : "),
122 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
123 new JLabel(System.getProperty("os.name")),
125 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
126 new JLabel(I18nManager.getText("dialog.about.systeminfo.java") + " : "),
128 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
129 new JLabel(System.getProperty("java.runtime.version")),
131 // Create install labels to be populated later
132 final int NUM_INSTALL_CHECKS = 5;
133 _installedLabels = new JLabel[NUM_INSTALL_CHECKS];
134 for (int i=0; i<NUM_INSTALL_CHECKS; i++) {
135 _installedLabels[i] = new JLabel("...");
137 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
138 new JLabel(I18nManager.getText("dialog.about.systeminfo.java3d") + " : "),
140 addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[0], 1, 2);
141 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
142 new JLabel(I18nManager.getText("dialog.about.systeminfo.exiftool") + " : "),
144 addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[1], 1, 3);
145 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
146 new JLabel(I18nManager.getText("dialog.about.systeminfo.gpsbabel") + " : "),
148 addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[2], 1, 4);
149 addToGridBagPanel(sysInfoPanel, gridBag, constraints,
150 new JLabel(I18nManager.getText("dialog.about.systeminfo.gnuplot") + " : "),
152 addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[3], 1, 5);
153 addToGridBagPanel(sysInfoPanel, gridBag, constraints, new JLabel("Xerces : "), 0, 6);
154 addToGridBagPanel(sysInfoPanel, gridBag, constraints, _installedLabels[4], 1, 6);
155 _tabs.add(I18nManager.getText("dialog.about.systeminfo"), sysInfoPanel);
157 // Third pane for credits
158 JPanel creditsPanel = new JPanel();
159 gridBag = new GridBagLayout();
160 creditsPanel.setLayout(gridBag);
161 constraints = new GridBagConstraints();
162 constraints.weightx = 0.0; constraints.weighty = 0.0;
163 constraints.ipady = 3;
165 addToGridBagPanel(creditsPanel, gridBag, constraints,
166 new JLabel(I18nManager.getText("dialog.about.credits.code") + " : "),
168 addToGridBagPanel(creditsPanel, gridBag, constraints,
169 new JLabel("activityworkshop.net"),
171 addToGridBagPanel(creditsPanel, gridBag, constraints,
172 new JLabel(I18nManager.getText("dialog.about.credits.exifcode") + " : "),
174 addToGridBagPanel(creditsPanel, gridBag, constraints,
175 new JLabel("Drew Noakes"),
177 addToGridBagPanel(creditsPanel, gridBag, constraints,
178 new JLabel(I18nManager.getText("dialog.about.credits.icons") + " : "),
180 addToGridBagPanel(creditsPanel, gridBag, constraints,
181 new JLabel("Eclipse"),
183 addToGridBagPanel(creditsPanel, gridBag, constraints,
184 new JLabel(I18nManager.getText("dialog.about.credits.translators") + " : "),
186 addToGridBagPanel(creditsPanel, gridBag, constraints,
187 new JLabel("Ramon, Miguel, In\u00E9s, Piotr, Petrovsk, Josatoc, Weehal,"),
189 addToGridBagPanel(creditsPanel, gridBag, constraints,
190 new JLabel(" theYinYeti, Rothermographer, Sam, Rudolph, nazotoko,"),
192 addToGridBagPanel(creditsPanel, gridBag, constraints,
193 new JLabel(" katpatuka, R\u00E9mi, Marcus, Ali, Javier, Jeroen, prot_d,"),
195 addToGridBagPanel(creditsPanel, gridBag, constraints,
196 new JLabel(" Gy\u00F6rgy, HooAU, Sergey, P\u00E9ter, serhijdubyk, Peter, Cristian,"),
198 addToGridBagPanel(creditsPanel, gridBag, constraints,
199 new JLabel(" Roman, Erkki"),
201 addToGridBagPanel(creditsPanel, gridBag, constraints,
202 new JLabel(I18nManager.getText("dialog.about.credits.translations") + " : "),
204 addToGridBagPanel(creditsPanel, gridBag, constraints,
205 new JLabel("Open Office, Gpsdrive, Babelfish, Leo, Launchpad"),
207 addToGridBagPanel(creditsPanel, gridBag, constraints,
208 new JLabel(I18nManager.getText("dialog.about.credits.devtools") + " : "),
210 addToGridBagPanel(creditsPanel, gridBag, constraints,
211 new JLabel("Debian Linux, Sun Java, OpenJDK, Eclipse, Svn, Gimp, Inkscape"),
213 addToGridBagPanel(creditsPanel, gridBag, constraints,
214 new JLabel(I18nManager.getText("dialog.about.credits.othertools") + " : "),
216 addToGridBagPanel(creditsPanel, gridBag, constraints,
217 new JLabel("Openstreetmap, Povray, Exiftool, Gpsbabel, Gnuplot"),
219 addToGridBagPanel(creditsPanel, gridBag, constraints,
220 new JLabel(I18nManager.getText("dialog.about.credits.thanks") + " : "),
222 addToGridBagPanel(creditsPanel, gridBag, constraints,
223 new JLabel("Friends and loved ones, for encouragement and support"),
225 _tabs.add(I18nManager.getText("dialog.about.credits"), creditsPanel);
228 JPanel readmePanel = new JPanel();
229 readmePanel.setLayout(new BorderLayout());
230 _aboutTextArea = new JTextArea(I18nManager.getText("details.photo.loading"));
231 // Set readme text in separate thread so that about screen pops up sooner
232 new Thread(new Runnable() {
234 _aboutTextArea.setText(getReadmeText());
237 _aboutTextArea.setEditable(false);
238 _aboutTextArea.setLineWrap(true); _aboutTextArea.setWrapStyleWord(true);
239 JScrollPane scrollPane = new JScrollPane(_aboutTextArea);
240 scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
241 scrollPane.setPreferredSize(new Dimension(600, 130));
242 readmePanel.add(scrollPane, BorderLayout.CENTER);
243 _tabs.add(I18nManager.getText("dialog.about.readme"), readmePanel);
245 // OK button at the bottom
246 JPanel okPanel = new JPanel();
247 okPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
248 _okButton = new JButton(I18nManager.getText("button.ok"));
249 _okButton.addActionListener(new ActionListener()
251 public void actionPerformed(ActionEvent e)
256 _okButton.addKeyListener(new KeyListener() {
257 public void keyPressed(KeyEvent e)
259 if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {_dialog.dispose();}
261 public void keyTyped(KeyEvent e) {}
262 public void keyReleased(KeyEvent e) {}
264 okPanel.add(_okButton);
265 mainPanel.add(okPanel, BorderLayout.SOUTH);
270 * Helper function to reduce complexity of gui-making code
271 * when adding labels to a GridBagLayout
272 * @param inPanel panel to add to
273 * @param inLayout GridBagLayout object
274 * @param inConstraints GridBagConstraints object
275 * @param inLabel label to add
279 private static void addToGridBagPanel(JPanel inPanel, GridBagLayout inLayout,
280 GridBagConstraints inConstraints, JLabel inLabel, int inX, int inY)
282 // set x and y in constraints
283 inConstraints.gridx = inX;
284 inConstraints.gridy = inY;
286 inConstraints.anchor = (inX == 0?GridBagConstraints.EAST:GridBagConstraints.WEST);
287 // set constraints to label
288 inLayout.setConstraints(inLabel, inConstraints);
289 // add label to panel
290 inPanel.add(inLabel);
294 * @return text from the readme file
296 private String getReadmeText()
298 // First, try locally-held readme.txt if available (as it normally should be)
299 // Readme file can either be in file system or packed in the same jar as code
300 String errorMessage = null;
301 String readme = null;
302 InputStream in = null;
305 // For some reason using ../readme.txt doesn't work, so need absolute path
306 in = AboutScreen.class.getResourceAsStream("/tim/prune/readme.txt");
308 byte[] buffer = new byte[in.available()];
311 readme = new String(buffer);
314 catch (IOException e) {
315 errorMessage = e.getMessage();
318 try {in.close();} catch (Exception e) {}
320 if (readme != null) {return readme;}
322 // Locally-held file failed, so try to find gz file installed on system (eg Debian)
325 File gzFile = new File("/usr/share/doc/gpsprune/readme.txt.gz");
328 // Copy decompressed bytes from gz file into out
329 in = new GZIPInputStream(new FileInputStream(gzFile));
330 ByteArrayOutputStream out = new ByteArrayOutputStream();
331 byte[] buffer = new byte[8 * 1024];
334 out.write(buffer, 0, count);
335 count = in.read(buffer, 0, buffer.length);
336 } while (count != -1);
339 readme = out.toString();
342 catch (IOException e) {
343 System.err.println("Exception trying to get readme.gz : " + e.getMessage());
346 try {in.close();} catch (Exception e) {}
348 if (readme != null) {return readme;}
349 // Only show first error message if couldn't get readme from gz either
350 if (errorMessage != null) {
351 System.err.println("Exception trying to get readme: " + errorMessage);
353 return I18nManager.getText("error.readme.notfound");
363 _dialog = new JDialog(_parentFrame, I18nManager.getText(getNameKey()));
364 _dialog.getContentPane().add(makeContents());
367 _tabs.setSelectedIndex(0);
369 _dialog.setVisible(true);
370 _okButton.requestFocus();
374 * Check the installed components and set the label texts accordingly
376 private void checkInstalls()
378 String yesText = I18nManager.getText("dialog.about.yes");
379 String noText = I18nManager.getText("dialog.about.no");
380 _installedLabels[0].setText(WindowFactory.isJava3dEnabled()?yesText:noText);
381 final int[] tools = {ExternalTools.TOOL_EXIFTOOL, ExternalTools.TOOL_GPSBABEL,
382 ExternalTools.TOOL_GNUPLOT, ExternalTools.TOOL_XERCES};
383 for (int i=0; i<tools.length; i++) {
384 _installedLabels[i+1].setText(ExternalTools.isToolInstalled(tools[i])?yesText:noText);