Appendix B. A Java Swing GUI for BudgetPro

This is the listing of the GUI for BudgetPro. For a discussion, see Chapter 16.

  1 package net.multitool.gui;
  2
  3 import java.awt.*;
  4 import java.awt.event.*;
  5 import javax.swing.*;
  6 import javax.swing.event.*;
  7 import javax.swing.table.*;
  8 import java.util.*;
  9 import net.multitool.core.*;
 10
 11 /**
 12  * This class is the main application class for the BudgetPro gui
 13  */
 14
 15 public class
 16 BudgetPro
 17 {
 18   Account top;
 19   Account current;
 20
 21  // gui components
 22  private JFrame frame;   // needed by dialogs to root themselves
 23  private JLabel nam;
 24  private JLabel tot;
 25  private JLabel val;
 26  private JButton upton = new JButton(
                       new ImageIcon("net/multitool/gui/back.gif"));
 27  private JButton creat = new JButton("New Subaccount");
 28  private JButton view = new JButton("View Subaccount");
 29  private JButton clos = new JButton("Quit");
 30
 31  private JTable list;
 32  private AbstractTableModel model;
 33
 34  private AcctDialog askem;   // make once, use often
 35
 36  // Set Up an Action for a Button
 37  private ActionListener upAction = new ActionListener()
 38  {
 39    public void
 40    actionPerformed(ActionEvent e)
 41    {
 42      // this is the action for UP arrow icon;
 43      Account next;
 44      next = current.getParent();
 45      if (next != null) {
 46        current = next;
 47        setStatus();
 48        // TODO: notify the table, too
 49        model.fireTableDataChanged();
 50      } // TODO: else infodialog or Beep.
 51    }
 52  } ;
 53
 54  private ActionListener cdAction = new ActionListener()
 55  {
 56    public void
 57    actionPerformed(ActionEvent e)
 58    {
 59      // this is the action for VIEW subdirectory;
 60      // a "cd" into the subaccount.
 61      int row = list.getSelectedRow();
 62      // System.out.println("Row="+row); // DEBUG; TODO: REMOVE
 63      if (row > -1) {             // only if a row was selected
 64        String subname = (String) model.getValueAt(row, 0); // name column
 65        Account next = current.getSub(subname);
 66        if (next != null) {
 67          current = next;
 68          // System.out.println("cd to:"+current.getName());
 69          setStatus();
 70          // notify the table, too
 71          model.fireTableDataChanged();
 72        } // TODO: else infodialog or Beep.
 73      }
 74    }
 75  } ;
 76
 77  // TEST ONLY:
 78  int testid = 0;
 79
 80  BudgetPro(JFrame frame, String username, String value)
 81  {
 82    this.frame = frame;
 83    top = new Account("TopLevel", new User(username), value);
 84    current = top;
 85
 86  } // constructor
 87
 88  private Component
 89  createStatus()
 90  {
 91    JPanel retval = new JPanel();   // default: flow layout
 92
 93    upton.addActionListener(upAction);
 94
 95    nam = new JLabel("Account: Name");
 96    tot = new JLabel("Total: $");
 97    val = new JLabel("Remaining: $");
 98
 99    retval.add(upton);
100    retval.add(nam);
101    retval.add(tot);
102    retval.add(val);
103
104    setStatus();
105
106    return retval;
107  } // createStatus
108
109  /**
110   * Set the values of the status fields,
111   * as when the account has changed.
112   */
113  private void
114  setStatus()
115  {
116    nam.setText("Account: "+current.getName());
117    tot.setText("Total: $"+current.getTotal());
118    // tot.setText("SubAccounts: "+current.size());
119    val.setText("Remaining: $"+current.getBalance());
120
121    // disable the button if there is no "up" to go
122    if (current.getParent() == null) {
123        upton.setEnabled(false);
124    } else {
125        upton.setEnabled(true);
126    }
127
128  } // setStatus
129
130  private Component
131  createList()
132  {
133    JScrollPane retval;
134
135    model = new AbstractTableModel()
136      {
137        private String [] columnNames = {"Account", "Owner", "Value"};
138
139        public String
140        getColumnName(int col) {
141          return columnNames[col];
142        } // getColumnName
143
144        public int
145        getRowCount()
146        {
147          int retval;
148
149          if (current != null) {
150              retval = current.size();
151          } else {
152              retval = 1;     // testing only
153          }
154
155          return retval;
156
157        } // getRowCount
158
159        public int getColumnCount() { return columnNames.length; }
160
161        public Object
162        getValueAt(int row, int col) {
163          Object retval = null;
164          Account aa = null;
165          // return "---";   // rowData[row][col];
166          int count = 0;
167          for (Iterator itr=current.getAllSubs(); itr.hasNext(); )
168          {
169            count++;
170            aa = (Account) itr.next();
171            if (count > row) { break; }
172          } // next
173          switch (col) {
174          case 0:
175                  retval = aa.getName();
176                  break;
177          case 1:
178                  retval = aa.getOwner();
179                  break;
180          case 2:
181                  retval = aa.getTotal();
182                  break;
183          } // endswitch
184          return retval;
185        } // getValueAt
186
187        public boolean
188        isCellEditable(int row, int col)
189        {
190          return false;
191        } // isCellEditable
192      };
193    list = new JTable(model);
194    list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
195
196    list.getSelectionModel().addListSelectionListener(
197      new ListSelectionListener()
198      {
199        public void
200        valueChanged(ListSelectionEvent e)
201        {
202          ListSelectionModel lsm = (ListSelectionModel)e.getSource();
203          if (lsm.isSelectionEmpty()) {
204              view.setEnabled(false);
205          } else {
206              view.setEnabled(true);
207          }
208        } // valueChanged
209      }
210    );
211
212    retval = new JScrollPane(list);
213
214    return retval;
215
216  } // createList
217
218  private Component
219  createButtons(JRootPane root)
220  {
221    JPanel retval = new JPanel();   // default: flow layout
222
223    //Lay out the buttons from left to right.
224    retval.setLayout(new BoxLayout(retval, BoxLayout.X_AXIS));
225    retval.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
226    retval.add(Box.createHorizontalGlue());
227    retval.add(creat);
228    retval.add(Box.createRigidArea(new Dimension(10, 0)));
229    retval.add(view);
230    retval.add(Box.createRigidArea(new Dimension(10, 0)));
231    retval.add(clos);
232
233    // ---------------------------------------- Define some actions
234    ActionListener closAction = new ActionListener()
235    {
236      public void
237      actionPerformed(ActionEvent e)
238      {
239          System.exit(0);
240      }
241    } ;
242    clos.addActionListener(closAction);
243
244    ActionListener creatAction = new ActionListener()
245    {
246      public void
247      actionPerformed(ActionEvent e)
248      {
249        Account child;
250        // get the info via a Dialog (of sorts)
251        if (askem == null) {
252            askem = new AcctDialog(frame, "New Subaccount");
253        } else {
254            askem.clear();
255            askem.setVisible(true);
256        }
257        String subName = askem.getName();
258        String subAmnt = askem.getAmnt();
259
260        // if empty, assume the operation was cancelled, else:
261        if ((subName != null) && (subName.length() > 0)) {
262            child = current.createSub(subName, subAmnt);
263            setStatus();
264            model.fireTableDataChanged(); // notify the table
265        }
266      }
267    };
268    creat.addActionListener(creatAction);
269
270    // function is to get selection from table and cd there
271    view.addActionListener(cdAction);
272    // but it starts off disabled, since there is no data yet
273    view.setEnabled(false);
274
275    // ------------------------------------------------------------
276    frame.getRootPane().setDefaultButton(creat);
277    clos.grabFocus();
278
279    return retval;
280
281  } // createButtons
282
283  public static void
284  main(String[] args)
285  {
286    BudgetPro app = null;
287
288    //Create the top-level container
289    JFrame frame = new JFrame("BudgetPro");
290
291    // ----------- set up the account/app based on the command line args
292    try {
293        String username = System.getProperty("user.name", "default");
294        if (args.length > 0) {
295            app = new BudgetPro(frame, username, args[0]);
296         } else {
297            System.err.println("usage: BudgetPro dollar_amt");
298            System.exit(1);
299         }
300    } catch (Exception e) {
301        System.err.println("Error on startup.");
302        e.printStackTrace();
303        System.exit(2);
304    }
305
306    // ----------- now set up the UI and get things going
307    try {
308        UIManager.setLookAndFeel(
309                    UIManager.getCrossPlatformLookAndFeelClassName());
310    } catch (Exception e) {
311        System.err.println("Can't set the desired look and feel.");
312        e.printStackTrace();
313        System.exit(3);
314    }
315
316    // build the pieces and add them to the top-level container
317
318    Component status = app.createStatus();
319    frame.getContentPane().add(status, BorderLayout.NORTH);
320
321    Component list = app.createList();
322    frame.getContentPane().add(list, BorderLayout.CENTER);
323
324    Component buttons = app.createButtons(frame.getRootPane());
325    frame.getContentPane().add(buttons, BorderLayout.SOUTH);
326
327    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
328    frame.pack();
329    frame.setVisible(true);
330  } // main
331
332 } // class BudgetPro

