1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package com.ochafik.lang.jnaerator.studio;
20
21 import java.awt.BorderLayout;
22 import java.awt.Component;
23 import java.awt.Dimension;
24 import java.awt.GridLayout;
25 import java.awt.event.ActionEvent;
26 import java.awt.event.ActionListener;
27 import java.awt.event.InputEvent;
28 import java.awt.event.ItemEvent;
29 import java.awt.event.ItemListener;
30 import java.awt.event.KeyEvent;
31 import java.awt.event.MouseAdapter;
32 import java.awt.event.MouseEvent;
33 import java.awt.event.MouseWheelEvent;
34 import java.awt.event.MouseWheelListener;
35 import java.awt.event.WindowAdapter;
36 import java.awt.event.WindowEvent;
37 import java.io.File;
38 import java.io.IOException;
39 import java.io.PrintStream;
40 import java.io.PrintWriter;
41 import java.io.StringWriter;
42 import java.net.URL;
43 import java.util.ArrayList;
44 import java.util.prefs.Preferences;
45
46 import javax.swing.AbstractAction;
47 import javax.swing.Action;
48 import javax.swing.BorderFactory;
49 import javax.swing.Box;
50 import javax.swing.JButton;
51 import javax.swing.JCheckBox;
52 import javax.swing.JComboBox;
53 import javax.swing.JComponent;
54 import javax.swing.JFrame;
55 import javax.swing.JLabel;
56 import javax.swing.JOptionPane;
57 import javax.swing.JPanel;
58 import javax.swing.JProgressBar;
59 import javax.swing.JScrollPane;
60 import javax.swing.JSplitPane;
61 import javax.swing.JTabbedPane;
62 import javax.swing.JTextArea;
63 import javax.swing.JTextField;
64 import javax.swing.JToolBar;
65 import javax.swing.JTree;
66 import javax.swing.SwingUtilities;
67 import javax.swing.UIManager;
68 import javax.swing.event.DocumentEvent;
69 import javax.swing.event.TreeSelectionEvent;
70 import javax.swing.event.TreeSelectionListener;
71 import javax.swing.tree.TreePath;
72
73 import com.ochafik.io.JTextAreaOutputStream;
74 import com.ochafik.io.ReadText;
75 import com.ochafik.io.WriteText;
76 import com.ochafik.lang.SyntaxUtils;
77 import com.ochafik.lang.compiler.MemoryFileManager;
78 import com.ochafik.lang.jnaerator.ClassOutputter;
79 import com.ochafik.lang.jnaerator.JNAerator;
80 import com.ochafik.lang.jnaerator.JNAeratorCommandLineArgs;
81 import com.ochafik.lang.jnaerator.JNAeratorConfig;
82 import com.ochafik.lang.jnaerator.Result;
83 import com.ochafik.lang.jnaerator.SourceFiles;
84 import com.ochafik.lang.jnaerator.JNAerator.Feedback;
85 import com.ochafik.swing.SimpleDocumentAdapter;
86 import com.ochafik.swing.UndoRedoUtils;
87 import com.ochafik.swing.syntaxcoloring.CCTokenMarker;
88 import com.ochafik.swing.syntaxcoloring.JEditTextArea;
89 import com.ochafik.swing.syntaxcoloring.JavaTokenMarker;
90 import com.ochafik.swing.syntaxcoloring.TokenMarker;
91 import com.ochafik.util.SystemUtils;
92 import com.ochafik.util.listenable.ListenableCollections;
93 import com.ochafik.util.listenable.ListenableComboModel;
94 import com.ochafik.util.listenable.ListenableList;
95
96
97
98
99
100 @SuppressWarnings("serial")
101 public class JNAeratorStudio extends JPanel {
102 private static final long serialVersionUID = -6061806156049213635L;
103 private static final String PREF_RADIX = "JNAeratorStudio.";
104 JEditTextArea sourceArea = textArea(new JavaTokenMarker());
105 JEditTextArea resultArea = textArea(new CCTokenMarker());
106 JTextField libraryName = new JTextField("test");
107 JLabel classCountLabel = new JLabel("JNAerated class :");
108
109 JComboBox resultsListCombo = new JComboBox();
110 JCheckBox directCallingCb = new JCheckBox("Direct Calling (experimental)", false),
111 structsAsTopLevelClassesCb = new JCheckBox("Structs as Top-Level classes", true),
112 noCommentNoManglingCb = new JCheckBox("No comment & no mangling", false);
113
114 JTextArea errorsArea = new JTextArea();
115 JSplitPane sp;
116 ListenableList<ResultContent> results = ListenableCollections.listenableList(new ArrayList<ResultContent>());
117 MemoryFileManager memoryFileManager;
118 static MouseWheelListener mouseWheelListener = new MouseWheelListener() {
119
120 @Override
121 public void mouseWheelMoved(MouseWheelEvent e) {
122 JEditTextArea ta = SyntaxUtils.as(e.getSource(), JEditTextArea.class);
123 if (ta == null)
124 return;
125
126 int line = ta.getFirstLine();
127 if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {
128 int u = e.getUnitsToScroll();
129 line += u > 0 ? 1 : -1;
130 if (line < 0)
131 line = 0;
132 else if (line >= ta.getLineCount())
133 line = ta.getLineCount() - 1;
134
135 ta.setFirstLine(line);
136 }
137 }
138
139 };
140 public void error(String title, String message, Throwable th) {
141 error(this, title, message, th);
142 }
143 public static void error(Component parent, String title, String message, Throwable th) {
144 StringWriter sw = new StringWriter();
145 th.printStackTrace(new PrintWriter(sw));
146 JScrollPane jsp = new JScrollPane(new JTextArea(sw.toString())) {
147 public Dimension getMaximumSize() {
148 return new Dimension(500, 500);
149 };
150 };
151
152 JOptionPane.showMessageDialog(
153 parent,
154 new Object[] {
155 message,
156 jsp
157 },
158 title == null ? "JNAerator Error" : title,
159 -1
160 );
161 }
162 public File getDir(String name) {
163 File dir = new File(getDir(), name);
164 dir.mkdirs();
165 return dir;
166 }
167 public File getDir() {
168 File dir = new File(System.getProperty("user.home"));
169 dir = new File(dir, ".jnaeratorStudio");
170 dir = new File(dir, "pad");
171 dir.mkdirs();
172 return dir;
173 }
174 public File getInputFile() {
175 return new File(getDir(), "input.h");
176 }
177 public File getOutputJarFile() {
178 String lib = libraryName.getText().trim();
179 if (lib.length() == 0)
180 lib = "out";
181 return new File(getDir(), lib + ".jar");
182 }
183 void save() throws IOException {
184 WriteText.writeText(sourceArea.getText(), getInputFile());
185 }
186 static JEditTextArea textArea(TokenMarker marker) {
187 JEditTextArea ta = new JEditTextArea() {
188 private static final long serialVersionUID = 1L;
189
190
191
192 @Override
193 public void processKeyEvent(KeyEvent evt) {
194 if (SystemUtils.isMacOSX()) {
195 int m = evt.getModifiers();
196 if ((m & InputEvent.META_MASK) != 0) {
197 m = (m & ~InputEvent.META_MASK) | InputEvent.CTRL_MASK;
198 evt = new KeyEvent(evt.getComponent(), evt.getID(), evt.getWhen(), m, evt.getKeyCode(), evt.getKeyChar(), evt.getKeyLocation());
199 if (evt.getID() == KeyEvent.KEY_TYPED)
200 return;
201 }
202 }
203
204 super.processKeyEvent(evt);
205 }
206 @Override
207 public Dimension getMinimumSize() {
208 return new Dimension(100, 100);
209 }
210 };
211 ta.setBorder(BorderFactory.createLoweredBevelBorder());
212 ta.setFocusTraversalKeysEnabled(false);
213 ta.addMouseWheelListener(mouseWheelListener);
214 ta.setPreferredSize(new Dimension(200, 300));
215 ta.setTokenMarker(marker);
216 return ta;
217 }
218
219
220 public void close() {
221 try {
222 save();
223 } catch (Exception ex) {
224 error(null, "Error while closing", ex);
225 }
226 }
227 JTabbedPane sourceTabs = new JTabbedPane(JTabbedPane.TOP), resultTabs = new JTabbedPane(JTabbedPane.TOP);
228
229
230 void switchOrientation() {
231 boolean hor = sp.getOrientation() == JSplitPane.HORIZONTAL_SPLIT;
232 int l = sp.getDividerLocation(), d = hor ? sp.getWidth() : sp.getHeight();
233 sp.setOrientation(hor ? JSplitPane.VERTICAL_SPLIT : JSplitPane.HORIZONTAL_SPLIT);
234 if (d != 0)
235 sp.setDividerLocation(l / (double)d);
236 }
237
238 Action
239 switchOrientationAction = new AbstractAction("Switch Orientation") {
240 @Override
241 public void actionPerformed(ActionEvent e) {
242 switchOrientation();
243 }
244 },
245 generateAction = new AbstractAction("JNAerate !") {
246 @Override
247 public void actionPerformed(ActionEvent e) {
248 generate();
249 generateButton.requestFocus();
250 }
251 },
252 aboutJNAeratorAction = new AbstractAction("About JNAerator") {
253 @Override
254 public void actionPerformed(ActionEvent e) {
255 try {
256 URL url = new URL("http://code.google.com/p/jnaerator/wiki/AboutJNAerator");
257 System.out.println("About JNAerator: " + url);
258 SystemUtils.runSystemOpenURL(url);
259 } catch (Exception ex) {
260 error(null, "Error while opening about page", ex);
261 }
262 }
263 },
264 aboutJNAAction = new AbstractAction("About JNA") {
265 @Override
266 public void actionPerformed(ActionEvent e) {
267 try {
268 URL url = new URL("http://jna.dev.java.net/");
269 System.out.println("About JNA: " + url);
270 SystemUtils.runSystemOpenURL(url);
271 } catch (Exception ex) {
272 error(null, "Error while opening about page", ex);
273 }
274 }
275 },
276 showExampleAction = new AbstractAction("Open Example") {
277 @Override
278 public void actionPerformed(ActionEvent e) {
279 if (sourceArea.getText().trim().length() > 0) {
280 if (JOptionPane.showConfirmDialog(JNAeratorStudio.this, "This is going to overwrite the contents of your source text area.\nProceed ?", "Open Example", JOptionPane.OK_CANCEL_OPTION) != JOptionPane.OK_OPTION) {
281 return;
282 }
283 doShowExample(true);
284 }
285 }
286 }
287 ;
288 Object lastJNAeratedArtifact;
289
290 JButton showJarButton;
291 JPanel errorsPane = new JPanel(new BorderLayout());
292 JProgressBar statusBar = new JProgressBar();
293 private JButton generateButton;
294 public JNAeratorStudio() {
295 super(new BorderLayout());
296 resultsListCombo.setModel(new ListenableComboModel<ResultContent>(results));
297
298
299
300
301 JToolBar tb = new JToolBar();
302 generateButton = tb.add(generateAction);
303 tb.add(showExampleAction);
304 tb.add(switchOrientationAction);
305 tb.add(aboutJNAeratorAction);
306 tb.add(aboutJNAAction);
307
308 add("North", tb);
309
310 sourceArea.getDocument().addDocumentListener(new SimpleDocumentAdapter() {
311
312 @Override
313 public void updated(DocumentEvent e) {
314 setReadyToJNAerate();
315 }
316
317 });
318
319 add("South", statusBar);
320
321
322
323 JComponent sourcePane = new JPanel(new BorderLayout()), resultPane = new JPanel(new BorderLayout());
324 Box libBox = Box.createHorizontalBox();
325 showJarButton = new JButton("Show JAR");
326 showJarButton.setEnabled(false);
327 showJarButton.addActionListener(new ActionListener() {
328 @Override
329 public void actionPerformed(ActionEvent e) {
330 if (lastJNAeratedArtifact == null || !(lastJNAeratedArtifact instanceof File))
331 return;
332
333 File file = (File)lastJNAeratedArtifact;
334 try {
335 if (file.isDirectory())
336 SystemUtils.runSystemOpenDirectory(file);
337 else
338 SystemUtils.runSystemOpenFileParent(file);
339 } catch (Exception e1) {
340 showJarButton.setEnabled(false);
341 showJarButton.setToolTipText(e1.toString());
342 }
343 }
344 });
345 statusBar.addMouseListener(new MouseAdapter() {
346 @Override
347 public void mouseClicked(MouseEvent e) {
348 if (lastJNAeratedArtifact != null && lastJNAeratedArtifact instanceof Throwable)
349 error(null, null, (Throwable)lastJNAeratedArtifact);
350 else
351 generateAction.actionPerformed(null);
352 }
353 });
354 libBox.add(new JLabel("Library Name :", JLabel.RIGHT));
355 libBox.add(libraryName);
356
357
358 Box optBox = Box.createVerticalBox();
359 optBox.add(libBox);
360
361 JPanel optPanel = new JPanel(new GridLayout(2, 2));
362 optPanel.add(directCallingCb);
363 optPanel.add(noCommentNoManglingCb);
364 optPanel.add(structsAsTopLevelClassesCb);
365
366 optBox.add(optPanel);
367 for (Component c : optBox.getComponents())
368 ((JComponent)c).setAlignmentX(0);
369
370 sourcePane.add("North", optBox);
371 sourcePane.add("Center", sourceArea);
372 sourceTabs.addTab("Source", sourcePane);
373
374
375 Box resChoiceBox = Box.createHorizontalBox();
376 resChoiceBox.add(classCountLabel);
377 resChoiceBox.add(resultsListCombo);
378 resChoiceBox.add(showJarButton);
379
380 resultPane.add("North", resChoiceBox);
381 resultPane.add("Center", resultArea);
382 sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, sourceTabs, resultTabs);
383 sp.setOneTouchExpandable(true);
384 sp.setResizeWeight(0.5);
385
386
387 errorsPane.add("Center", new JScrollPane(errorsArea));
388
389 resultTabs.add("JNAeration Results", resultPane);
390 resultTabs.add("Logs", errorsPane);
391 add("Center", sp);
392
393
394 resultsListCombo.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) {
395 ResultContent c = (ResultContent)resultsListCombo.getSelectedItem();
396 resultArea.setText(c == null ? "" : c.getContent());
397 resultArea.scrollTo(0, 0);
398 }});
399
400 try {
401 sourceArea.setText(ReadText.readText(getInputFile()));
402 sourceArea.scrollTo(0, 0);
403 } catch (Exception ex) {}
404
405 if (sourceArea.getText().trim().length() == 0)
406 doShowExample(false);
407
408 UndoRedoUtils.registerNewUndoManager(sourceArea, sourceArea.getDocument());
409 }
410 void setReadyToJNAerate() {
411 statusBar.setToolTipText("Click to JNAerate !");
412 statusBar.setMaximum(1);
413 statusBar.setMinimum(0);
414 statusBar.setValue(0);
415 statusBar.setStringPainted(true);
416 statusBar.setString("Ready to JNAerate");
417 statusBar.setIndeterminate(false);
418 }
419
420 private void doShowExample(boolean generate) {
421
422 try {
423 sourceArea.setText(ReadText.readText(getClass().getClassLoader().getResourceAsStream("com/ochafik/lang/jnaerator/examples/example.h")));
424 sourceArea.scrollTo(0, 0);
425 if (generate)
426 generate();
427 } catch (Exception e1) {
428 e1.printStackTrace();
429 }
430 }
431
432
433
434
435
436
437 protected void generate() {
438
439 try {
440 save();
441 } catch (IOException e1) {
442 error(null, "Error while saving file", e1);
443 return;
444 }
445 JNAeratorStudio.this.setEnabled(false);
446 errorsArea.setText("");
447 results.clear();
448 resultArea.setText("");
449 generateAction.setEnabled(false);
450 showJarButton.setEnabled(false);
451 showJarButton.setToolTipText(null);
452 statusBar.setIndeterminate(true);
453 statusBar.setToolTipText("JNAerating...");
454 lastJNAeratedArtifact = null;
455
456 new Thread() {
457 public void run() {
458 JNAeratorConfig config = new JNAeratorConfig();
459 config.outputJar = getOutputJarFile();
460 config.compile = true;
461 config.useJNADirectCalls = directCallingCb.isSelected();
462 config.putTopStructsInSeparateFiles = structsAsTopLevelClassesCb.isSelected();
463 config.noComments = config.noMangling = noCommentNoManglingCb.isSelected();
464 config.defaultLibrary = libraryName.getText();
465 config.libraryForElementsInNullFile = libraryName.getText();
466
467 config.preprocessorConfig.includeStrings.add(sourceArea.getText());
468 config.genCPlusPlus = config.genCPlusPlus || sourceArea.getText().contains("//@" + JNAeratorCommandLineArgs.OptionDef.CPlusPlusGen.clSwitch);
469 config.cacheDir = getDir("cache");
470
471 final PrintStream out = System.out;
472 final PrintStream err = System.err;
473 JTextAreaOutputStream to = new JTextAreaOutputStream(errorsArea);
474 PrintStream pto = new PrintStream(to);
475 System.setOut(pto);
476 System.setErr(pto);
477
478 Feedback feedback = new Feedback() {
479
480 @Override
481 public void setStatus(final String string) {
482 SwingUtilities.invokeLater(new Runnable() { public void run() {
483 statusBar.setString(string);
484 statusBar.setToolTipText(string);
485 }});
486 }
487
488 @Override
489 public void setFinished(final File toOpen) {
490 lastJNAeratedArtifact = toOpen;
491 SwingUtilities.invokeLater(new Runnable() { public void run() {
492 statusBar.setToolTipText("Click to re-JNAerate !");
493 statusBar.setString("JNAeration completed");
494 showJarButton.setEnabled(true);
495 showJarButton.setToolTipText(toOpen.getAbsolutePath());
496 statusBar.setValue(statusBar.getMaximum());
497 statusBar.setIndeterminate(false);
498 }});
499 }
500
501 @Override
502 public void setFinished(Throwable e) {
503 statusBar.setToolTipText("Click to examine the JNAeration error report");
504 lastJNAeratedArtifact = e;
505 setStatus("JNAeration failed : " + e.toString());
506 statusBar.setValue(statusBar.getMinimum());
507 statusBar.setIndeterminate(false);
508 error(null, null, e);
509 }
510 @Override
511 public void wrappersGenerated(final Result result) {
512 SwingUtilities.invokeLater(new Runnable() { public void run() {
513 if (resultsListCombo.getItemCount() > 0)
514 resultsListCombo.setSelectedIndex(0);
515 }});
516 }
517 @Override
518 public void sourcesParsed(SourceFiles sourceFiles) {
519 final SourceFiles sourceFilesClone = sourceFiles;
520 SwingUtilities.invokeLater(new Runnable() { public void run() {
521 String title = "Parsing Tree";
522 for (int i = sourceTabs.getTabCount(); i-- != 0;) {
523 if (title.equals(sourceTabs.getTitleAt(i))) {
524 sourceTabs.removeTabAt(i);
525 break;
526 }
527 }
528
529 final JTree parsedTree = new JTree(new ElementNode(null, "ROOT", sourceFilesClone));
530 final JEditTextArea selectionContent = textArea(new CCTokenMarker());
531
532 parsedTree.addTreeSelectionListener(new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) {
533 TreePath selectionPath = parsedTree.getSelectionPath();
534 AbstractNode c = selectionPath == null ? null : (AbstractNode)selectionPath.getLastPathComponent();
535 selectionContent.setText(c == null ? "" : c.getContent());
536 selectionContent.scrollTo(0, 0);
537 }});
538 JPanel parsePane = new JPanel(new BorderLayout());
539 parsePane.add("West", new JScrollPane(parsedTree));
540 parsePane.add("Center", selectionContent);
541
542 sourceTabs.addTab(title, parsePane);
543 }});
544 }
545 };
546 try {
547 new JNAerator(config) {
548 public PrintWriter getClassSourceWriter(final ClassOutputter outputter, final String className) throws IOException {
549 ResultContent c = new ResultContent(className) {
550 protected void closed() {
551 try {
552 PrintWriter w = outputter.getClassSourceWriter(className);
553 w.write(this.getContent());
554 w.close();
555 } catch (Exception ex) {
556 ex.printStackTrace();
557 }
558 };
559 };
560 results.add(c);
561 return c.getPrintWriter();
562 };
563 }.jnaerate(feedback);
564 } finally {
565 SwingUtilities.invokeLater(new Runnable() { public void run() {
566 generateAction.setEnabled(true);
567 sourceArea.scrollTo(0, 0);
568 JNAeratorStudio.this.setEnabled(true);
569 System.setOut(out);
570 System.setErr(err);
571 classCountLabel.setText("JNAerated classes (" + results.size() + ") :");
572 setTabTitle(resultTabs, errorsPane, "Logs (" + (errorsArea.getLineCount() - 1) + " lines)");
573
574 }});
575 }
576 }
577 }.start();
578 }
579
580 public static class SyntaxException extends Exception {
581 public SyntaxException(String message) {
582 super(message);
583 }
584 }
585
586
587
588
589 private static void setTabTitle(JTabbedPane tabs, Component c, String string) {
590 for (int i = tabs.getTabCount(); i-- != 0;) {
591 Component tc = tabs.getComponent(i);
592 if (tc == c) {
593 tabs.setTitleAt(i, string);
594 return;
595 }
596
597 }
598 }
599
600 static Preferences prefNode() {
601 return Preferences.userNodeForPackage(JNAeratorStudio.class);
602 }
603 public static String getPref(String name, String defaultValue) {
604 return prefNode().get(JNAeratorStudio.PREF_RADIX + name, defaultValue);
605 }
606 public static void setPref(String name, String value) {
607 prefNode().put(JNAeratorStudio.PREF_RADIX + name, value);
608 }
609 public static void setPref(String name, boolean value) {
610 prefNode().putBoolean(JNAeratorStudio.PREF_RADIX + name, value);
611 }
612 public static boolean getPref(String name, boolean defaultValue) {
613 return prefNode().getBoolean(JNAeratorStudio.PREF_RADIX + name, defaultValue);
614 }
615 public static void setPref(String name, double value) {
616 prefNode().putDouble(JNAeratorStudio.PREF_RADIX + name, value);
617 }
618 public static double getPref(String name, double defaultValue) {
619 return prefNode().getDouble(JNAeratorStudio.PREF_RADIX + name, defaultValue);
620 }
621 public static void setPref(String name, int value) {
622 prefNode().putInt(JNAeratorStudio.PREF_RADIX + name, value);
623 }
624 public static int getPref(String name, int defaultValue) {
625 return prefNode().getInt(JNAeratorStudio.PREF_RADIX + name, defaultValue);
626 }
627
628 public static void main(String[] args) {
629 String[] prefArgs = JNAerator.getJNAeratorArgsFromPref();
630 if (args.length > 0 || prefArgs != null)
631 {
632 String[] nargs = null;
633 if (prefArgs != null)
634 nargs = new String[0];
635 else if (args.length == 1) {
636 nargs = new String[] {"@", args[0], "-gui"};
637 } else if (args.length == 2 && args[0].equals("-open")) {
638 nargs = new String[] {"@", args[1], "-gui"};
639 }
640 if (nargs != null) {
641 JNAerator.main(nargs);
642 return;
643 }
644 }
645 try {
646 System.setProperty("apple.laf.useScreenMenuBar", "true");
647 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
648 } catch(Exception e) {
649 System.out.println("Error setting native LAF: " + e);
650 }
651
652 String ver = "";
653 try {
654 ver = " " + ReadText.readText(JNAeratorStudio.class.getClassLoader().getResourceAsStream("VERSION"));
655 } catch (Exception ex) {}
656
657 final JFrame f = new JFrame((JNAeratorStudio.class.getSimpleName() + ver).trim());
658 final JNAeratorStudio js = new JNAeratorStudio();
659 f.getContentPane().add("Center", js);
660
661
662 try {
663 js.libraryName.setText(getPref("options.libraryName", "test"));
664 js.directCallingCb.setSelected(getPref("options.direct", false));
665 js.structsAsTopLevelClassesCb.setSelected(getPref("options.topLevelStructs", true));
666 js.noCommentNoManglingCb.setSelected(getPref("options.noCommentNoMangling", false));
667
668 js.sp.setOrientation(getPref("splitPane.orientation", JSplitPane.HORIZONTAL_SPLIT));
669 js.sp.setDividerLocation(getPref("splitPane.dividedLocation", 0.5));
670 f.setSize(getPref("window.width", 800), getPref("height", 600));
671 f.setExtendedState(getPref("window.extendedState", JFrame.NORMAL));
672
673 } catch (Exception ex) {
674 ex.printStackTrace();
675 f.setExtendedState(JFrame.MAXIMIZED_BOTH);
676 f.setSize(800, 800);
677 }
678
679 Runtime.getRuntime().addShutdownHook(new Thread() {
680 public void run() {
681 try {
682 setPref("window.width", f.getWidth());
683 setPref("window.height", f.getHeight());
684 setPref("window.extendedState", f.getExtendedState());
685 setPref("options.libraryName", js.libraryName.getText());
686 setPref("options.direct", js.directCallingCb.isSelected());
687 setPref("options.topLevelStructs", js.structsAsTopLevelClassesCb.isSelected());
688 setPref("options.noCommentNoMangling", js.noCommentNoManglingCb.isSelected());
689 setPref("splitPane.orientation", js.sp.getOrientation());
690 setPref("splitPane.dividedLocation", getProportionalDividerLocation(js.sp));
691 prefNode().flush();
692 } catch (Exception ex) {
693 ex.printStackTrace();
694 }
695 }
696 });
697 f.addWindowListener(new WindowAdapter() {
698 @Override
699 public void windowClosing(WindowEvent e) {
700 System.exit(0);
701 }
702 });
703 Runtime.getRuntime().addShutdownHook(new Thread() { public void run() {
704 js.close();
705 }});
706
707 f.setVisible(true);
708
709 }
710 protected static double getProportionalDividerLocation(JSplitPane sp) {
711 boolean hor = sp.getOrientation() == JSplitPane.HORIZONTAL_SPLIT;
712 int l = sp.getDividerLocation(), d = hor ? sp.getWidth() : sp.getHeight();
713 sp.setOrientation(hor ? JSplitPane.VERTICAL_SPLIT : JSplitPane.HORIZONTAL_SPLIT);
714 return d != 0 ? l / (double)d : 0.5;
715 }
716 }