Methapolis  0.27
 All Classes Namespaces Files Functions Variables Enumerator
BudgetDialog.java
Go to the documentation of this file.
1 // This file is part of MicropolisJ.
2 // Copyright (C) 2013 Jason Long
3 // Portions Copyright (C) 1989-2007 Electronic Arts Inc.
4 //
5 // MicropolisJ is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU GPLv3, with additional terms.
7 // See the README file, included in this distribution, for details.
8 
9 package micropolisj.gui;
10 
11 import java.awt.*;
12 import java.awt.event.*;
13 import javax.swing.*;
14 import javax.swing.event.*;
15 import java.text.NumberFormat;
16 import java.util.*;
17 
18 import micropolisj.engine.*;
19 import static micropolisj.gui.MainWindow.formatFunds;
20 import static micropolisj.gui.MainWindow.formatGameDate;
21 
22 public class BudgetDialog extends JDialog
23 {
24  Micropolis engine;
25 
26  JSpinner taxRateEntry;
27  int origTaxRate;
28  double origRoadPct;
29  double origFirePct;
30  double origPolicePct;
31  double origResearchPct;
32 
33 
34  JLabel roadFundRequest = new JLabel();
35  JLabel roadFundAlloc = new JLabel();
36  JSlider roadFundEntry;
37 
38  JLabel policeFundRequest = new JLabel();
39  JLabel policeFundAlloc = new JLabel();
40  JSlider policeFundEntry;
41 
42  JLabel fireFundRequest = new JLabel();
43  JLabel fireFundAlloc = new JLabel();
44  JSlider fireFundEntry;
45 
46  JLabel researchFundRequest = new JLabel();
47  JLabel researchFundAlloc = new JLabel();
48  JSlider researchFundEntry;
49 
50  JLabel taxRevenueLbl = new JLabel();
51 
52  static ResourceBundle strings = MainWindow.strings;
53 
54  JCheckBox autoBudgetBtn = new JCheckBox(strings.getString("budgetdlg.auto_budget"));
55  JCheckBox pauseBtn = new JCheckBox(strings.getString("budgetdlg.pause_game"));
56 
57  private void applyChange()
58  {
59  int newTaxRate = ((Number) taxRateEntry.getValue()).intValue();
60  int newRoadPct = ((Number) roadFundEntry.getValue()).intValue();
61  int newPolicePct = ((Number) policeFundEntry.getValue()).intValue();
62  int newFirePct = ((Number) fireFundEntry.getValue()).intValue();
63  int newResearchPct = ((Number) researchFundEntry.getValue()).intValue();
64 
65  engine.setBudgetNumbers(newTaxRate, (double)newRoadPct / 100.0, (double)newRoadPct / 100.0,
66  (double)newPolicePct / 100.0, (double)newFirePct / 100.0, (double)newResearchPct/100.0);
67 
68  loadBudgetNumbers(false);
69  }
70 
71  private void loadBudgetNumbers(boolean updateEntries)
72  { //Change required
73  BudgetNumbers b = engine.generateBudget(engine.getPlayerInfo());
74  if (updateEntries)
75  {
76  taxRateEntry.setValue(b.taxRate);
77  roadFundEntry.setValue((int)Math.round(b.roadPercent*100.0));
78  policeFundEntry.setValue((int)Math.round(b.policePercent*100.0));
79  fireFundEntry.setValue((int)Math.round(b.firePercent*100.0));
80  researchFundEntry.setValue((int)Math.round(b.researchPercent*100.0));
81  }
82 
83  taxRevenueLbl.setText(formatFunds(b.taxIncome));
84 
85  roadFundRequest.setText(formatFunds(b.roadRequest));
86  roadFundAlloc.setText(formatFunds(b.roadFunded));
87 
88  policeFundRequest.setText(formatFunds(b.policeRequest));
89  policeFundAlloc.setText(formatFunds(b.policeFunded));
90 
91  fireFundRequest.setText(formatFunds(b.fireRequest));
92  fireFundAlloc.setText(formatFunds(b.fireFunded));
93 
94  researchFundRequest.setText(formatFunds(b.researchRequest));
95  researchFundAlloc.setText(formatFunds(b.researchFunded));
96  }
97 
98  static void adjustSliderSize(JSlider slider)
99  {
100  Dimension sz = slider.getPreferredSize();
101  slider.setPreferredSize(
102  new Dimension(80, sz.height)
103  );
104  }
105 
106  public BudgetDialog(Window owner, Micropolis engine)
107  {
108  super(owner);
109  setTitle(strings.getString("budgetdlg.title"));
110 
111  this.engine = engine;
112  this.origTaxRate = engine.getPlayerInfo().cityTax;
113  this.origRoadPct = engine.getPlayerInfo().roadPercent;
114  this.origFirePct = engine.getPlayerInfo().firePercent;
115  this.origPolicePct = engine.getPlayerInfo().policePercent;
116  this.origResearchPct = engine.getPlayerInfo().researchPercent;
117 
118  // give text fields of the fund-level spinners a minimum size
119  taxRateEntry = new JSpinner(new SpinnerNumberModel(7,0,20,1));
120 
121  // widgets to set funding levels
122  roadFundEntry = new JSlider(JSlider.HORIZONTAL, 0, 100, 100);
123  adjustSliderSize(roadFundEntry);
124  fireFundEntry = new JSlider(JSlider.HORIZONTAL, 0, 100, 100);
125  adjustSliderSize(fireFundEntry);
126  policeFundEntry = new JSlider(JSlider.HORIZONTAL, 0, 100, 100);
127  adjustSliderSize(policeFundEntry);
128  researchFundEntry = new JSlider(JSlider.HORIZONTAL, 0, 100, 100);
129  adjustSliderSize(researchFundEntry);
130 
131  ChangeListener change = new ChangeListener() {
132  public void stateChanged(ChangeEvent ev) {
133  applyChange();
134  }
135  };
136  taxRateEntry.addChangeListener(change);
137  roadFundEntry.addChangeListener(change);
138  fireFundEntry.addChangeListener(change);
139  policeFundEntry.addChangeListener(change);
140  researchFundEntry.addChangeListener(change);
141 
142  Box mainBox = new Box(BoxLayout.Y_AXIS);
143  mainBox.setBorder(BorderFactory.createEmptyBorder(8,8,8,8));
144  add(mainBox, BorderLayout.CENTER);
145 
146  mainBox.add(makeTaxPane());
147 
148  JSeparator sep = new JSeparator(SwingConstants.HORIZONTAL);
149  mainBox.add(sep);
150 
151  mainBox.add(makeFundingRatesPane());
152 
153  JSeparator sep1 = new JSeparator(SwingConstants.HORIZONTAL);
154  mainBox.add(sep1);
155 
156  mainBox.add(makeBalancePane());
157 
158  JSeparator sep2 = new JSeparator(SwingConstants.HORIZONTAL);
159  mainBox.add(sep2);
160 
161  mainBox.add(makeOptionsPane());
162 
163  JPanel buttonPane = new JPanel();
164  add(buttonPane, BorderLayout.SOUTH);
165 
166  JButton continueBtn = new JButton(strings.getString("budgetdlg.continue"));
167  continueBtn.addActionListener(new ActionListener() {
168  public void actionPerformed(ActionEvent ev) {
170  }});
171  buttonPane.add(continueBtn);
172 
173  JButton resetBtn = new JButton(strings.getString("budgetdlg.reset"));
174  resetBtn.addActionListener(new ActionListener() {
175  public void actionPerformed(ActionEvent ev) {
176  onResetClicked();
177  }});
178  buttonPane.add(resetBtn);
179 
180  loadBudgetNumbers(true);
182  pack();
183  setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
184  setLocationRelativeTo(owner);
185  getRootPane().registerKeyboardAction(new ActionListener() {
186  public void actionPerformed(ActionEvent evt) {
187  dispose();
188  }},
189  KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
190  JComponent.WHEN_IN_FOCUSED_WINDOW);
191  }
192 
193  private void setAutoRequestFocus_compat(boolean v)
194  {
195  try
196  {
197  if (super.getClass().getMethod("setAutoRequestFocus", boolean.class) != null) {
198  super.setAutoRequestFocus(v);
199  }
200  }
201  catch (NoSuchMethodException e) {
202  // ok to ignore
203  }
204  }
205 
206  private JComponent makeFundingRatesPane()
207  {
208  JPanel fundingRatesPane = new JPanel(new GridBagLayout());
209  fundingRatesPane.setBorder(BorderFactory.createEmptyBorder(8,0,8,0));
210 
211  GridBagConstraints c0 = new GridBagConstraints();
212  c0.gridx = 0;
213  c0.weightx = 0.25;
214  c0.anchor = GridBagConstraints.WEST;
215  GridBagConstraints c1 = new GridBagConstraints();
216  c1.gridx = 1;
217  c1.weightx = 0.25;
218  c1.anchor = GridBagConstraints.EAST;
219  GridBagConstraints c2 = new GridBagConstraints();
220  c2.gridx = 2;
221  c2.weightx = 0.5;
222  c2.anchor = GridBagConstraints.EAST;
223  GridBagConstraints c3 = new GridBagConstraints();
224  c3.gridx = 3;
225  c3.weightx = 0.5;
226  c3.anchor = GridBagConstraints.EAST;
227 
228  c1.gridy = c2.gridy = c3.gridy = 0;
229  fundingRatesPane.add(new JLabel(strings.getString("budgetdlg.funding_level_hdr")), c1);
230  fundingRatesPane.add(new JLabel(strings.getString("budgetdlg.requested_hdr")), c2);
231  fundingRatesPane.add(new JLabel(strings.getString("budgetdlg.allocation_hdr")), c3);
232 
233  c0.gridy = c1.gridy = c2.gridy = c3.gridy = 1;
234  fundingRatesPane.add(new JLabel(strings.getString("budgetdlg.road_fund")), c0);
235  fundingRatesPane.add(roadFundEntry, c1);
236  fundingRatesPane.add(roadFundRequest, c2);
237  fundingRatesPane.add(roadFundAlloc, c3);
238 
239  c0.gridy = c1.gridy = c2.gridy = c3.gridy = 2;
240  fundingRatesPane.add(new JLabel(strings.getString("budgetdlg.police_fund")), c0);
241  fundingRatesPane.add(policeFundEntry, c1);
242  fundingRatesPane.add(policeFundRequest, c2);
243  fundingRatesPane.add(policeFundAlloc, c3);
244 
245  c0.gridy = c1.gridy = c2.gridy = c3.gridy = 3;
246  fundingRatesPane.add(new JLabel(strings.getString("budgetdlg.fire_fund")), c0);
247  fundingRatesPane.add(fireFundEntry, c1);
248  fundingRatesPane.add(fireFundRequest, c2);
249  fundingRatesPane.add(fireFundAlloc, c3);
250 
251  c0.gridy = c1.gridy = c2.gridy = c3.gridy = 4;
252  fundingRatesPane.add(new JLabel(strings.getString("budgetdlg.research_fund")), c0);
253  fundingRatesPane.add(researchFundEntry, c1);
254  fundingRatesPane.add(researchFundRequest, c2);
255  fundingRatesPane.add(researchFundAlloc, c3);
256 
257 
258  return fundingRatesPane;
259  }
260 
261  private JComponent makeOptionsPane()
262  {
263  JPanel optionsPane = new JPanel(new GridBagLayout());
264  optionsPane.setBorder(BorderFactory.createEmptyBorder(8,0,0,0));
265 
266  GridBagConstraints c0 = new GridBagConstraints();
267  GridBagConstraints c1 = new GridBagConstraints();
268 
269  c0.gridx = 0;
270  c1.gridx = 1;
271  c0.anchor = c1.anchor = GridBagConstraints.WEST;
272  c0.gridy = c1.gridy = 0;
273  c0.weightx = c1.weightx = 0.5;
274  optionsPane.add(autoBudgetBtn, c0);
275  optionsPane.add(pauseBtn, c1);
276 
277  autoBudgetBtn.setSelected(engine.autoBudget);
278  pauseBtn.setSelected(engine.simSpeed == Speed.PAUSED);
279 
280  return optionsPane;
281  }
282 
283  private JComponent makeTaxPane()
284  {
285  JPanel pane = new JPanel(new GridBagLayout());
286  pane.setBorder(BorderFactory.createEmptyBorder(0,0,8,0));
287 
288  GridBagConstraints c0 = new GridBagConstraints();
289  GridBagConstraints c1 = new GridBagConstraints();
290  GridBagConstraints c2 = new GridBagConstraints();
291 
292  c0.gridx = 0;
293  c0.anchor = GridBagConstraints.WEST;
294  c0.weightx = 0.25;
295  c1.gridx = 1;
296  c1.anchor = GridBagConstraints.EAST;
297  c1.weightx = 0.25;
298  c2.gridx = 2;
299  c2.anchor = GridBagConstraints.EAST;
300  c2.weightx = 0.5;
301 
302  c0.gridy = c1.gridy = c2.gridy = 0;
303  pane.add(new JLabel(strings.getString("budgetdlg.tax_rate_hdr")), c1);
304  pane.add(new JLabel(strings.getString("budgetdlg.annual_receipts_hdr")), c2);
305 
306  c0.gridy = c1.gridy = c2.gridy = 1;
307  pane.add(new JLabel(strings.getString("budgetdlg.tax_revenue")), c0);
308  pane.add(taxRateEntry, c1);
309  pane.add(taxRevenueLbl, c2);
310 
311  return pane;
312  }
313 
314  private void onContinueClicked()
315  {
316  if (autoBudgetBtn.isSelected() != engine.autoBudget) {
317  engine.toggleAutoBudget();
318  }
319  if (pauseBtn.isSelected() && engine.simSpeed != Speed.PAUSED) {
320  engine.setSpeed(Speed.PAUSED);
321  }
322  else if (!pauseBtn.isSelected() && engine.simSpeed == Speed.PAUSED) {
323  engine.setSpeed(Speed.NORMAL);
324  }
325 
326  dispose();
327  }
328 
329  private void onResetClicked()
330  {
331  engine.getPlayerInfo().cityTax = this.origTaxRate;
332  engine.getPlayerInfo().roadPercent = this.origRoadPct;
333  engine.getPlayerInfo().firePercent = this.origFirePct;
334  engine.getPlayerInfo().policePercent = this.origPolicePct;
335  engine.getPlayerInfo().researchPercent = this.origResearchPct;
336  loadBudgetNumbers(true);
337  }
338 
339  private JComponent makeBalancePane()
340  {
341  JPanel balancePane = new JPanel(new GridBagLayout());
342  balancePane.setBorder(BorderFactory.createEmptyBorder(8,24,8,24));
343 
344  GridBagConstraints c0 = new GridBagConstraints();
345  GridBagConstraints c1 = new GridBagConstraints();
346 
347  c0.anchor = GridBagConstraints.WEST;
348  c0.weightx = 0.5;
349  c0.gridx = 0;
350  c0.gridy = 0;
351 
352  JLabel thLbl = new JLabel(strings.getString("budgetdlg.period_ending"));
353  Font origFont = thLbl.getFont();
354  Font headFont = origFont.deriveFont(Font.ITALIC);
355  thLbl.setFont(headFont);
356  thLbl.setForeground(Color.MAGENTA);
357  balancePane.add(thLbl, c0);
358  //changeswp extra
359  //c0.gridy++;
360  //balancePane.add(new JLabel(strings.getString("budgetdlg.cash_begin")), c0);
361  c0.gridy++;
362  balancePane.add(new JLabel(strings.getString("budgetdlg.taxes_collected")), c0);
363  c0.gridy++;
364  balancePane.add(new JLabel(strings.getString("budgetdlg.capital_expenses")), c0);
365  c0.gridy++;
366  balancePane.add(new JLabel(strings.getString("budgetdlg.operating_expenses")), c0);
367  //c0.gridy++;
368  //balancePane.add(new JLabel(strings.getString("budgetdlg.cash_end")), c0);
369  c0.gridy++;
370  balancePane.add(new JLabel(strings.getString("budgetdlg.cash_income")), c0);
371  c0.gridy++;
372  balancePane.add(new JLabel(strings.getString("budgetdlg.cash_income_w/o")), c0);
373 
374  c1.anchor = GridBagConstraints.EAST;
375  c1.weightx = 0.25;
376  c1.gridx = 0;
377 
378  for (int i = 0; i < 2; i++) {
379 
380  if (i + 1 >= engine.financialHistory.size()) {
381  break;
382  }
383 
384  Micropolis.FinancialHistory f = engine.financialHistory.get(i);
385  Micropolis.FinancialHistory fPrior = engine.financialHistory.get(i+1);
386  int cashFlow = f.totalFunds - fPrior.totalFunds;
387  int capExpenses = -(cashFlow - f.taxIncome + f.operatingExpenses);
388  //int cashIncome = f.taxIncome - f.operatingExpenses - capExpenses;
389  int cashIncome = cashFlow;
390  int cashIncomeWO = f.taxIncome - f.operatingExpenses;
391 
392 
393 
394  c1.gridx++;
395  c1.gridy = 0;
396 
397  thLbl = new JLabel(formatGameDate(f.cityTime-1));
398  thLbl.setFont(headFont);
399  thLbl.setForeground(Color.MAGENTA);
400  balancePane.add(thLbl, c1);
401 /*
402  c1.gridy++;
403  JLabel previousBalanceLbl = new JLabel();
404  previousBalanceLbl.setText(formatFunds(fPrior.totalFunds));
405  balancePane.add(previousBalanceLbl, c1);
406 */
407  c1.gridy++;
408  JLabel taxIncomeLbl = new JLabel();
409  taxIncomeLbl.setText(formatFunds(f.taxIncome));
410  balancePane.add(taxIncomeLbl, c1);
411 
412  c1.gridy++;
413  JLabel capExpensesLbl = new JLabel();
414  capExpensesLbl.setText(formatFunds(capExpenses));
415  balancePane.add(capExpensesLbl, c1);
416 
417  c1.gridy++;
418  JLabel opExpensesLbl = new JLabel();
419  opExpensesLbl.setText(formatFunds(f.operatingExpenses));
420  balancePane.add(opExpensesLbl, c1);
421 
422  /*c1.gridy++;
423  JLabel newBalanceLbl = new JLabel();
424  newBalanceLbl.setText(formatFunds(f.totalFunds));
425  balancePane.add(newBalanceLbl, c1);
426 */
427  c1.gridy++;
428  JLabel newCashIncomeLbl = new JLabel();
429  newCashIncomeLbl.setText(formatFunds(cashIncome));
430  balancePane.add(newCashIncomeLbl, c1);
431 
432  c1.gridy++;
433  JLabel newCashIncomeWOLbl = new JLabel();
434  newCashIncomeWOLbl.setText(formatFunds(cashIncomeWO));
435  balancePane.add(newCashIncomeWOLbl, c1);
436  }
437 
438  return balancePane;
439  }
440 }