< Zurück | Inhalt | Weiter >

Appendix B


A Java Swing GUI for BudgetPro


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



image

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


527



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


image


Here is the code for the dialog for creating new accounts,

AcctDialog.java:


image

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


image