Here is the code for the dialog for creating new accounts, AcctDialog.java:

  1 package net.multitool.gui;
  2
  3 import java.awt.*;
  4 import java.awt.event.*;
  5 import javax.swing.*;
  6 import javax.swing.table.*;
  7 import java.util.*;
  8 import net.multitool.core.*;
  9
 10 class
 11 AcctDialog
 12   extends JDialog
 13 {
 14   JDialog dialog;   // for reference from the buttons' actions
 15   JTextField nameField;
 16   JTextField amntField;
 17
 18   AcctDialog(JFrame frame, String title)
 19   {
 20     super(frame, title, true);
 21     dialog = this;
 22     nameField = new JTextField(25);
 23     amntField = new JTextField(9);
 24
 25     // right justify the numeric field
 26     amntField.setHorizontalAlignment(JTextField.RIGHT);
 27
 28     // TODO: so that <Enter> will do a create
 29     // this.getInputMap().put(KeyStroke.getKeyStroke("Enter"), "create");
 30     /*
 31       Action myAction = new AbstractAction("doSomething") {
 32         public void actionPerformed() {
 33           doSomething();
 34         }
 35       };
 36       myComponent.getActionMap().put(myAction.get(Action.NAME), myAction);
 37      */
 38
 39     //--------------------------------------------------Label on top----
 40     JLabel label = new JLabel("<html><p align=left><i>"
 41                    + "Enter the info to create a subaccount.<br>"
 42                    + "</i>");
 43     label.setHorizontalAlignment(JLabel.LEFT);
 44     Font font = label.getFont();
 45     label.setFont(label.getFont().deriveFont(font.PLAIN, 14.0f));
 46
 47     //--------------------------------------------------Text Fields----
 48     String[] labels = {"(Sub)Account Name: ", "Dollar Amount: "};
 49     JTextField [] fields = {nameField, amntField};
 50     int numPairs = fields.length;
 51
 52     //Create and populate the panel.
 53     JPanel textes = new JPanel(new SpringLayout());
 54     for (int i = 0; i < numPairs; i++) {
 55       JLabel l = new JLabel(labels[i], JLabel.TRAILING);
 56       textes.add(l);
 57       l.setLabelFor(fields[i]);  // not nec. since we have no kb shortcuts
 58       textes.add(fields[i]);
 59     }
 60
 61     //Lay out the panel.
 62     SpringUtilities.makeCompactGrid(textes,
 63                                     numPairs, 2, //rows, cols
 64                                     6, 6,        //initX, initY
 65                                     6, 6);       //xPad, yPad
 66
 67
 68     //--------------------------------------------------Buttons on bottom
 69     JButton createButton = new JButton("Create");
 70     createButton.addActionListener(new ActionListener() {
 71       public void actionPerformed(ActionEvent e) {
 72         nameField.grabFocus(); // before leaving, ready for next time.
 73         dialog.setVisible(false);   // go away
 74       }
 75     });
 76
 77     JButton cancelButton = new JButton("Cancel");
 78     cancelButton.addActionListener(new ActionListener() {
 79       public void actionPerformed(ActionEvent e) {
 80         clear(); // toss out any entry
 81         dialog.setVisible(false);
 82       }
 83     });
 84     getRootPane().setDefaultButton(createButton);
 85
 86     JPanel closePanel = new JPanel();
 87     closePanel.setLayout(new BoxLayout(closePanel, BoxLayout.LINE_AXIS));
 88     closePanel.add(Box.createHorizontalGlue());
 89     closePanel.add(createButton);
 90     closePanel.add(Box.createRigidArea(new Dimension(5, 0)));
 91     closePanel.add(cancelButton);
 92     closePanel.setBorder(BorderFactory.createEmptyBorder(10,0,5,5));
 93
 94     JPanel contentPane = new JPanel(new BorderLayout());
 95     contentPane.add(label, BorderLayout.PAGE_START);
 96     contentPane.add(textes, BorderLayout.CENTER);
 97     contentPane.add(closePanel, BorderLayout.PAGE_END);
 98     contentPane.setOpaque(true);
 99     setContentPane(contentPane);
100
101     //Show it.
102     setSize(new Dimension(300, 160));
103     setLocationRelativeTo(frame);
104     setVisible(true);
105
106   } // constructor
107
108   public String
109   getName()
110   {
111     String retval = null;
112     if (nameField != null) {
113       retval = nameField.getText();
114     }
115     return retval;
116   } // getName
117     
118   public String
119   getAmnt()
120   {
121     String retval = null;
122     if (amntField != null) {
123       retval = amntField.getText();
124     }
125     return retval;
126   } // getAmnt
127
128   public void
129   clear()
130   {
131     nameField.setText(null);
132     amntField.setText(null);
133   } // clear
134
135 } // class AcctDialog
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.194.182