jTracer  1.03
Stack trace visualization tool
MainFrame.java
Go to the documentation of this file.
1 
7 package org.libcsdbg.jtracer.installer;
8 
9 /*
10 import java.util.Hashtable;
11 import java.util.Enumeration;
12 import java.net.URL;
13 import java.awt.Container;
14 import java.awt.EventQueue;
15 import javax.swing.ImageIcon;
16 import javax.swing.SwingUtilities;
17 */
18 
19 import java.util.Vector;
20 import java.util.zip.ZipEntry;
21 import java.util.jar.JarInputStream;
22 
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.FileOutputStream;
26 import java.io.FileWriter;
27 import java.io.DataInputStream;
28 import java.io.DataOutputStream;
29 import java.io.IOException;
30 
31 import java.net.URL;
32 
33 import java.nio.channels.FileLock;
34 import java.nio.file.Files;
35 
36 import java.awt.event.KeyEvent;
37 import java.awt.event.ActionEvent;
38 import java.awt.event.ActionListener;
39 import java.awt.Font;
40 import java.awt.Color;
41 import java.awt.Dimension;
42 import java.awt.Insets;
43 import java.awt.BorderLayout;
44 import java.awt.GridBagLayout;
45 import java.awt.GridBagConstraints;
46 
47 import javax.swing.event.HyperlinkEvent;
48 import javax.swing.event.HyperlinkListener;
49 import javax.swing.JFrame;
50 import javax.swing.JLabel;
51 import javax.swing.JPanel;
52 import javax.swing.JEditorPane;
53 import javax.swing.JScrollPane;
54 import javax.swing.JCheckBox;
55 import javax.swing.JProgressBar;
56 import javax.swing.JFileChooser;
57 import javax.swing.UIManager;
58 import javax.swing.WindowConstants;
59 
63 public class MainFrame extends JFrame implements
64  Runnable,
65  ActionListener,
66  HyperlinkListener
67 {
69  private static final long serialVersionUID = 0x00;
70 
72  private JLabel caption = null;
73 
75  private JLabel progress = null;
76 
78  private JPanel viewport = null;
79 
81  private Button previous = null, next = null, select = null;
82 
84  private TextField home = null, prefix = null;
85 
87  private JProgressBar setupBar = null;
88 
89  private AboutDialog about = null;
90 
92  private Vector<JPanel> screens = null;
93 
95  private int current = 0;
96 
98  private FileLock lock = null;
99 
101  private Thread installer = null;
102 
103 
107  MainFrame()
108  {
109  super();
110  Registry conf = Registry.getCurrent();
111  screens = new Vector<JPanel>();
112 
113  String pkg = (String) conf.get("installed", "package");
114  setTitle("Installation of " + pkg);
115  setIconImages(conf.getProjectIcons());
116 
117  add(createCaption(), BorderLayout.NORTH);
118  add(createControls(), BorderLayout.SOUTH);
119  try {
120  createScreen(0);
121  createScreen(1);
122  createScreen(2);
123  }
124 
125  catch (Throwable t) {
126  Registry.debug(t);
127  dispose();
128  return;
129  }
130 
131  viewport = new JPanel(new BorderLayout());
132  viewport.add(screens.get(0), BorderLayout.CENTER);
133  add(viewport, BorderLayout.CENTER);
134 
135  setSize((Dimension) conf.get("generic", "size"));
136  setLocationRelativeTo(null);
137  setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
138  }
139 
140 
146  private JPanel createCaption()
147  {
148  Registry conf = Registry.getCurrent();
149  GridBagLayout lm = new GridBagLayout();
150  GridBagConstraints c = new GridBagConstraints();
151  JPanel retval = new JPanel(lm);
152 
153  String pkg = (String) conf.get("installed", "package");
154  caption = new JLabel("Installing " + pkg);
155  caption.setFont((Font) conf.get("caption", "font"));
156  caption.setForeground((Color) conf.get("caption", "fgcolor"));
157 
158  c.gridx = c.gridy = 0;
159  c.weightx = 1.0;
160  c.insets = new Insets(12, 12, 0, 12);
161  c.fill = GridBagConstraints.HORIZONTAL;
162  c.anchor = GridBagConstraints.WEST;
163  lm.setConstraints(caption, c);
164  retval.add(caption);
165 
166  return retval;
167  }
168 
169 
175  private JPanel createControls()
176  {
177  GridBagLayout lm = new GridBagLayout();
178  GridBagConstraints c = new GridBagConstraints();
179  JPanel retval = new JPanel(lm);
180 
181  Button info = new Button("About", this);
182  info.setMnemonic(KeyEvent.VK_A);
183 
184  Button cancel = new Button("Cancel", this);
185  cancel.setMnemonic(KeyEvent.VK_C);
186 
187  next = new Button("Next", this);
188  next.setMnemonic(KeyEvent.VK_N);
189 
190  previous = new Button("Previous", this);
191  previous.setMnemonic(KeyEvent.VK_P);
192  previous.setEnabled(false);
193 
194  c.gridx = c.gridy = 0;
195  c.insets = new Insets(12, 12, 6, 12);
196  lm.setConstraints(info, c);
197  retval.add(info);
198 
199  c.gridx++;
200  c.weightx = 1.0;
201  c.insets.left = 0;
202  c.anchor = GridBagConstraints.WEST;
203  lm.setConstraints(cancel, c);
204  retval.add(cancel);
205 
206  c.gridx++;
207  c.weightx = 0;
208  c.anchor = GridBagConstraints.CENTER;
209  lm.setConstraints(previous, c);
210  retval.add(previous);
211 
212  c.gridx++;
213  c.insets.left = 0;
214  lm.setConstraints(next, c);
215  retval.add(next);
216 
217  return retval;
218  }
219 
220 
226  private void createScreen(int i) throws IOException
227  {
228  Registry conf = Registry.getCurrent();
229  GridBagLayout lm = new GridBagLayout();
230  GridBagConstraints c = new GridBagConstraints();
231  JPanel scr = new JPanel(lm);
232 
233  Font fnt = (Font) conf.get("component", "font");
234  Color fg = (Color) conf.get("component", "fgcolor");
235 
236  switch (i) {
237  case 0:
238  case 1:
239  File page = null;
240  if (i == 0)
241  page = conf.getResource("var/package.html");
242  else
243  page = conf.getResource("var/license.html");
244 
245  JEditorPane pager = new JEditorPane(page.toURI().toURL());
246  pager.putClientProperty(JEditorPane.W3C_LENGTH_UNITS, true);
247  pager.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, true);
248  pager.addHyperlinkListener(this);
249  pager.setEditable(false);
250  pager.setMargin(new Insets(0, 0, 0, 0));
251  JScrollPane viewport = new JScrollPane(pager);
252 
253 
254  c.gridx = c.gridy = 0;
255  c.weightx = c.weighty = 1;
256  c.insets = new Insets(12, 12, 0, 12);
257  c.fill = GridBagConstraints.BOTH;
258  lm.setConstraints(viewport, c);
259  scr.add(viewport);
260  break;
261 
262  case 2:
263  JLabel l = new JLabel("User data in: ");
264  l.setFont(fnt);
265  l.setForeground(fg);
266  c.gridx = c.gridy = 0;
267  c.insets = new Insets(12, 12, 0, 0);
268  c.anchor = GridBagConstraints.EAST;
269  lm.setConstraints(l, c);
270  scr.add(l);
271 
272  l = new JLabel("Install in: ");
273  l.setFont(fnt);
274  l.setForeground(fg);
275  c.gridy++;
276  lm.setConstraints(l, c);
277  scr.add(l);
278 
279  String pkg = (String) conf.get("installed", "name");
280  File f = new File(Registry.getHomeDirectory(), "." + pkg);
281  if (Registry.isLinux())
282  home = new TextField(f.getCanonicalPath());
283  else
284  home = new TextField("C:\\Program Files\\" + pkg + "\\");
285 
286  home.setFont(fnt);
287  home.setForeground(fg);
288  home.setEnabled(false);
289  c.gridy = 0;
290  c.gridx++;
291  c.weightx = 1;
292  c.insets.left = 2;
293  //c.ipady = 7;
294  c.anchor = GridBagConstraints.CENTER;
295  c.fill = GridBagConstraints.HORIZONTAL;
296  lm.setConstraints(home, c);
297  scr.add(home);
298 
299  if (Registry.isLinux())
300  prefix = new TextField("/usr/local/");
301  else
302  prefix = new TextField("C:\\Program Files\\" + pkg + "\\");
303 
304  prefix.setFont(fnt);
305  prefix.setForeground(fg);
306  c.gridy++;
307  lm.setConstraints(prefix, c);
308  scr.add(prefix);
309 
310  select = new Button("Select", this);
311  select.setMnemonic(KeyEvent.VK_S);
312  c.gridx++;
313  c.weightx = 0;
314  c.insets.right = 12;
315  //c.ipady = 0;
316  c.fill = GridBagConstraints.NONE;
317  lm.setConstraints(select, c);
318  scr.add(select);
319 
320  JCheckBox storeApi = new JCheckBox("Install all documentation", true);
321  storeApi.setFont(fnt);
322  storeApi.setForeground(fg);
323  c.gridx = 1;
324  c.gridy++;
325  c.anchor = GridBagConstraints.WEST;
326  lm.setConstraints(storeApi, c);
327  scr.add(storeApi);
328 
329  JCheckBox themes = new JCheckBox("Install all secondary themes", true);
330  themes.setFont(fnt);
331  themes.setForeground(fg);
332  c.gridy++;
333  lm.setConstraints(themes, c);
334  scr.add(themes);
335 
336  JCheckBox appIcon = new JCheckBox("Install desktop icon", true);
337  appIcon.setFont(fnt);
338  appIcon.setForeground(fg);
339  c.gridy++;
340  lm.setConstraints(appIcon, c);
341  scr.add(appIcon);
342 
343  progress = new JLabel("Installation progress: Unpacking");
344  progress.setFont(fnt);
345  progress.setForeground(fg);
346  progress.setVisible(false);
347  c.gridx = 0;
348  c.gridy++;
349  c.gridwidth = 3;
350  c.insets = new Insets(24, 12, 0, 12);
351  c.anchor = GridBagConstraints.WEST;
352  lm.setConstraints(progress, c);
353  scr.add(progress);
354 
355  fnt = (Font) conf.get("progressbar", "font");
356  fg = (Color) conf.get("progressbar", "fgcolor");
357  setupBar = new JProgressBar(0, 100);
358  setupBar.setStringPainted(true);
359  setupBar.setFont(fnt);
360  setupBar.setForeground(fg);
361  setupBar.setVisible(false);
362  c.gridy++;
363  c.weightx = 1;
364  c.insets.top = 12;
365  c.fill = GridBagConstraints.HORIZONTAL;
366  lm.setConstraints(setupBar, c);
367  scr.add(setupBar);
368 
369  l = new JLabel();
370  c.gridy++;
371  c.weighty = 1;
372  c.fill = GridBagConstraints.BOTH;
373  lm.setConstraints(l, c);
374  scr.add(l);
375  break;
376  }
377 
378  screens.add(scr);
379  }
380 
381 
385  private void showScreen()
386  {
387  System.out.println("Current stage: " + current);
388  Registry conf = Registry.getCurrent();
389 
390  viewport.removeAll();
391  viewport.add(screens.get(current), BorderLayout.CENTER);
392  viewport.repaint();
393  viewport.validate();
394 
395  switch (current) {
396  case 0:
397  String pkg = (String) conf.get("installed", "package");
398  caption.setText("Installing " + pkg);
399 
400  previous.setEnabled(false);
401  break;
402 
403  case 1:
404  String license = (String) conf.get("installed", "license");
405  caption.setText(license);
406 
407  previous.setEnabled(true);
408  next.setText("Next");
409  next.setActionCommand("Next");
410  next.setMnemonic(KeyEvent.VK_N);
411  break;
412 
413  case 2:
414  caption.setText("Select options");
415 
416  next.setText("Install");
417  next.setActionCommand("Install");
418  next.setMnemonic(KeyEvent.VK_I);
419  }
420  }
421 
422 
423  public static void extractJar(File jar, File dir, JProgressBar bar) throws IOException
424  {
425  if (dir == null) {
426  String path = System.getProperty("java.io.tmpdir");
427  dir = new File(path, ".jTracer.installer");
428  }
429 
430  try {
431  boolean autodel = false;
432  dir.mkdir();
433  if (jar == null) {
434  autodel = true;
435  dir.deleteOnExit();
436  jar = new File(System.getProperty("java.class.path"));
437  }
438 
439  JarInputStream in = new JarInputStream(new FileInputStream(jar));
440  ZipEntry entry;
441 
442  float bytes = 0, sz = jar.length();
443  while ((entry = in.getNextEntry()) != null) {
444  File from = new File(entry.getName());
445  File to = new File(dir, entry.getName());
446 
447  if (entry.isDirectory()) {
448  String parts[] = entry.getName().split("/"); //File.separator);
449  File subdir = new File(dir, "");
450 
451  for (int i = 0; i < parts.length; i++) {
452  subdir = new File(subdir, parts[i]);
453  System.out.println(parts[i]);
454  subdir.mkdir();
455 
456  bytes += to.length();
457  if (bar != null)
458  bar.setValue((int) ((bytes / sz) * 100));
459 
460  if (autodel)
461  subdir.deleteOnExit();
462  }
463 
464  System.out.println(subdir.getAbsolutePath());
465  continue;
466  }
467 
468  System.out.println(from.getAbsolutePath() + " -> " + to.getAbsolutePath());
469  /*String parent = from.getParent();
470  if (parent != null) {
471  String parts[] = parent.split(File.separator);
472  File subdir = new File(dir, "");
473 
474  for (int i = 0; i < parts.length; i++) {
475  subdir = new File(subdir, parts[i]);
476  //System.out.println(subdir.getAbsolutePath());
477  subdir.mkdir();
478  if (autodel)
479  subdir.deleteOnExit();
480  }
481  }*/
482 
483  to.createNewFile();
484  if (autodel)
485  to.deleteOnExit();
486 
487  /*if (bar != null)
488  bar.setMaximum((int) to.length());*/
489 
490  DataOutputStream out = new DataOutputStream(new FileOutputStream(to));
491  while (in.available() == 1) {
492  //byte[] data = new byte[1];
493  int data = in.read();
494  if (data == -1)
495  break;
496  out.writeByte(data);
497 
498  bytes++;
499  if (bar != null)
500  bar.setValue((int) ((bytes / sz) * 100));
501  }
502 
503  out.close();
504  }
505 
506  if (!Registry.isLinux() && bar != null)
507  bar.setValue(100);
508  in.close();
509  }
510 
511  catch(Throwable t) {
512  Registry.debug(t);
513  }
514  }
515 
516 
522  public static void main(String[] argv)
523  {
524  try {
525  if (Registry.isLinux())
526  System.out.println("Linux");
527  else
528  System.out.println("Windows");
529 
530  Registry conf = new Registry();
531  conf.setup();
532 
533  extractJar(null, null, null);
534  MainFrame app = new MainFrame();
535  File lockf = conf.getResource("var/.lock");
536  FileOutputStream fs = new FileOutputStream(lockf);
537 
538  app.lock = fs.getChannel().tryLock();
539  if (app.lock == null) {
540  String nm = (String) conf.get("generic", "name");
541  Alert.error(null, nm + " is already running", true);
542  }
543 
544  lockf.deleteOnExit();
545  UIManager.setLookAndFeel((String) conf.get("generic", "lnf"));
546  app.setVisible(true);
547  }
548 
549  catch (Throwable t) {
550  Registry.debug(t);
551  System.exit(1);
552  }
553  }
554 
555 
584  public void run()
585  {
586  //while (installer == Thread.currentThread()) {
587  try {
588  Registry conf = Registry.getCurrent();
589  File pkg = conf.getResource("config/package.jar");
590  File dest = new File(home.getText());
591  dest.mkdirs();
592 
593  extractJar(pkg, dest, setupBar);
594  progress.setText("Installation progress: Configuring");
595  File exec = new File(dest, "jTracer-1.03.jar");
596  exec.setExecutable(true, false);
597 
598  if (Registry.isLinux()) {
599  File theme = new File(dest, "res/theme/default");
600  File link = new File(dest, "res/theme/current");
601  Files.createSymbolicLink(link.toPath(), theme.toPath());
602 
603  File launcher = new File(prefix.getText() + "/bin/jTracer");
604  launcher.createNewFile();
605  launcher.setExecutable(true, false);
606  FileWriter out = new FileWriter(launcher);
607  out.write("#!/bin/bash\n\n");
608  out.write("java -jar " + exec.getAbsolutePath() + " &\n");
609  out.close();
610  }
611 
612  progress.setText("Installation progress: Complete");
613  System.out.println("finished");
614  }
615 
616  catch (Throwable t) {
617  getToolkit().beep();
618  Registry.debug(t);
619  }
620 
621  next.setEnabled(true);
622  next.setText("Finish");
623  next.setActionCommand("Finish");
624  next.setMnemonic(KeyEvent.VK_F);
625  //}
626  }
627 
628 
634  public void actionPerformed(ActionEvent event)
635  {
636  try {
637  String cmd = event.getActionCommand();
638 
639  if (cmd.equals("Cancel")) {
640  Registry conf = Registry.getCurrent();
641 
642  String pkg = (String) conf.get("installed", "package");
643  String msg = "Really cancel the installation of " + pkg + "?";
644 
645  if (Alert.prompt(this, msg))
646  System.exit(0);
647  }
648 
649  else if (cmd.equals("Previous")) {
650  if (current == 0)
651  return;
652 
653  current--;
654  showScreen();
655  }
656 
657  else if (cmd.equals("Next")) {
658  if (current == screens.size() - 1)
659  return;
660 
661  current++;
662  showScreen();
663  }
664 
665  else if (cmd.equals("Select")) {
666  JFileChooser chooser = new JFileChooser();
667  chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
668 
669  int retval = chooser.showDialog(this, "Select");
670  if (retval == JFileChooser.APPROVE_OPTION)
671  prefix.setText(chooser.getSelectedFile().getPath());
672  }
673 
674  else if (cmd.equals("Install")) {
675  progress.setVisible(true);
676  setupBar.setVisible(true);
677 
678  next.setEnabled(false);
679  previous.setEnabled(false);
680  select.setEnabled(false);
681  prefix.setEnabled(false);
682 
683  setupBar.setValue(0);
684  installer = new Thread(this);
685  installer.start();
686  }
687 
688  else if (cmd.equals("Finish"))
689  System.exit(0);
690 
691  else if (cmd.startsWith("About")) {
692  if (about == null)
693  about = new AboutDialog(this);
694 
695  about.setLocationRelativeTo(this);
696  about.setVisible(true);
697  }
698  }
699 
700  catch (Throwable t) {
701  Registry.debug(t);
702  }
703  }
704 
705 
711  public void hyperlinkUpdate(HyperlinkEvent event)
712  {
713  try {
714  if (event.getEventType() != HyperlinkEvent.EventType.ACTIVATED)
715  return;
716 
717  URL url = event.getURL();
718  String proto = url.getProtocol();
719  Registry conf = Registry.getCurrent();
720 
721  if (proto.equals("file")) {
722  if (about != null)
723  about.setVisible(false);
724  }
725 
726  else if (proto.equals("mailto"))
727  conf.mail(url);
728 
729  else if (proto.equals("http"))
730  conf.browse(url);
731  }
732 
733  catch (Throwable t) {
734  Registry.debug(t);
735  }
736  }
737 }
738 
void run()
/ public void spawn() { if (EventQueue.isDispatchThread()) { return; }
Definition: MainFrame.java:584
void actionPerformed(ActionEvent event)
Handler for action events fired from the wizard control buttons.
Definition: MainFrame.java:634
int current
Current screen index.
Definition: MainFrame.java:95
JLabel caption
Wizard screen caption.
Definition: MainFrame.java:72
void hyperlinkUpdate(HyperlinkEvent event)
Handler for hyperlink events.
Definition: MainFrame.java:711
Object get(String section, String key)
Get an entry.
Definition: Registry.java:106
A dialog that shows an HTML page with project information (version, short description, license, copyright e.t.c) and links to various online project resources.
static void extractJar(File jar, File dir, JProgressBar bar)
Definition: MainFrame.java:423
JPanel createCaption()
Create the wizard screen caption.
Definition: MainFrame.java:146
void showScreen()
Update the viewport with the current wizard screen.
Definition: MainFrame.java:385
FileLock lock
Unique installer lock.
Definition: MainFrame.java:98
Button previous
Wizard control buttons.
Definition: MainFrame.java:81
JPanel createControls()
Create the wizard control buttons.
Definition: MainFrame.java:175
Vector< Image > getProjectIcons()
Get a cross-platform set of project icons.
Definition: Registry.java:238
void mail(URL url)
Open a URL on the registered mail composer.
Definition: Registry.java:197
static File getHomeDirectory()
Get the user home directory.
Definition: Registry.java:278
TextField home
Installation path fields.
Definition: MainFrame.java:84
Custom icon-text button with configurable styles.
Definition: Button.java:18
static void main(String[] argv)
Process entry point.
Definition: MainFrame.java:522
User alert or simple prompt dialog with configurable styles.
Definition: Alert.java:29
static boolean prompt(JFrame owner, String msg)
Show an alert prompting the user to make a choice.
Definition: Alert.java:198
Vector< JPanel > screens
Wizard screen enumeration.
Definition: MainFrame.java:92
void createScreen(int i)
Create a wizard screen.
Definition: MainFrame.java:226
JLabel progress
Installation progress indicator.
Definition: MainFrame.java:75
static final long serialVersionUID
Class version.
Definition: MainFrame.java:69
Main application window frame and process entry point.
Definition: MainFrame.java:63
JProgressBar setupBar
Installation progress bar.
Definition: MainFrame.java:87
Thread installer
Installer thread.
Definition: MainFrame.java:101
JPanel viewport
Content viewport.
Definition: MainFrame.java:78