1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package ffx.ui;
39
40 import ffx.potential.parsers.KeyFileFilter;
41 import ffx.potential.parsers.KeyFilter;
42 import ffx.ui.commands.DTDResolver;
43 import ffx.utilities.Keyword;
44 import java.awt.BorderLayout;
45 import java.awt.FlowLayout;
46 import java.awt.Font;
47 import java.awt.GridBagConstraints;
48 import java.awt.GridBagLayout;
49 import java.awt.Insets;
50 import java.awt.event.ActionEvent;
51 import java.awt.event.ActionListener;
52 import java.io.*;
53 import java.net.URL;
54 import java.util.ArrayList;
55 import java.util.Hashtable;
56 import java.util.Iterator;
57 import java.util.LinkedHashMap;
58 import java.util.Vector;
59 import java.util.logging.Level;
60 import java.util.logging.Logger;
61 import java.util.prefs.Preferences;
62 import javax.annotation.Nullable;
63 import javax.swing.BorderFactory;
64 import javax.swing.ImageIcon;
65 import javax.swing.JButton;
66 import javax.swing.JCheckBoxMenuItem;
67 import javax.swing.JComboBox;
68 import javax.swing.JFileChooser;
69 import javax.swing.JLabel;
70 import javax.swing.JOptionPane;
71 import javax.swing.JPanel;
72 import javax.swing.JScrollPane;
73 import javax.swing.JSplitPane;
74 import javax.swing.JTextArea;
75 import javax.swing.JToolBar;
76 import javax.swing.border.Border;
77 import javax.swing.border.EtchedBorder;
78 import javax.xml.parsers.DocumentBuilder;
79 import javax.xml.parsers.DocumentBuilderFactory;
80 import javax.xml.parsers.ParserConfigurationException;
81 import org.apache.commons.configuration2.CompositeConfiguration;
82 import org.apache.commons.configuration2.Configuration;
83 import org.apache.commons.configuration2.PropertiesConfiguration;
84 import org.w3c.dom.Document;
85 import org.w3c.dom.Element;
86 import org.w3c.dom.Node;
87 import org.w3c.dom.NodeList;
88 import org.xml.sax.SAXException;
89
90
91
92
93
94
95 public final class KeywordPanel extends JPanel implements ActionListener {
96
97 @Serial
98 private static final long serialVersionUID = 1L;
99
100 private static final Logger logger = Logger.getLogger(KeywordPanel.class.getName());
101 private static final Preferences preferences = Preferences.userNodeForPackage(KeywordPanel.class);
102
103 private final MainPanel mainPanel;
104
105 private final JLabel statusLabel = new JLabel(" ");
106 private final GridBagLayout gridBagLayout = new GridBagLayout();
107 private final GridBagConstraints gridBagConstraints = new GridBagConstraints();
108
109 private final JPanel gridPanel = new JPanel(gridBagLayout);
110
111 private final JLabel noSystemLabel =
112 new JLabel("Keywords for the active system are edited here. ");
113
114 private final JLabel noKeywordLabel = new JLabel("Keyword desciptions are displayed here.");
115 private final JPanel noKeywordPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 5));
116 private final FlowLayout flowLayout = new FlowLayout(FlowLayout.LEFT, 5, 5);
117 private final BorderLayout borderLayout = new BorderLayout();
118
119 private boolean fileOpen = false;
120
121 private Hashtable<String, Keyword> currentKeys;
122
123 private File currentKeyFile;
124
125 private FFXSystem currentSystem;
126
127 private LinkedHashMap<String, KeywordComponent> keywordHashMap;
128
129 private LinkedHashMap<String, String> groupHashMap;
130
131 private JComboBox<String> groupComboBox;
132
133 private JPanel editPanel;
134
135 private JToolBar toolBar;
136
137 private JSplitPane splitPane;
138
139 private JScrollPane editScrollPane;
140
141 private JScrollPane descriptScrollPane;
142
143 private JTextArea descriptTextArea;
144
145 private JCheckBoxMenuItem descriptCheckBox;
146
147
148
149
150 private StringBuilder commentStringBuffer = new StringBuilder();
151
152 private JTextArea flatfileTextArea;
153
154 private String[] paramNames = null;
155 private LinkedHashMap<String, String> paramHashtable = null;
156
157
158
159
160
161
162 KeywordPanel(MainPanel f) {
163 super();
164 mainPanel = f;
165 initialize();
166 }
167
168
169
170
171
172
173 @Override
174 public void actionPerformed(ActionEvent evt) {
175 String arg = evt.getActionCommand();
176 switch (arg) {
177 case "Open...":
178 keyOpen();
179 break;
180 case "Close":
181 keyClose();
182 break;
183 case "Save":
184 keySave(currentKeyFile);
185 break;
186 case "Save As...":
187 keySaveAs();
188 break;
189 case "Description":
190 JCheckBoxMenuItem box = (JCheckBoxMenuItem) evt.getSource();
191 setDivider(box.isSelected());
192 break;
193 }
194 if (evt.getSource() instanceof JComboBox) {
195 loadKeywordGroup();
196 }
197 }
198
199
200
201
202
203
204
205 public String getKeyword(String key) {
206 if (key == null) {
207 return null;
208 }
209 synchronized (this) {
210 KeywordComponent keyword = keywordHashMap.get(key.toUpperCase());
211 if (keyword == null) {
212 return null;
213 }
214 return keyword.toString();
215 }
216 }
217
218
219
220
221
222
223
224 public String getKeywordDescription(String key) {
225 if (key == null) {
226 return null;
227 }
228 synchronized (this) {
229 KeywordComponent keyword = keywordHashMap.get(key.toUpperCase());
230 if (keyword == null) {
231 return null;
232 }
233 return keyword.getKeywordDescription();
234 }
235 }
236
237
238
239
240
241
242
243 public String getKeywordValue(String key) {
244 if (key == null) {
245 return null;
246 }
247 synchronized (this) {
248 KeywordComponent keyword = keywordHashMap.get(key.toUpperCase());
249 if (keyword == null) {
250 return null;
251 }
252 String value = keyword.toString().trim();
253 int firstSpace = value.indexOf(" ");
254 if (firstSpace < 1) {
255 return value;
256 }
257 return value.substring(firstSpace, value.length());
258 }
259 }
260
261
262
263
264
265
266
267 public String getParamPath(String key) {
268 return paramHashtable.get(key);
269 }
270
271
272
273
274
275
276
277 public boolean isKeyword(String key) {
278 synchronized (this) {
279 KeywordComponent keyword = keywordHashMap.get(key.toUpperCase());
280 return keyword != null;
281 }
282 }
283
284
285 public void selected() {
286 setDivider(descriptCheckBox.isSelected());
287 validate();
288 repaint();
289 }
290
291
292
293
294
295
296 public void setKeywordGroup(String keygroup) {
297 synchronized (this) {
298 keygroup = groupHashMap.get(keygroup.toUpperCase());
299 if (keygroup == null) {
300 return;
301 }
302 if (!groupComboBox.getSelectedItem().equals(keygroup)) {
303 groupComboBox.setSelectedItem(keygroup);
304 loadKeywordGroup();
305 }
306 }
307 }
308
309
310
311
312
313
314
315
316
317
318 public void setKeywordValue(String key, String value) {
319 synchronized (this) {
320 KeywordComponent keyword = keywordHashMap.get(key.toUpperCase());
321 if (keyword == null) {
322 return;
323 }
324 keyword.loadKeywordEntry(value);
325 String keygroup = keyword.getKeywordGroup();
326 if (!groupComboBox.getSelectedItem().equals(keygroup)) {
327 groupComboBox.setSelectedItem(keygroup);
328 loadKeywordGroup();
329 }
330 mainPanel.setPanel(MainPanel.KEYWORDS);
331 }
332 }
333
334
335
336
337
338
339 public void store(FFXSystem sys) {
340 synchronized (this) {
341 FFXSystem back = currentSystem;
342 currentSystem = sys;
343 storeActive();
344 currentSystem = back;
345 }
346 }
347
348
349 @Override
350 public String toString() {
351 return "Keyword Editor";
352 }
353
354
355
356
357
358
359 String[] getParamFiles() {
360 return paramNames;
361 }
362
363 private void initialize() {
364
365 loadXML();
366
367 flatfileTextArea = new JTextArea();
368 flatfileTextArea.setEditable(false);
369 flatfileTextArea.setFont(Font.decode("monospaced plain 12"));
370 Insets insets = flatfileTextArea.getInsets();
371 insets.set(5, 5, 5, 5);
372 flatfileTextArea.setMargin(insets);
373
374 editPanel = new JPanel(flowLayout);
375 ClassLoader loader = getClass().getClassLoader();
376 ImageIcon icKeyPanel = new ImageIcon(loader.getResource("ffx/ui/icons/page_key.png"));
377 noSystemLabel.setIcon(icKeyPanel);
378 ImageIcon icon = new ImageIcon(loader.getResource("ffx/ui/icons/information.png"));
379 noKeywordLabel.setIcon(icon);
380 noKeywordPanel.add(noKeywordLabel);
381 editScrollPane =
382 new JScrollPane(
383 editPanel,
384 JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
385 JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
386 descriptScrollPane =
387 new JScrollPane(
388 descriptTextArea,
389 JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
390 JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
391 Border eb = BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
392 descriptScrollPane.setBorder(eb);
393
394 splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, editScrollPane, descriptScrollPane);
395 splitPane.setResizeWeight(1.0);
396 splitPane.setOneTouchExpandable(true);
397 statusLabel.setBorder(eb);
398
399 setLayout(new BorderLayout());
400 add(splitPane, BorderLayout.CENTER);
401 add(statusLabel, BorderLayout.SOUTH);
402
403 gridBagConstraints.gridx = 0;
404 gridBagConstraints.gridy = 0;
405 gridBagConstraints.anchor = GridBagConstraints.WEST;
406 gridBagConstraints.gridheight = 1;
407 gridBagConstraints.gridwidth = 1;
408 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
409 initToolBar();
410 add(toolBar, BorderLayout.NORTH);
411 setParamPath();
412 loadPrefs();
413 loadKeywordGroup();
414 }
415
416
417 private void initToolBar() {
418 toolBar = new JToolBar("Keyword Editor");
419 toolBar.setLayout(flowLayout);
420 ClassLoader loader = getClass().getClassLoader();
421 JButton jbopen = new JButton(new ImageIcon(loader.getResource("ffx/ui/icons/folder_page.png")));
422 jbopen.setActionCommand("Open...");
423 jbopen.setToolTipText("Open a *.KEY File for Editing");
424 jbopen.addActionListener(this);
425 Insets insets = jbopen.getInsets();
426 insets.top = 2;
427 insets.bottom = 2;
428 insets.left = 2;
429 insets.right = 2;
430 jbopen.setMargin(insets);
431
432 JButton jbsave = new JButton(new ImageIcon(loader.getResource("ffx/ui/icons/disk.png")));
433 jbsave.setActionCommand("Save");
434 jbsave.setToolTipText("Save the Active *.KEY File");
435 jbsave.addActionListener(this);
436 jbsave.setMargin(insets);
437 toolBar.add(jbsave);
438 JButton jbsaveas = new JButton(new ImageIcon(loader.getResource("ffx/ui/icons/page_save.png")));
439 jbsaveas.setActionCommand("Save As...");
440 jbsaveas.setToolTipText("Save the Active *.KEY File Under a New Name");
441 jbsaveas.addActionListener(this);
442 jbsaveas.setMargin(insets);
443 toolBar.add(jbsaveas);
444 JButton jbclose = new JButton(new ImageIcon(loader.getResource("ffx/ui/icons/cancel.png")));
445 jbclose.setActionCommand("Close");
446 jbclose.setToolTipText("Close the Active *.KEY File");
447 jbclose.addActionListener(this);
448 jbclose.setMargin(insets);
449
450 toolBar.addSeparator();
451 groupComboBox.setMaximumSize(groupComboBox.getPreferredSize());
452 groupComboBox.addActionListener(this);
453 groupComboBox.setEditable(false);
454 toolBar.add(groupComboBox);
455 toolBar.addSeparator();
456 ImageIcon icinfo = new ImageIcon(loader.getResource("ffx/ui/icons/information.png"));
457 descriptCheckBox = new JCheckBoxMenuItem(icinfo);
458 descriptCheckBox.setActionCommand("Description");
459 descriptCheckBox.setToolTipText("Show/Hide Keyword Descriptions");
460 descriptCheckBox.addActionListener(this);
461 descriptCheckBox.setMargin(insets);
462 toolBar.add(descriptCheckBox);
463 toolBar.add(new JLabel(""));
464 toolBar.setBorderPainted(false);
465 toolBar.setFloatable(false);
466 toolBar.setRollover(true);
467 toolBar.setOrientation(JToolBar.HORIZONTAL);
468 }
469
470
471
472
473
474
475 boolean isFileOpen() {
476 return fileOpen;
477 }
478
479
480 private void keyClear() {
481 synchronized (this) {
482
483 for (KeywordComponent kw : keywordHashMap.values()) {
484 kw.clearKeywordComponent();
485 }
486 KeywordComponent.setKeywordModified(false);
487
488 fileOpen = false;
489 currentKeys = null;
490 currentSystem = null;
491 currentKeyFile = null;
492
493 commentStringBuffer = new StringBuilder();
494 statusLabel.setText(" ");
495 loadKeywordGroup();
496 }
497 }
498
499
500
501
502
503
504 private boolean keyClose() {
505 if (KeywordComponent.isKeywordModified()) {
506 return false;
507 }
508 keyClear();
509 return true;
510 }
511
512
513 private void keyOpen() {
514 if (fileOpen && KeywordComponent.isKeywordModified()) {
515 int option =
516 JOptionPane.showConfirmDialog(
517 this,
518 "Save Changes First",
519 "Opening New File",
520 JOptionPane.YES_NO_CANCEL_OPTION,
521 JOptionPane.INFORMATION_MESSAGE);
522 if (option == JOptionPane.CANCEL_OPTION) {
523 return;
524 } else if (option == JOptionPane.YES_OPTION) {
525 keySave(currentKeyFile);
526 }
527 keyClear();
528 }
529 JFileChooser d = MainPanel.resetFileChooser();
530 if (currentSystem != null) {
531 File cwd = currentSystem.getFile();
532 if (cwd != null && cwd.getParentFile() != null) {
533 d.setCurrentDirectory(cwd.getParentFile());
534 }
535 }
536 d.setAcceptAllFileFilterUsed(false);
537 d.setFileFilter(MainPanel.keyFileFilter);
538 d.setDialogTitle("Open KEY File");
539 int result = d.showOpenDialog(this);
540 if (result == JFileChooser.APPROVE_OPTION) {
541 File newKeyFile = d.getSelectedFile();
542 if (newKeyFile != null && newKeyFile.exists() && newKeyFile.canRead()) {
543 keyOpen(newKeyFile);
544 }
545 }
546 }
547
548
549
550
551
552
553
554 private boolean keyOpen(@Nullable File newKeyFile) {
555 if (newKeyFile != null && newKeyFile.exists() && newKeyFile.canRead()) {
556 Hashtable<String, Keyword> newKeys = KeyFilter.open(newKeyFile);
557 if (newKeys != null && !newKeys.isEmpty()) {
558 if (currentSystem != null) {
559 currentSystem.setKeyFile(currentKeyFile);
560 currentSystem.setKeywords(currentKeys);
561 }
562 loadActive(currentSystem, newKeys, newKeyFile);
563 return true;
564 }
565 }
566 return false;
567 }
568
569
570
571
572
573
574 void keySave(File f) {
575 if (f != null) {
576 currentKeyFile = f;
577 }
578 if (!fileOpen || currentKeyFile == null) {
579 return;
580 }
581 storeActive();
582 saveKeywords(currentKeyFile, keywordHashMap, commentStringBuffer);
583 }
584
585
586 private void keySaveAs() {
587 if (!fileOpen) {
588 return;
589 }
590 JFileChooser d = MainPanel.resetFileChooser();
591 d.setDialogTitle("Save KEY File");
592 d.setAcceptAllFileFilterUsed(false);
593 if (currentKeyFile != null) {
594 d.setCurrentDirectory(currentKeyFile.getParentFile());
595 d.setSelectedFile(currentKeyFile);
596 }
597 d.setFileFilter(new KeyFileFilter());
598 int result = d.showSaveDialog(this);
599 if (result == JFileChooser.APPROVE_OPTION) {
600 currentKeyFile = d.getSelectedFile();
601 keySave(currentKeyFile);
602 }
603 }
604
605
606
607
608
609
610
611 boolean loadActive(FFXSystem newSystem) {
612 synchronized (this) {
613 if (newSystem == null) {
614 keyClear();
615 return false;
616 }
617 configToKeywords(newSystem);
618 File newKeyFile = newSystem.getKeyFile();
619 if (newKeyFile != null) {
620
621 }
622 Hashtable<String, Keyword> newKeys = newSystem.getKeywords();
623 if (newKeyFile == null && newKeys == null) {
624 logger.info(String.format("Loaded %s with no keywords.", newSystem));
625 return false;
626 }
627
628
629 return loadActive(newSystem, newKeys, newKeyFile);
630 }
631 }
632
633 private void configToKeywords(FFXSystem newSystem) {
634
635 CompositeConfiguration properties = newSystem.getProperties();
636 Hashtable<String, Keyword> keywordHash = new Hashtable<>();
637
638
639 Keyword keyword = new Keyword("COMMENTS");
640 keywordHash.put("COMMENTS", keyword);
641
642
643 Configuration config = properties.getConfiguration(0);
644 if (config instanceof PropertiesConfiguration) {
645 PropertiesConfiguration prop = (PropertiesConfiguration) config;
646 Iterator<String> keys = prop.getKeys();
647 while (keys.hasNext()) {
648 String key = keys.next();
649 if (keywordHash.contains(key)) {
650 keyword = keywordHash.get(key);
651 keyword.append(prop.getStringArray(key));
652 } else {
653 String[] values = prop.getStringArray(key);
654 keyword = new Keyword(key, values);
655 keywordHash.put(key, keyword);
656 }
657 }
658 }
659
660 newSystem.setKeywords(keywordHash);
661 }
662
663
664
665
666
667
668
669
670
671 private boolean loadActive(
672 FFXSystem newSystem, @Nullable Hashtable<String, Keyword> newKeys, File newKeyFile) {
673
674 synchronized (this) {
675
676 if (currentKeys != null && KeywordComponent.isKeywordModified()) {
677 if (currentSystem != null && currentSystem != newSystem) {
678 storeActive();
679 } else {
680 saveChanges();
681 }
682 }
683
684 keyClear();
685
686 if (newKeys == null || newKeys.isEmpty()) {
687 return false;
688 }
689 currentSystem = newSystem;
690 currentKeyFile = newKeyFile;
691 currentKeys = newKeys;
692 fileOpen = true;
693
694
695
696
697
698
699 ArrayList<String> keysToRemove = new ArrayList<>();
700 Keyword comments = currentKeys.get("COMMENTS");
701 for (Keyword keyword : currentKeys.values()) {
702 String label = keyword.getKeyword();
703 Vector<String> data = keyword.getEntries();
704 if (label.equals("COMMENTS")) {
705 continue;
706 }
707 KeywordComponent tk = keywordHashMap.get(label.toUpperCase());
708
709
710 if (tk == null) {
711 keysToRemove.add(keyword.getKeyword());
712 if (data.isEmpty()) {
713 comments.append(label);
714 } else if (label.equalsIgnoreCase("MULTIPOLE")) {
715 int count = 5;
716 for (String entry : data) {
717 count++;
718 if (count > 5) {
719 comments.append(label + " " + entry);
720 count = 1;
721 } else {
722 comments.append(entry);
723 }
724 }
725 } else if (label.equalsIgnoreCase("TORTORS")) {
726 int points = 0;
727 int count = 0;
728 for (String entry : data) {
729 count++;
730 if (count > points) {
731 String[] res = entry.split(" +");
732 int xres = Integer.parseInt(res[5]);
733 int yres = Integer.parseInt(res[5]);
734 points = xres * yres;
735 comments.append(label + " " + entry);
736 count = 0;
737 } else {
738 comments.append(entry);
739 }
740 }
741 } else {
742 for (String entry : data) {
743 comments.append(label + " " + entry);
744 }
745 }
746 continue;
747 }
748
749
750 if (data.isEmpty()) {
751 tk.loadKeywordEntry(label);
752 }
753
754
755 for (String s : data) {
756 tk.loadKeywordEntry(s);
757 }
758 }
759
760 Vector<String> entries = comments.getEntries();
761 if (entries != null) {
762 for (String s : entries) {
763 if (s.length() > 1) {
764 if (!groupHashMap.containsKey(s.substring(1).toUpperCase().trim())) {
765 commentStringBuffer.append(s).append("\n");
766 }
767 } else {
768 commentStringBuffer.append(s).append("\n");
769 }
770 }
771 }
772
773 for (String k : keysToRemove) {
774 currentKeys.remove(k);
775 }
776 if (currentSystem != null) {
777 currentSystem.setKeywords(currentKeys);
778 currentSystem.setKeyFile(currentKeyFile);
779 }
780 loadKeywordGroup();
781 return true;
782 }
783 }
784
785 private void loadKeywordGroup() {
786 synchronized (this) {
787 editPanel.removeAll();
788 String selectedGroup = (String) groupComboBox.getSelectedItem();
789 if (currentKeys == null) {
790 editPanel.setLayout(flowLayout);
791 editPanel.add(noSystemLabel);
792 int temp = splitPane.getDividerLocation();
793 splitPane.setBottomComponent(noKeywordPanel);
794 splitPane.setDividerLocation(temp);
795 } else if (selectedGroup.equalsIgnoreCase("Flat File View")) {
796 editPanel.setLayout(borderLayout);
797 publishKeywords();
798 editPanel.add(flatfileTextArea, BorderLayout.CENTER);
799 int temp = splitPane.getDividerLocation();
800 splitPane.setBottomComponent(noKeywordPanel);
801 splitPane.setDividerLocation(temp);
802 } else if (selectedGroup.equalsIgnoreCase("Active Keywords")) {
803 gridPanel.removeAll();
804 gridBagConstraints.gridy = 0;
805 gridBagConstraints.anchor = GridBagConstraints.WEST;
806 gridBagConstraints.gridheight = 1;
807 gridBagConstraints.gridwidth = 1;
808 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
809 for (KeywordComponent keywordComponent : keywordHashMap.values()) {
810 if (keywordComponent.isActive()) {
811 JPanel jptemp = keywordComponent.getKeywordGUI();
812 gridBagLayout.setConstraints(jptemp, gridBagConstraints);
813 gridPanel.add(jptemp);
814 gridBagConstraints.gridy++;
815 }
816 }
817 KeywordComponent.fillPanel(gridPanel, gridBagLayout, gridBagConstraints);
818 editPanel.setLayout(flowLayout);
819 editPanel.add(gridPanel);
820 int temp = splitPane.getDividerLocation();
821 splitPane.setBottomComponent(descriptScrollPane);
822 splitPane.setDividerLocation(temp);
823 } else {
824 gridPanel.removeAll();
825 gridBagConstraints.gridy = 0;
826 gridBagConstraints.gridx = 0;
827 gridBagConstraints.anchor = GridBagConstraints.WEST;
828 gridBagConstraints.gridheight = 1;
829 gridBagConstraints.gridwidth = 1;
830 gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
831 for (KeywordComponent keywordComponent : keywordHashMap.values()) {
832 if (keywordComponent.getKeywordGroup().equalsIgnoreCase(selectedGroup)) {
833 JPanel jptemp = keywordComponent.getKeywordGUI();
834 gridBagLayout.setConstraints(jptemp, gridBagConstraints);
835 gridPanel.add(jptemp);
836 gridBagConstraints.gridy++;
837 }
838 }
839 KeywordComponent.fillPanel(gridPanel, gridBagLayout, gridBagConstraints);
840 editPanel.setLayout(flowLayout);
841 editPanel.add(gridPanel);
842 int temp = splitPane.getDividerLocation();
843 splitPane.setBottomComponent(descriptScrollPane);
844 splitPane.setDividerLocation(temp);
845 }
846 if (currentKeyFile != null) {
847 statusLabel.setText(" " + currentKeyFile);
848 } else {
849 statusLabel.setText(" ");
850 }
851 editScrollPane.validate();
852 editScrollPane.repaint();
853 }
854 }
855
856
857 private void loadPrefs() {
858 String c = KeywordPanel.class.getName();
859 descriptCheckBox.setSelected(!preferences.getBoolean(c + ".description", true));
860 descriptCheckBox.doClick();
861 }
862
863
864 private void loadXML() {
865 NodeList groups, keywords, values;
866 Element group, keyword, value;
867 String groupName;
868 String keywordName, keywordDescription, keywordGUI;
869 groups = null;
870 try {
871
872 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
873 DocumentBuilder db = dbf.newDocumentBuilder();
874 db.setEntityResolver(new DTDResolver());
875 URL keyURL = getClass().getClassLoader().getResource("ffx/ui/commands/keywords.xml");
876 Document doc = db.parse(keyURL.openStream());
877 Element document = doc.getDocumentElement();
878 Element body = (Element) document.getElementsByTagName("body").item(0);
879 groups = body.getElementsByTagName("section");
880 } catch (ParserConfigurationException | SAXException | IOException e) {
881 logger.warning(e.toString());
882 }
883 keywordHashMap = new LinkedHashMap<>();
884 groupHashMap = new LinkedHashMap<>();
885 groupHashMap.put("ACTIVE KEYWORDS", "Active Keywords");
886 groupHashMap.put("FLAT FILE VIEW", "Flat File View");
887 groupComboBox = new JComboBox<>();
888 groupComboBox.addItem("Active Keywords");
889 groupComboBox.addItem("Flat File View");
890 descriptTextArea = new JTextArea();
891 descriptTextArea.setLineWrap(true);
892 descriptTextArea.setWrapStyleWord(true);
893 Insets insets = descriptTextArea.getInsets();
894 insets.set(5, 5, 5, 5);
895 descriptTextArea.setMargin(insets);
896 int length = groups.getLength();
897
898 for (int i = 0; i < length; i++) {
899 group = (Element) groups.item(i);
900 groupName = group.getAttribute("name");
901 groupComboBox.addItem(groupName);
902 keywords = group.getElementsByTagName("subsection");
903 int klength = keywords.getLength();
904 for (int j = 0; j < klength; j++) {
905 keyword = (Element) keywords.item(j);
906 keywordName = keyword.getAttribute("name");
907 Node text = keyword.getFirstChild();
908 keywordDescription = text.getNodeValue().replace('\n', ' ');
909 keywordDescription = keywordDescription.replaceAll(" +", " ");
910 keywordGUI = keyword.getAttribute("rep");
911 KeywordComponent.SwingRepresentation type;
912 try {
913 type = KeywordComponent.SwingRepresentation.valueOf(keywordGUI.toUpperCase());
914 } catch (Exception e) {
915 type = null;
916 logger.log(
917 Level.WARNING, "{0}: Unknown GUI Component - {1}", new Object[] {keywordName, type});
918 System.exit(-1);
919 }
920 KeywordComponent key;
921 if (type == KeywordComponent.SwingRepresentation.CHECKBOXES
922 || type == KeywordComponent.SwingRepresentation.COMBOBOX) {
923 values = keyword.getElementsByTagName("Value");
924 String[] labels = new String[values.getLength()];
925 for (int k = 0; k < values.getLength(); k++) {
926 value = (Element) values.item(k);
927 labels[k] = value.getAttribute("name");
928 }
929 key =
930 new KeywordComponent(
931 keywordName, groupName, type, keywordDescription, descriptTextArea, labels);
932 } else {
933 key =
934 new KeywordComponent(
935 keywordName, groupName, type, keywordDescription, descriptTextArea);
936 }
937 keywordHashMap.put(keywordName.toUpperCase(), key);
938 groupHashMap.put(groupName.toUpperCase(), groupName);
939 }
940 }
941 groupComboBox.setSelectedIndex(0);
942 }
943
944
945 private void publishKeywords() {
946 synchronized (this) {
947 flatfileTextArea.setText("");
948 boolean writegroup = false;
949 String pgroup = null;
950
951 for (KeywordComponent keyword : keywordHashMap.values()) {
952 String group = keyword.getKeywordGroup();
953 if (pgroup == null || !group.equalsIgnoreCase(pgroup)) {
954 writegroup = true;
955 pgroup = group;
956 }
957 String line = keyword.toString();
958 if (line != null) {
959 if (writegroup) {
960 flatfileTextArea.append("\n");
961 flatfileTextArea.append("# " + group);
962 flatfileTextArea.append("\n");
963 writegroup = false;
964 }
965 flatfileTextArea.append(line);
966 flatfileTextArea.append("\n");
967 }
968 }
969 flatfileTextArea.append("\n");
970 String s = commentStringBuffer.toString();
971 if (!s.trim().isEmpty()) {
972 flatfileTextArea.append(s.trim());
973 }
974 flatfileTextArea.append("\n");
975 }
976 }
977
978
979
980
981
982
983 boolean saveChanges() {
984 if (KeywordComponent.isKeywordModified() && currentKeyFile != null) {
985 keySave(currentKeyFile);
986 return true;
987 }
988 return false;
989 }
990
991
992
993
994
995
996
997
998
999 private boolean saveKeywords(
1000 File keyFile,
1001 LinkedHashMap<String, KeywordComponent> keywordHashMap,
1002 StringBuilder comments) {
1003 synchronized (this) {
1004 FileWriter fw = null;
1005 BufferedWriter bw = null;
1006 try {
1007 fw = new FileWriter(keyFile);
1008 bw = new BufferedWriter(fw);
1009 boolean writegroup = false;
1010 String pgroup = null;
1011
1012 for (KeywordComponent keyword : keywordHashMap.values()) {
1013 String group = keyword.getKeywordGroup();
1014 if (pgroup == null || !group.equalsIgnoreCase(pgroup)) {
1015 writegroup = true;
1016 pgroup = group;
1017 }
1018 String line = keyword.toString();
1019 if (line != null) {
1020 if (writegroup) {
1021 bw.newLine();
1022 bw.write("# " + group);
1023 bw.newLine();
1024 writegroup = false;
1025 }
1026 bw.write(line);
1027 bw.newLine();
1028 }
1029 }
1030 bw.newLine();
1031 String s = comments.toString();
1032 if (s != null && !s.trim().isEmpty()) {
1033 bw.write(s.trim());
1034 }
1035 bw.newLine();
1036 bw.flush();
1037 KeywordComponent.setKeywordModified(false);
1038 } catch (IOException e) {
1039 logger.warning(e.toString());
1040 return false;
1041 } finally {
1042 try {
1043 if (bw != null) {
1044 bw.close();
1045 }
1046 if (fw != null) {
1047 fw.close();
1048 }
1049 } catch (Exception e) {
1050 logger.warning(e.toString());
1051 }
1052 }
1053 return true;
1054 }
1055 }
1056
1057
1058 void savePrefs() {
1059 String c = KeywordPanel.class.getName();
1060 preferences.putInt(c + ".divider", splitPane.getDividerLocation());
1061 preferences.putBoolean(c + ".description", descriptCheckBox.isSelected());
1062 }
1063
1064
1065
1066
1067
1068
1069 private void setDivider(boolean b) {
1070 if (b) {
1071 descriptCheckBox.setSelected(b);
1072 int spDivider = (int) (this.getHeight() * (3.0f / 5.0f));
1073 splitPane.setDividerLocation(spDivider);
1074 } else {
1075 splitPane.setDividerLocation(1.0);
1076 }
1077 }
1078
1079
1080 private void setParamPath() {
1081
1082 File paramDir = new File(MainPanel.ffxDir.getAbsolutePath() + File.separator + "params");
1083 if (paramDir.exists()) {
1084 File[] paramFiles = paramDir.listFiles();
1085 paramHashtable = new LinkedHashMap<>();
1086 for (File f : paramFiles) {
1087 if (f.exists() && f.canRead() && MainPanel.forceFieldFileFilter.accept(f)) {
1088 paramHashtable.put(f.getName(), f.getAbsolutePath());
1089 }
1090 }
1091 int num = paramHashtable.size();
1092 paramNames = new String[num + 1];
1093 int i = 1;
1094 for (String name : paramHashtable.keySet()) {
1095 paramNames[i] = name;
1096 i++;
1097 }
1098 paramNames[0] = "AAA";
1099 java.util.Arrays.sort(paramNames);
1100 paramNames[0] = "Use an existing TINKER Key file".intern();
1101 }
1102 }
1103
1104
1105 private void storeActive() {
1106 synchronized (this) {
1107 if (currentSystem == null) {
1108 return;
1109 }
1110
1111 if (!KeywordComponent.isKeywordModified()) {
1112 return;
1113 }
1114 Hashtable<String, Keyword> currentKeys = currentSystem.getKeywords();
1115 Hashtable<String, Keyword> newKeys = new Hashtable<String, Keyword>();
1116 for (KeywordComponent kc : keywordHashMap.values()) {
1117 if (kc.isActive()) {
1118 Keyword keywordData = null;
1119 if (currentKeys != null) {
1120 keywordData = currentKeys.get(kc.getKeyword());
1121 }
1122 if (keywordData == null) {
1123 keywordData = new Keyword(kc.getKeyword());
1124 } else {
1125 keywordData.clear();
1126 }
1127 kc.getKeywordData(keywordData);
1128 newKeys.put(kc.getKeyword(), keywordData);
1129 }
1130 }
1131 Keyword comments = new Keyword("COMMENTS", commentStringBuffer.toString());
1132 newKeys.put("COMMENTS", comments);
1133 currentSystem.setKeywords(newKeys);
1134 }
1135 }
1136 }