001    package net.provision.soap;
002    
003    import java.awt.Color;
004    import java.awt.Container;
005    import java.awt.Dimension;
006    import java.awt.FlowLayout;
007    import java.awt.Font;
008    import java.awt.FontMetrics;
009    import java.awt.GridBagConstraints;
010    import java.awt.GridBagLayout;
011    import java.awt.Insets;
012    import java.awt.KeyboardFocusManager;
013    import java.awt.Toolkit;
014    import java.awt.event.*;
015    
016    import java.util.*;
017    
018    import javax.swing.AbstractAction;
019    import javax.swing.Action;
020    import javax.swing.BorderFactory;
021    import javax.swing.ImageIcon;
022    import javax.swing.JButton;
023    import javax.swing.JFrame;
024    import javax.swing.JLabel;
025    import javax.swing.JMenu;
026    import javax.swing.JMenuBar;
027    import javax.swing.JMenuItem;
028    import javax.swing.JOptionPane;
029    import javax.swing.JPanel;
030    import javax.swing.JScrollPane;
031    import javax.swing.JTable;
032    import javax.swing.JTextArea;
033    import javax.swing.JTextField;
034    import javax.swing.JToolBar;
035    import javax.swing.KeyStroke;
036    import javax.swing.ListSelectionModel;
037    import javax.swing.SwingConstants;
038    import javax.swing.UIManager;
039    import javax.swing.border.*;
040    import javax.swing.event.*;
041    import javax.swing.table.*;
042    
043    
044    /**
045     * DOCUMENT ME!
046     *
047     * @author $author$
048     * @version $Revision$
049     */
050    public class SOAPGUI extends JFrame implements ListSelectionListener {
051       public static final Font SUB_TITLE_FONT = new Font("Monospaced", Font.BOLD, 16);
052       public static final Font TITLE_FONT = new Font("Serif", Font.BOLD, 20);
053       public static final Font BUTTON_FONT = new Font("Dialog", Font.BOLD, 16);
054       public static final Font DEFAULT_FONT = new Font("Monospaced", Font.PLAIN, 14);
055       static Border BLACK_LINE_BORDER = BorderFactory.createLineBorder(Color.BLACK);
056       public static Border BUTTON_BORDER = new CompoundBorder(BorderFactory.createLineBorder(
057                Color.BLACK), new EmptyBorder(5, 10, 5, 10));
058       public static Insets TEXT_INS = new Insets(5, 5, 5, 5);
059       private static boolean newEdit;
060       public static int dateButttonX;
061       public static int dateButtonY;
062       public static Color TEXT_BACKGROUND = Color.WHITE;
063       DefaultTableModel tableMDL;
064       FlowLayout buttonLayout = new FlowLayout();
065       JPanel buttonPNL = new JPanel(buttonLayout);
066       TableSorter sorter;
067       private final Border blackLineSpaceBDR;
068       private Action aboutACT;
069       private Action aboutMenuACT;
070       private Action dailyReadingACT;
071       private Action dailyReadingMenuACT;
072       private Action deleteACT;
073       private Action deleteMenuACT;
074       private Action editACT;
075       private Action editMenuACT;
076       private Action exitACT;
077       private Action exitMenuACT;
078       private Action newACT;
079       private Action newMenuACT;
080       private Action prayerLogACT;
081       private Action prayerLogMenuACT;
082       private Color background = new Color(152, 152, 152);
083       private Container c = getContentPane();
084       private DailyItem currentItem;
085       private DateButton dateBTN;
086       private GridBagConstraints gb = new GridBagConstraints();
087       private JButton aboutBTN;
088       private JButton cancelBTN;
089       private JButton dailyReadingBTN;
090       private JButton deleteBTN;
091       private JButton editBTN;
092       private JButton exitBTN;
093       private JButton newBTN;
094       private JButton prayerLogBTN;
095       private JButton saveBTN;
096       private JMenuItem aboutMNI;
097       private JMenuItem dailyReadingMNI;
098       private JMenuItem deleteMNI;
099       private JMenuItem editMNI;
100       private JMenuItem exitMNI;
101       private JMenuItem newEntryMNI;
102       private JMenuItem prayerLogMNI;
103       private JScrollPane applicationSP;
104       private JScrollPane dailyItemsSP;
105       private JScrollPane observationSP;
106       private JScrollPane prayerSP;
107       private JScrollPane scriptureSP;
108       private JTable dailyItemsTBL;
109       private JTextArea applicationTXA;
110       private JTextArea observationTXA;
111       private JTextArea prayerTXA;
112       private JTextArea scriptureTXA;
113       private JTextField titleTXF;
114       private JTextField verseTopicTXF;
115       private ListSelectionModel rowSM;
116       private Storage storage;
117       private Vector dailyItems;
118       private int currentItemLocation;
119       private int selectedRow;
120    
121       public SOAPGUI() {
122          dateBTN = new DateButton(new Date(), this);
123          buttonLayout.setHgap(20);
124    
125          //create components
126          saveBTN = new JButton("Save");
127          cancelBTN = new JButton("Cancel");
128          verseTopicTXF = new JTextField(20);
129          titleTXF = new JTextField("");
130          scriptureTXA = new JTextArea(7, 20);
131          observationTXA = new JTextArea(7, 20);
132          applicationTXA = new JTextArea(7, 20);
133          prayerTXA = new JTextArea(7, 20);
134          scriptureSP = new JScrollPane(scriptureTXA);
135          observationSP = new JScrollPane(observationTXA);
136          applicationSP = new JScrollPane(applicationTXA);
137          prayerSP = new JScrollPane(prayerTXA);
138    
139          JLabel scriptureLBL = new JLabel("<html><font size=5 color=#9D1009>S" +
140                "</font>cripture:</html>");
141          JLabel observationLBL = new JLabel("<html><font size=5 color=#9D1009>" +
142                "O</font>bservation:</html>");
143          JLabel applicationLBL = new JLabel("<html><font size=5 color=#9D1009>" +
144                "A</font>pplication</html>:");
145          JLabel prayerLBL = new JLabel("<html><font size=5 color=#9D1009>P" +
146                "</font>rayer</html>:");
147    
148          //borders
149          blackLineSpaceBDR = new CompoundBorder(BorderFactory.createLineBorder(Color.BLACK),
150                new EmptyBorder(0, 5, 0, 5));
151          scriptureSP.setBorder(BLACK_LINE_BORDER);
152          observationSP.setBorder(BLACK_LINE_BORDER);
153          applicationSP.setBorder(BLACK_LINE_BORDER);
154          prayerSP.setBorder(BLACK_LINE_BORDER);
155    
156          //setup components
157          //      scriptureLBL.setBorder(new EmptyBorder(0, 0, 0, 0));
158          //      observationLBL.setBorder(new EmptyBorder(0, 0, 0, 0));
159          //      applicationLBL.setBorder(new EmptyBorder(0, 0, 0, 0));
160          //      prayerLBL.setBorder(new EmptyBorder(0, 0, 0, 0));
161          titleTXF.setFont(TITLE_FONT);
162          verseTopicTXF.setFont(DEFAULT_FONT);
163          scriptureTXA.setFont(DEFAULT_FONT);
164          observationTXA.setFont(DEFAULT_FONT);
165          applicationTXA.setFont(DEFAULT_FONT);
166          scriptureLBL.setFont(SUB_TITLE_FONT);
167          observationLBL.setFont(SUB_TITLE_FONT);
168          applicationLBL.setFont(SUB_TITLE_FONT);
169          prayerLBL.setFont(SUB_TITLE_FONT);
170          prayerTXA.setFont(DEFAULT_FONT);
171    
172          scriptureTXA.setLineWrap(true);
173          observationTXA.setLineWrap(true);
174          applicationTXA.setLineWrap(true);
175          prayerTXA.setLineWrap(true);
176          scriptureTXA.setWrapStyleWord(true);
177          observationTXA.setWrapStyleWord(true);
178          applicationTXA.setWrapStyleWord(true);
179          prayerTXA.setWrapStyleWord(true);
180    
181          titleTXF.setHorizontalAlignment(JTextField.CENTER);
182          scriptureLBL.setVerticalAlignment(SwingConstants.BOTTOM);
183          observationLBL.setVerticalAlignment(SwingConstants.BOTTOM);
184          applicationLBL.setVerticalAlignment(SwingConstants.BOTTOM);
185          prayerLBL.setVerticalAlignment(SwingConstants.BOTTOM);
186    
187          scriptureLBL.setFocusable(false);
188          observationLBL.setFocusable(false);
189          applicationLBL.setFocusable(false);
190          prayerLBL.setFocusable(false);
191    
192          scriptureTXA.setMargin(TEXT_INS);
193          observationTXA.setMargin(TEXT_INS);
194          applicationTXA.setMargin(TEXT_INS);
195          prayerTXA.setMargin(TEXT_INS);
196    
197          saveBTN.setFont(BUTTON_FONT);
198          cancelBTN.setFont(BUTTON_FONT);
199    
200          saveBTN.setBorder(BUTTON_BORDER);
201          cancelBTN.setBorder(BUTTON_BORDER);
202    
203          buttonPNL.add(saveBTN);
204          buttonPNL.add(cancelBTN);
205    
206          createTable();
207    
208          //menu
209          JMenuBar menuBar = new JMenuBar();
210    
211          JMenu fileMNU = new JMenu("File");
212          fileMNU.setMnemonic('F');
213    
214          JMenu viewMNU = new JMenu("View");
215          viewMNU.setMnemonic('V');
216    
217          JMenu helpMNU = new JMenu("Help");
218          helpMNU.setMnemonic('H');
219    
220          newEntryMNI = new JMenuItem("New Entry");
221          editMNI = new JMenuItem("Edit");
222          deleteMNI = new JMenuItem("Delete");
223          exitMNI = new JMenuItem("Exit");
224          aboutMNI = new JMenuItem("About");
225          dailyReadingMNI = new JMenuItem("Daily Reading");
226          prayerLogMNI = new JMenuItem("Prayer Log");
227    
228          menuBar.add(fileMNU);
229          menuBar.add(viewMNU);
230          menuBar.add(helpMNU);
231          fileMNU.add(newEntryMNI);
232          fileMNU.add(editMNI);
233          fileMNU.add(deleteMNI);
234          fileMNU.add(exitMNI);
235          viewMNU.add(dailyReadingMNI);
236    
237          //viewMNU.add(prayerLogMNI);
238          helpMNU.add(aboutMNI);
239    
240          //initialize actions
241          exitACT = new ExitAction("Exit", null, "Exit", new Integer(KeyEvent.VK_X));
242          editACT = new EditAction("Edit", createGeneralIcon("edit22"), "Edit Entry",
243                new Integer(KeyEvent.VK_E));
244          editMenuACT = new EditAction("Edit", createGeneralIcon("edit16"), "Edit Entry",
245                new Integer(KeyEvent.VK_E));
246          newACT = new NewAction("New", createGeneralIcon("new22"), "Create New Entry",
247                new Integer(KeyEvent.VK_N));
248          newMenuACT = new NewAction("New", createGeneralIcon("new16"), "Create New Entry",
249                new Integer(KeyEvent.VK_N));
250          aboutACT = new AboutAction("About", createGeneralIcon("about22"),
251                "Info About This Program", new Integer(KeyEvent.VK_B));
252          aboutMenuACT = new AboutAction("About", createGeneralIcon("about16"),
253                "Info About This Program", new Integer(KeyEvent.VK_B));
254          deleteACT = new DeleteAction("Delete", createGeneralIcon("delete22"),
255                "Delete Entry", new Integer(KeyEvent.VK_D));
256          deleteMenuACT = new DeleteAction("Delete", createGeneralIcon("delete16"),
257                "Delete Entry", new Integer(KeyEvent.VK_D));
258          dailyReadingACT = new DailyReadingAction("Daily Reading",
259                createGeneralIcon("dailyReading22"), "View Daily Readings",
260                new Integer(KeyEvent.VK_R));
261          dailyReadingMenuACT = new DailyReadingAction("Daily Reading",
262                createGeneralIcon("dailyReading16"), "View Daily Readings",
263                new Integer(KeyEvent.VK_R));
264    
265          //      prayerLogACT = new PrayerLogAction("Prayer Log",
266          //            createGeneralIcon("AlignJustify22"), "Prayer Log",
267          //            new Integer(KeyEvent.VK_P));
268          //      prayerLogMenuACT = new PrayerLogAction("Prayer Log",
269          //            createGeneralIcon("AlignJustify16"), "Prayer Log",
270          //            new Integer(KeyEvent.VK_P));
271          //Options.setDefaultIconSize(new Dimension(24,24));
272          exitMNI.setAction(exitMenuACT);
273          editMNI.setAction(editMenuACT);
274          newEntryMNI.setAction(newMenuACT);
275          aboutMNI.setAction(aboutMenuACT);
276          deleteMNI.setAction(deleteMenuACT);
277          dailyReadingMNI.setAction(dailyReadingMenuACT);
278          prayerLogMNI.setAction(prayerLogMenuACT);
279    
280          JToolBar toolBar = new JToolBar();
281          toolBar.setRollover(true);
282          toolBar.setFloatable(false);
283    
284          newBTN = new JButton(newACT);
285          newBTN.setFocusPainted(false);
286          editBTN = new JButton(editACT);
287          editBTN.setFocusPainted(false);
288          dailyReadingBTN = new JButton(dailyReadingACT);
289          dailyReadingBTN.setFocusPainted(false);
290          prayerLogBTN = new JButton(prayerLogACT);
291          prayerLogBTN.setFocusPainted(false);
292          deleteBTN = new JButton(deleteACT);
293          deleteBTN.setFocusPainted(false);
294          aboutBTN = new JButton(aboutACT);
295          aboutBTN.setFocusPainted(false);
296    
297          toolBar.add(newBTN);
298          toolBar.add(editBTN);
299          toolBar.add(dailyReadingBTN);
300    
301          //toolBar.add(prayerLogBTN);
302          toolBar.add(deleteBTN);
303          toolBar.add(aboutBTN);
304    
305          titleTXF.addFocusListener(new FocusListener() {
306                public void focusGained(FocusEvent e) {
307                   titleTXF.selectAll();
308                }
309    
310                public void focusLost(FocusEvent e) {
311                }
312             });
313    
314          saveBTN.addActionListener(new ActionListener() {
315                public void actionPerformed(ActionEvent evt) {
316                   //add DailyItem object to Vector
317                   Date date = dateBTN.getDate();
318                   String verseTopic = verseTopicTXF.getText();
319                   String title = titleTXF.getText();
320                   String scripture = scriptureTXA.getText();
321                   String observation = observationTXA.getText();
322                   String application = applicationTXA.getText();
323                   String prayer = prayerTXA.getText();
324    
325                   DailyItem item = new DailyItem(date, verseTopic, title, scripture,
326                         observation, application, prayer);
327    
328                   if((dailyItems.indexOf(item) != -1) && newEdit) {
329                      JOptionPane.showMessageDialog(SOAPGUI.this,
330                         "Duplicate Record: A new record cannot be \n" +
331                         "added that contains the same date, title, \n" +
332                         "and topic as an existing entry. \n\n" +
333                         "Please change one of these values in order \n" +
334                         "to add the entry.");
335                   } else if(newEdit) {
336                      //add item to vector
337                      dailyItems.add(item);
338    
339                      //add item to row in table
340                      Vector tempVector = new Vector();
341                      tempVector.add(date);
342                      tempVector.add(verseTopic);
343                      tempVector.add(title);
344                      tableMDL.addRow(tempVector);
345    
346                      newEdit = false;
347                      edit(false);
348    
349                      int row = tableMDL.getRowCount() - 1;
350                      rowSM.setSelectionInterval(row, row);
351                   } else {
352                      //update item in vector
353                      dailyItems.setElementAt(item, currentItemLocation);
354    
355                      //update item in table
356                      sorter.setValueAt(date, selectedRow, 0);
357                      sorter.setValueAt(verseTopic, selectedRow, 1);
358                      sorter.setValueAt(title, selectedRow, 2);
359                      sorter.fireTableDataChanged();
360                      edit(false);
361    
362                      //reselect the row the user just edited.
363                      rowSM.setSelectionInterval(selectedRow, selectedRow);
364                   }
365                }
366             });
367    
368          cancelBTN.addActionListener(new ActionListener() {
369                public void actionPerformed(ActionEvent evt) {
370                   edit(false);
371                }
372             });
373    
374          //layout components
375          c.setLayout(new GridBagLayout());
376    
377          //c.setBackground(background);
378          Insets textFieldINS = new Insets(0, 20, 5, 20);
379          Insets labelINS = new Insets(0, 20, 1, 20);
380    
381          gb.gridx = 1;
382          gb.gridy = 3;
383          gb.weightx = 0;
384          gb.insets = new Insets(10, 20, 5, 5); //top, left, bottom, right
385          gb.fill = GridBagConstraints.HORIZONTAL;
386          c.add(new JLabel("Verse / Topic:"), gb);
387    
388          gb.gridx = 2;
389          gb.insets = new Insets(10, 0, 5, 10);
390          gb.weightx = 100;
391          c.add(verseTopicTXF, gb);
392    
393          gb.gridx = 3;
394          gb.insets = new Insets(10, 10, 5, 5);
395          gb.anchor = GridBagConstraints.EAST;
396          gb.weightx = 0;
397          c.add(new JLabel("Date:"), gb);
398    
399          gb.gridx = 4;
400          gb.insets = new Insets(10, 20, 5, 20);
401          gb.fill = GridBagConstraints.NONE;
402          c.add(dateBTN, gb);
403    
404          gb.gridx = 1;
405          gb.gridy = 1;
406          gb.gridwidth = 4;
407          gb.weightx = 100;
408          gb.fill = GridBagConstraints.BOTH;
409          gb.insets = new Insets(0, 0, 0, 0);
410          c.add(toolBar, gb);
411    
412          gb.gridx = 1;
413          gb.gridy = 4;
414          gb.gridwidth = 4;
415          gb.weighty = 0;
416          gb.weightx = 100;
417          gb.anchor = GridBagConstraints.CENTER;
418          gb.fill = GridBagConstraints.BOTH;
419          gb.insets = new Insets(0, 20, 0, 20);
420          c.add(titleTXF, gb);
421    
422          gb.gridy = 5;
423          gb.weighty = 0;
424          gb.insets = labelINS;
425          c.add(scriptureLBL, gb);
426    
427          gb.gridy = 6;
428          gb.weighty = 100;
429          gb.insets = textFieldINS;
430          c.add(scriptureSP, gb);
431    
432          gb.gridy = 7;
433          gb.weighty = 0;
434          gb.insets = labelINS;
435          c.add(observationLBL, gb);
436    
437          gb.gridy = 8;
438          gb.weighty = 100;
439          gb.insets = textFieldINS;
440          c.add(observationSP, gb);
441    
442          gb.gridy = 9;
443          gb.weighty = 0;
444          gb.insets = labelINS;
445          c.add(applicationLBL, gb);
446    
447          gb.gridy = 10;
448          gb.weighty = 100;
449          gb.insets = textFieldINS;
450          c.add(applicationSP, gb);
451    
452          gb.gridy = 11;
453          gb.weighty = 0;
454          gb.insets = labelINS;
455          c.add(prayerLBL, gb);
456    
457          gb.gridy = 12;
458          gb.weighty = 100;
459          gb.insets = new Insets(0, 20, 20, 20);
460          c.add(prayerSP, gb);
461    
462          dailyItemsSP = new JScrollPane(dailyItemsTBL);
463          dailyItemsSP.setBorder(BorderFactory.createEmptyBorder());
464    
465          edit(false);
466    
467          setJMenuBar(menuBar);
468          setTitle("SOAP"); //FIXME: have it also display the version number
469          pack();
470    
471          //insure frame is not larger than screensize and center
472          Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
473          int y = (d.height / 2) - (getHeight() / 2);
474          int toolbarSize = 50; //FIXME: there has got to be a better way, its using the
475    
476          //toolbar size to ensure that the height isn't larger than the toolbar.
477          //This is fine for most peope since they don't grow or move the toolbar. But,
478          //still is a cheap way of handling this.
479          if(getHeight() > (d.height - toolbarSize)) {
480             setSize(getWidth(), d.height - toolbarSize);
481             y = 0;
482          }
483    
484          setLocation((d.width / 2) - (getWidth() / 2), y);
485          setExtendedState(MAXIMIZED_BOTH);
486          setDefaultCloseOperation(EXIT_ON_CLOSE);
487          setVisible(true);
488    
489          addWindowListener(new WindowAdapter() {
490                public void windowClosing(WindowEvent evt) {
491                   try {
492                      //update data in storage and write to file.
493                      storage.setDIData(dailyItems);
494                      storage.writeToFile();
495                   } catch(Exception e) {
496                      JOptionPane.showMessageDialog(SOAPGUI.this,
497                         "Could not " +
498                         "access the database! Make sure the database exists" +
499                         " and has read/write permission.");
500                   }
501                }
502             });
503       } //end of constructor 
504    
505       /**
506        * DOCUMENT ME!
507        */
508       public void createTable() {
509          try {
510             storage = new Storage();
511             dailyItems = storage.getDIData();
512          } catch(Exception e) {
513             JOptionPane.showMessageDialog(this, "Could not access the " + "database!" + e);
514             dailyItems = new Vector();
515          }
516    
517          Vector tableData = new Vector();
518    
519          for(int i = 0; i < dailyItems.size(); i++) {
520             Vector row = new Vector();
521             DailyItem dailyItem = (DailyItem)dailyItems.get(i);
522             row.add(dailyItem.getDate());
523             row.add(dailyItem.getTopic());
524             row.add(dailyItem.getTitle());
525             tableData.add(row);
526          }
527    
528          Vector columnNames = new Vector();
529          columnNames.add("Date");
530          columnNames.add("Scripture/Topic");
531          columnNames.add("Title");
532    
533          tableMDL = new DefaultTableModel(3, 7);
534          tableMDL = new DefaultTableModel(tableData, columnNames) {
535                   public boolean isCellEditable(int row, int column) {
536                      return false;
537                   }
538                };
539          sorter = new TableSorter(tableMDL);
540          dailyItemsTBL = new JTable(sorter) {
541                   // Override this method so that it returns the preferred
542                   // size of the JTable instead of the default fixed size
543                   public Dimension getPreferredScrollableViewportSize() {
544                      return getPreferredSize();
545                   }
546                };
547          sorter.setTableHeader(dailyItemsTBL.getTableHeader());
548          sorter.setSortingStatus(0, TableSorter.DESCENDING);
549          dailyItemsTBL.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
550          dailyItemsTBL.setAlignmentX(JTable.CENTER_ALIGNMENT);
551          dailyItemsTBL.getTableHeader().setReorderingAllowed(false);
552    
553          TableColumnModel colModel = dailyItemsTBL.getColumnModel();
554          FontMetrics fm = getFontMetrics(dailyItemsTBL.getFont());
555          int dateWidth = fm.stringWidth("00/00/000000");
556          colModel.getColumn(0).setMaxWidth(dateWidth);
557          colModel.getColumn(0).setMinWidth(dateWidth);
558          colModel.getColumn(0).setPreferredWidth(dateWidth);
559    
560          //remove border around selected cell
561          UIManager.put("Table.focusCellHighlightBorder", new EmptyBorder(1, 1, 1, 1));
562    
563          //set the formatting for the "Date" column with DateRenderer and center
564          //align all columns
565          DateRenderer dateRenderer = new DateRenderer();
566          dateRenderer.setHorizontalAlignment(SwingConstants.CENTER);
567          dailyItemsTBL.getColumn("Date").setCellRenderer(dateRenderer);
568    
569          DefaultTableCellRenderer dtcr = new DefaultTableCellRenderer();
570          dtcr.setHorizontalAlignment(SwingConstants.CENTER);
571          dailyItemsTBL.getColumn("Scripture/Topic").setCellRenderer(dtcr);
572          dailyItemsTBL.getColumn("Title").setCellRenderer(dtcr);
573    
574          rowSM = dailyItemsTBL.getSelectionModel();
575          rowSM.addListSelectionListener(this);
576    
577          if(dailyItemsTBL.getRowCount() > 0) {
578             rowSM.setSelectionInterval(0, 0);
579          }
580       }
581    
582       /**
583        * DOCUMENT ME!
584        *
585        * @param edit DOCUMENT ME!
586        */
587       public void edit(boolean edit) {
588          Color borderColor = Color.BLACK;
589    
590          if(edit) {
591             //make components editable
592             verseTopicTXF.setEditable(true);
593             titleTXF.setEditable(true);
594             verseTopicTXF.setBorder(blackLineSpaceBDR);
595             titleTXF.setBorder(blackLineSpaceBDR);
596             scriptureTXA.setEditable(true);
597             observationTXA.setEditable(true);
598             applicationTXA.setEditable(true);
599             prayerTXA.setEditable(true);
600             dateBTN.setBorder(BorderFactory.createRaisedBevelBorder());
601             dateBTN.setFocusable(true);
602             dateBTN.setButtonState(true);
603             verseTopicTXF.setBackground(TEXT_BACKGROUND);
604             titleTXF.setBackground(TEXT_BACKGROUND);
605             dateBTN.setBackground(TEXT_BACKGROUND);
606             scriptureTXA.setBackground(TEXT_BACKGROUND);
607             observationTXA.setBackground(TEXT_BACKGROUND);
608             applicationTXA.setBackground(TEXT_BACKGROUND);
609             prayerTXA.setBackground(TEXT_BACKGROUND);
610    
611             //hide/remove
612             c.remove(dailyItemsSP);
613             c.repaint();
614             editMNI.setEnabled(false);
615             newEntryMNI.setEnabled(false);
616             deleteMNI.setEnabled(false);
617             dailyReadingBTN.setEnabled(true);
618             prayerLogBTN.setEnabled(true);
619    
620             //exitMNI.setEnabled(false);
621             editBTN.setEnabled(false);
622             newBTN.setEnabled(false);
623             deleteBTN.setEnabled(false);
624    
625             //display save & cancel buttons
626             gb.gridy = 13;
627             gb.gridx = 1;
628             gb.gridwidth = 4;
629             gb.weighty = 0;
630             gb.weightx = 0;
631             gb.insets = new Insets(10, 20, 10, 20);
632             gb.anchor = GridBagConstraints.CENTER;
633             gb.fill = GridBagConstraints.BOTH;
634             c.add(buttonPNL, gb);
635    
636             //make tab go to next focusable item for textareas and jtable
637             Set forwardTraversalKeys = new TreeSet();
638             forwardTraversalKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
639    
640             Set backwardTraversalKeys = new TreeSet();
641             backwardTraversalKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB,
642                   InputEvent.SHIFT_MASK));
643             scriptureTXA.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
644                forwardTraversalKeys);
645             scriptureTXA.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
646                backwardTraversalKeys);
647             observationTXA.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
648                forwardTraversalKeys);
649             observationTXA.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
650                backwardTraversalKeys);
651             applicationTXA.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
652                forwardTraversalKeys);
653             applicationTXA.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
654                backwardTraversalKeys);
655             prayerTXA.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
656                forwardTraversalKeys);
657             prayerTXA.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
658                backwardTraversalKeys);
659    
660             verseTopicTXF.requestFocus();
661    
662             scriptureTXA.addKeyListener(new TextAreaTab());
663             observationTXA.addKeyListener(new TextAreaTab());
664             applicationTXA.addKeyListener(new TextAreaTab());
665             prayerTXA.addKeyListener(new TextAreaTab());
666          } else {
667             verseTopicTXF.setEditable(false);
668             titleTXF.setEditable(false);
669             scriptureTXA.setEditable(false);
670             observationTXA.setEditable(false);
671             applicationTXA.setEditable(false);
672             prayerTXA.setEditable(false);
673             verseTopicTXF.setBackground(super.getBackground());
674             titleTXF.setBackground(super.getBackground());
675             dateBTN.setBackground(super.getBackground());
676             scriptureTXA.setBackground(super.getBackground());
677             observationTXA.setBackground(super.getBackground());
678             applicationTXA.setBackground(super.getBackground());
679             prayerTXA.setBackground(super.getBackground());
680             titleTXF.setBorder(BorderFactory.createEmptyBorder());
681             verseTopicTXF.setBorder(BorderFactory.createEmptyBorder());
682             dateBTN.setFocusable(false);
683             dateBTN.setBorder(new EmptyBorder(0, 0, 0, 0));
684             dateBTN.setButtonState(false);
685    
686             gb.gridy = 2;
687             gb.insets = new Insets(0, 0, 0, 0);
688             gb.gridx = 1;
689             gb.gridwidth = 4;
690             gb.weighty = 100;
691             gb.weightx = 100;
692             gb.fill = GridBagConstraints.BOTH;
693             c.add(dailyItemsSP, gb);
694    
695             if(dailyItems.isEmpty()) {
696                editMNI.setEnabled(false);
697                editBTN.setEnabled(false);
698                deleteBTN.setEnabled(false);
699                deleteMNI.setEnabled(false);
700             } else {
701                editMNI.setEnabled(true);
702                editBTN.setEnabled(true);
703                deleteBTN.setEnabled(true);
704                deleteMNI.setEnabled(true);
705             }
706    
707             newEntryMNI.setEnabled(true);
708    
709             //exitMNI.setEnabled(false);
710             newBTN.setEnabled(true);
711    
712             c.remove(buttonPNL);
713             c.repaint();
714          }
715       }
716    
717       /**
718        * DOCUMENT ME!
719        *
720        * @param e DOCUMENT ME!
721        */
722       public void valueChanged(ListSelectionEvent e) {
723          //Ignore extra message
724          if(e.getValueIsAdjusting() || (dailyItemsTBL.getSelectedRow() == -1)) {
725             return;
726          }
727    
728          //update selected row
729          selectedRow = dailyItemsTBL.getSelectedRow();
730    
731          //        if (selectedRow == -1) {
732          //            return;
733          //        }
734          Object[] obj = new Object[dailyItemsTBL.getColumnCount()];
735    
736          for(int column = 0; (column < obj.length) && (selectedRow != -1); column++) {
737             obj[column] = dailyItemsTBL.getValueAt(selectedRow, column);
738          }
739    
740          DailyItem tempItem = new DailyItem((Date)obj[0], (String)obj[1], (String)obj[2]);
741    
742          currentItemLocation = dailyItems.indexOf(tempItem);
743    
744          if(currentItemLocation != -1) {
745             currentItem = (DailyItem)dailyItems.elementAt(currentItemLocation);
746             verseTopicTXF.setText(currentItem.getTopic());
747             dateBTN.setDate(currentItem.getDate());
748             titleTXF.setText(currentItem.getTitle());
749             scriptureTXA.setText(currentItem.getScripture());
750             observationTXA.setText(currentItem.getObservation());
751             applicationTXA.setText(currentItem.getApplication());
752             prayerTXA.setText(currentItem.getPrayer());
753          }
754       }
755    
756       /**
757        * DOCUMENT ME!
758        *
759        * @param imageName DOCUMENT ME!
760        *
761        * @return DOCUMENT ME!
762        */
763       protected static ImageIcon createGeneralIcon(String imageName) {
764          String imgLocation = "icons/" + imageName + ".png";
765          java.net.URL imageURL = SOAPGUI.class.getResource(imgLocation);
766    
767          if(imageURL == null) {
768             System.err.println("Resource not found: " + imgLocation);
769    
770             return null;
771          } else {
772             return new ImageIcon(imageURL);
773          }
774       }
775    
776       /**
777        * DOCUMENT ME!
778        *
779        * @author $author$
780        * @version $Revision$
781        */
782       class AboutAction extends AbstractAction {
783          public AboutAction(String text, ImageIcon icon, String desc, Integer mnemonic) {
784             super(text, icon);
785             putValue(SHORT_DESCRIPTION, desc);
786             putValue(MNEMONIC_KEY, mnemonic);
787          }
788    
789          /**
790           * DOCUMENT ME!
791           *
792           * @param e DOCUMENT ME!
793           */
794          public void actionPerformed(ActionEvent e) {
795             new About();
796          }
797       }
798    
799       /**
800        * DOCUMENT ME!
801        *
802        * @author $author$
803        * @version $Revision$
804        */
805       class DailyReadingAction extends AbstractAction {
806          public DailyReadingAction(String text, ImageIcon icon, String desc,
807             Integer mnemonic) {
808             super(text, icon);
809             putValue(SHORT_DESCRIPTION, desc);
810             putValue(MNEMONIC_KEY, mnemonic);
811          }
812    
813          /**
814           * DOCUMENT ME!
815           *
816           * @param e DOCUMENT ME!
817           */
818          public void actionPerformed(ActionEvent e) {
819             new DailyReading(SOAPGUI.this, storage);
820          }
821       }
822    
823       /**
824        * DOCUMENT ME!
825        *
826        * @author $author$
827        * @version $Revision$
828        */
829       class DeleteAction extends AbstractAction {
830          public DeleteAction(String text, ImageIcon icon, String desc, Integer mnemonic) {
831             super(text, icon);
832             putValue(SHORT_DESCRIPTION, desc);
833             putValue(MNEMONIC_KEY, mnemonic);
834          }
835    
836          //the correct thing is in the vector but the wrong element from the table is being deleted
837          public void actionPerformed(ActionEvent e) {
838             //remove element from vector
839             dailyItems.removeElementAt(currentItemLocation);
840    
841             //remove the row from the table, and notifies all listeners
842             tableMDL.removeRow(sorter.modelIndex(selectedRow));
843    
844             //change selected item
845             if(selectedRow > 0) {
846                rowSM.setSelectionInterval(selectedRow - 1, selectedRow - 1);
847             } else if((selectedRow == 0) && (dailyItems.size() > 0)) {
848                rowSM.setSelectionInterval(selectedRow, selectedRow);
849             }
850    
851             //disable edit button
852             if(dailyItems.isEmpty()) {
853                editMNI.setEnabled(false);
854                editBTN.setEnabled(false);
855                deleteBTN.setEnabled(false);
856                deleteMNI.setEnabled(false);
857             }
858          }
859       }
860    
861       /**
862        * DOCUMENT ME!
863        *
864        * @author $author$
865        * @version $Revision$
866        */
867       class EditAction extends AbstractAction {
868          public EditAction(String text, ImageIcon icon, String desc, Integer mnemonic) {
869             super(text, icon);
870             putValue(SHORT_DESCRIPTION, desc);
871             putValue(MNEMONIC_KEY, mnemonic);
872          }
873    
874          /**
875           * DOCUMENT ME!
876           *
877           * @param e DOCUMENT ME!
878           */
879          public void actionPerformed(ActionEvent e) {
880             edit(true);
881          }
882       }
883    
884       ///////////////////////////////////////////////////////////////////////////////
885       // ACTIONS
886       ///////////////////////////////////////////////////////////////////////////////
887       class ExitAction extends AbstractAction {
888          public ExitAction(String text, ImageIcon icon, String desc, Integer mnemonic) {
889             super(text, icon);
890             putValue(SHORT_DESCRIPTION, desc);
891             putValue(MNEMONIC_KEY, mnemonic);
892          }
893    
894          /**
895           * The actions that take place when exiting the application. It currently saves
896           * the data and exits.
897           *
898           * @param evt DOCUMENT ME!
899           */
900          public void actionPerformed(ActionEvent evt) {
901             //update data in storage and write to file.
902             try {
903                storage.setDIData(dailyItems);
904                storage.writeToFile();
905             } catch(Exception e) {
906                JOptionPane.showMessageDialog(SOAPGUI.this,
907                   "Could not access the database! " +
908                   "Make sure the database exists and has read/write permission.");
909             }
910    
911             dispose();
912             System.exit(0);
913          }
914       }
915    
916       /**
917        * DOCUMENT ME!
918        *
919        * @author $author$
920        * @version $Revision$
921        */
922       class NewAction extends AbstractAction {
923          public NewAction(String text, ImageIcon icon, String desc, Integer mnemonic) {
924             super(text, icon);
925             putValue(SHORT_DESCRIPTION, desc);
926             putValue(MNEMONIC_KEY, mnemonic);
927          }
928    
929          /**
930           * DOCUMENT ME!
931           *
932           * @param e DOCUMENT ME!
933           */
934          public void actionPerformed(ActionEvent e) {
935             verseTopicTXF.setText("");
936             dateBTN.setDate(new Date());
937             titleTXF.setText("Title");
938             scriptureTXA.setText("");
939             observationTXA.setText("");
940             applicationTXA.setText("");
941             prayerTXA.setText("");
942             newEdit = true;
943             edit(true);
944          }
945       }
946    
947       /**
948        * DOCUMENT ME!
949        *
950        * @author $author$
951        * @version $Revision$
952        */
953       class PrayerLogAction extends AbstractAction {
954          public PrayerLogAction(String text, ImageIcon icon, String desc, Integer mnemonic) {
955             super(text, icon);
956             putValue(SHORT_DESCRIPTION, desc);
957             putValue(MNEMONIC_KEY, mnemonic);
958          }
959    
960          /**
961           * DOCUMENT ME!
962           *
963           * @param e DOCUMENT ME!
964           */
965          public void actionPerformed(ActionEvent e) {
966             new PrayerLog(storage);
967          }
968       }
969    }
970    
971    //FIXME: a little help section
972    /*
973     * - program to keep daily soap -store/retrieve data in a text file put this in
974     * its own class so it can be upgraded later -open from file menu retrieves data
975     * -write to file changes on close or save from file menu GUI - table containing -
976     * date - scripture/topic - title - date upper right - non editable unless edit
977     * is clicked - title top center - non editable unless edit is clicked - content
978     * bottom center - non editable unless edit is clicked - buttons - edit & close
979     * DailyItem - an object storing the date, scripture/topic, title & content
980     */