KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > compiere > grid > ed > Calculator


1 /******************************************************************************
2  * The contents of this file are subject to the Compiere License Version 1.1
3  * ("License"); You may not use this file except in compliance with the License
4  * You may obtain a copy of the License at http://www.compiere.org/license.html
5  * Software distributed under the License is distributed on an "AS IS" basis,
6  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
7  * the specific language governing rights and limitations under the License.
8  * The Original Code is Compiere ERP & CRM Business Solution
9  * The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc.
10  * Portions created by Jorg Janke are Copyright (C) 1999-2001 Jorg Janke, parts
11  * created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved.
12  * Contributor(s): ______________________________________.
13  *****************************************************************************/

14 package org.compiere.grid.ed;
15
16 import java.awt.*;
17 import javax.swing.*;
18 import java.awt.event.*;
19 import java.util.*;
20 import java.text.*;
21 import java.sql.*;
22 import java.math.*;
23
24 import org.compiere.util.*;
25 import org.compiere.apps.*;
26
27 /**
28  * Calculator with currency conversion
29  *
30  * @author Jorg Janke
31  * @version $Id: Calculator.java,v 1.6 2003/03/17 20:31:52 jjanke Exp $
32  */

33 public final class Calculator extends JDialog
34     implements ActionListener, KeyListener
35 {
36     /**
37      * Create Calculator
38      * @param frame parent
39      * @param title title
40      * @param displayType date or datetime or time
41      * @param format display format
42      * @param number initial amount
43      */

44     public Calculator(Frame frame, String JavaDoc title, int displayType,
45         DecimalFormat format, BigDecimal number)
46     {
47         super(frame, title, true);
48         setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
49         // Get WindowNo for Currency
50
m_WindowNo = Env.getWindowNo(frame);
51         //
52
m_DisplayType = displayType;
53         if (!DisplayType.isNumeric(m_DisplayType))
54             m_DisplayType = DisplayType.Number;
55         //
56
m_format = format;
57         if (m_format == null)
58             m_format = DisplayType.getNumberFormat(m_DisplayType);
59         //
60
m_number = number;
61         if (m_number == null)
62             m_number = new BigDecimal(0.0);
63         //
64
try
65         {
66             jbInit();
67             finishSetup();
68         }
69         catch(Exception JavaDoc ex)
70         {
71             Log.error("Calculator" + ex);
72         }
73     } // Calculator
74

75     /**
76      * Abbreviated Constructor
77      * @param frame parent
78      */

79     public Calculator(Frame frame)
80     {
81         this (frame, Msg.getMsg(Env.getCtx(), "Calculator"), DisplayType.Number, null, null);
82     } // Calculator
83

84     /**
85      * Abbreviated Constructor
86      * @param frame parent
87      * @param number initial amount
88      */

89     public Calculator(Frame frame, BigDecimal number)
90     {
91         this (frame, Msg.getMsg(Env.getCtx(), "Calculator"), DisplayType.Number, null, number);
92     } // Calculator
93

94     private BigDecimal m_number; // the current number
95
private String JavaDoc m_display = ""; // what is displayed
96
private int m_DisplayType;
97     private DecimalFormat m_format;
98     private int m_WindowNo;
99     private boolean m_abort = true;
100     private boolean m_currencyOK = false;
101
102     private final static String JavaDoc OPERANDS = "/*-+%";
103     private char m_decimal = '.';
104     //
105
private JPanel mainPanel = new JPanel();
106     private JPanel displayPanel = new JPanel();
107     private BorderLayout mainLayout = new BorderLayout();
108     private JPanel keyPanel = new JPanel();
109     private JLabel display = new JLabel();
110     private BorderLayout displayLayout = new BorderLayout();
111     private JButton b7 = new JButton();
112     private JButton b8 = new JButton();
113     private JButton b9 = new JButton();
114     private JButton b4 = new JButton();
115     private JButton b5 = new JButton();
116     private JButton b6 = new JButton();
117     private JButton b1 = new JButton();
118     private JButton b2 = new JButton();
119     private JButton b3 = new JButton();
120     private GridLayout keyLayout = new GridLayout();
121     private JButton bCur = new JButton();
122     private JButton bC = new JButton();
123     private JButton bDiv = new JButton();
124     private JButton bM = new JButton();
125     private JButton bMin = new JButton();
126     private JButton bProc = new JButton();
127     private JButton bAC = new JButton();
128     private JButton bResult = new JButton();
129     private JButton bDec = new JButton();
130     private JButton b0 = new JButton();
131     private JButton bPlus = new JButton();
132     private JPanel bordPanel = new JPanel();
133     private JPanel currencyPanel = new JPanel();
134     private BorderLayout bordLayout = new BorderLayout();
135     private JComboBox curFrom = new JComboBox();
136     private JComboBox curTo = new JComboBox();
137     private JLabel curLabel = new JLabel();
138     private FlowLayout currencyLayout = new FlowLayout();
139
140     /**
141      * Static init
142      * @throws Exception
143      */

144     void jbInit() throws Exception JavaDoc
145     {
146         mainPanel.setLayout(mainLayout);
147         displayPanel.setLayout(displayLayout);
148         keyPanel.setLayout(keyLayout);
149         mainLayout.setHgap(2);
150         mainLayout.setVgap(2);
151         mainPanel.setBorder(BorderFactory.createLoweredBevelBorder());
152         mainPanel.addKeyListener(this);
153         display.setBackground(Color.white);
154         display.setFont(new java.awt.Font JavaDoc("SansSerif", 0, 14));
155         display.setBorder(BorderFactory.createLoweredBevelBorder());
156         display.setText("0");
157         display.setHorizontalAlignment(SwingConstants.RIGHT);
158         b7.setText("7");
159         b8.setText("8");
160         b9.setText("9");
161         b4.setText("4");
162         b5.setText("5");
163         b6.setText("6");
164         b1.setText("1");
165         b2.setText("2");
166         b3.setText("3");
167         keyLayout.setColumns(5);
168         keyLayout.setHgap(3);
169         keyLayout.setRows(4);
170         keyLayout.setVgap(3);
171         bCur.setForeground(Color.yellow);
172         bCur.setToolTipText(Msg.getMsg(Env.getCtx(), "CurrencyConversion"));
173         bCur.setText("$");
174         bC.setForeground(Color.red);
175         bC.setText("C");
176         bDiv.setForeground(Color.blue);
177         bDiv.setText("/");
178         bM.setForeground(Color.blue);
179         bM.setText("*");
180         bMin.setForeground(Color.blue);
181         bMin.setText("-");
182         bProc.setForeground(Color.blue);
183         bProc.setText("%");
184         bAC.setForeground(Color.red);
185         bAC.setText("AC");
186         bResult.setForeground(Color.green);
187         bResult.setText("=");
188         bDec.setText(".");
189         b0.setText("0");
190         bPlus.setForeground(Color.blue);
191         bPlus.setText("+");
192         bordPanel.setLayout(bordLayout);
193         curLabel.setHorizontalAlignment(SwingConstants.CENTER);
194         curLabel.setHorizontalTextPosition(SwingConstants.CENTER);
195         curLabel.setText(" >> ");
196         currencyPanel.setLayout(currencyLayout);
197         bordLayout.setHgap(2);
198         bordLayout.setVgap(2);
199         displayLayout.setHgap(2);
200         displayLayout.setVgap(2);
201         currencyLayout.setHgap(3);
202         currencyLayout.setVgap(2);
203         displayPanel.setBackground(Color.white);
204         getContentPane().add(mainPanel);
205         mainPanel.add(displayPanel, BorderLayout.NORTH);
206         displayPanel.add(display, BorderLayout.CENTER);
207         mainPanel.add(bordPanel, BorderLayout.CENTER);
208         bordPanel.add(currencyPanel, BorderLayout.NORTH);
209         currencyPanel.add(curFrom, null);
210         currencyPanel.add(curLabel, null);
211         currencyPanel.add(curTo, null);
212         bordPanel.add(keyPanel, BorderLayout.CENTER);
213         keyPanel.add(bAC, null);
214         keyPanel.add(b7, null);
215         keyPanel.add(b8, null);
216         keyPanel.add(b9, null);
217         keyPanel.add(bM, null);
218         keyPanel.add(bC, null);
219         keyPanel.add(b4, null);
220         keyPanel.add(b5, null);
221         keyPanel.add(b6, null);
222         keyPanel.add(bDiv, null);
223         keyPanel.add(bProc, null);
224         keyPanel.add(b1, null);
225         keyPanel.add(b2, null);
226         keyPanel.add(b3, null);
227         keyPanel.add(bMin, null);
228         keyPanel.add(bCur, null);
229         keyPanel.add(b0, null);
230         keyPanel.add(bDec, null);
231         keyPanel.add(bResult, null);
232         keyPanel.add(bPlus, null);
233     } // jbInit
234

235     /**
236      * Finish Setup
237      */

238     private void finishSetup()
239     {
240         Insets in = new Insets(2, 2, 2, 2);
241
242         // For all buttons
243
Component[] comp = keyPanel.getComponents();
244         for (int i = 0; i < comp.length; i++)
245         {
246             if (comp[i] instanceof JButton)
247             {
248                 JButton b = (JButton)comp[i];
249                 b.setMargin(in);
250                 b.addActionListener(this);
251                 b.addKeyListener(this);
252             }
253         }
254         // Currency
255
toggleCurrency();
256
257         // Format setting
258
m_decimal = m_format.getDecimalFormatSymbols().getDecimalSeparator();
259
260         // display start number
261
m_display = m_format.format(m_number);
262         display.setText(m_display);
263     } // finishSetup
264

265     /**
266      * Action Listener
267      * @param e event
268      */

269     public void actionPerformed(ActionEvent e)
270     {
271         // Handle Button input
272
if (e.getSource() instanceof JButton)
273         {
274             String JavaDoc cmd = e.getActionCommand();
275             if (cmd != null && cmd.length() > 0)
276                 handleInput(cmd.charAt(0));
277         }
278         // Convert Amount
279
else if (e.getSource() == curTo)
280         {
281             KeyNamePair p = (KeyNamePair)curFrom.getSelectedItem();
282             int curFromID = p.getKey();
283             p = (KeyNamePair)curTo.getSelectedItem();
284             int curToID = p.getKey();
285             // convert
286
int AD_Client_ID = Env.getContextAsInt (Env.getCtx(), "#AD_Client_ID");
287             int AD_Org_ID = Env.getContextAsInt (Env.getCtx(), "#AD_Org_ID");
288             m_number = DB.getConvertedAmt(evaluate(), curFromID, curToID, AD_Client_ID, AD_Org_ID);
289             m_display = m_format.format(m_number);
290             display.setText(m_display);
291             curFrom.setSelectedItem(p);
292         }
293     } // actionPerformed
294

295     /**
296      * handle input
297      * @param c input character
298      */

299     public void handleInput(char c)
300     {
301     // System.out.println("Input: " + c);
302
switch (c)
303         {
304             // Number ===============================
305
case '0': case '1': case '2':
306             case '3': case '4': case '5':
307             case '6': case '7': case '8':
308             case '9':
309                 m_display += c;
310                 break;
311
312             // Decimal ===============================
313
case '.':
314             case ',':
315                 m_display += m_decimal;
316                 break;
317
318             // Commands ===============================
319
case '/': case '*':
320             case '-': case '+':
321             case '%':
322                 if (m_display.length() > 1)
323                 {
324                     char last = m_display.charAt(m_display.length()-1);
325                     if (OPERANDS.indexOf(last) == -1)
326                         m_display += c;
327                     else
328                         m_display = m_display.substring(0, m_display.length()-1) + c;
329                 }
330                 m_display = m_format.format(evaluate());
331                 if (c != '%')
332                     m_display += c;
333                 break;
334
335             // Clear last char
336
case 'C':
337                 if (m_display.length() > 0)
338                     m_display = m_display.substring(0, m_display.length()-1);
339                 break;
340
341             // Clear all
342
case 'A':
343                 m_display = "";
344                 break;
345
346             // Currency convert toggle
347
case '$':
348                 m_display = m_format.format(evaluate());
349                 toggleCurrency();
350                 break;
351
352             // fini
353
case '=':
354                 m_display = m_format.format(evaluate());
355                 m_abort = false;
356                 dispose();
357                 break;
358
359             // Error ===============================
360
default:
361                 ADialog.beep();
362                 break;
363         } // switch
364

365         if (m_display.equals(""))
366             m_display = "0";
367
368         // Eliminate leading zeroes
369
if (m_display.length() > 1 && m_display.startsWith("0"))
370             if (m_display.charAt(1) != ',' && m_display.charAt(1) != '.')
371                 m_display = m_display.substring(1);
372
373         // Display it
374
display.setText(m_display);
375     } // handleInput
376

377     /**
378      * Evaluate.
379      * - evaluate info in display and set number
380      * @return result
381      */

382     private BigDecimal evaluate()
383     {
384         // nothing or zero
385
if (m_display == null || m_display.equals("") || m_display.equals("0"))
386         {
387             m_number = new BigDecimal(0.0);
388             return m_number;
389         }
390
391         StringTokenizer st = new StringTokenizer(m_display, OPERANDS, true);
392
393         // first token
394
String JavaDoc token = st.nextToken();
395         // do we have a negative number ?
396
if (token.equals("-"))
397         {
398             if (st.hasMoreTokens())
399                 token += st.nextToken();
400             else
401             {
402                 m_number = new BigDecimal(0.0);
403                 return m_number;
404             }
405         }
406
407         // First Number
408
Number JavaDoc firstNumber;
409         try
410         {
411             firstNumber = m_format.parse(token);
412         }
413         catch (ParseException pe1)
414         {
415             Log.error("Calculator.evaluate - token: " + token, pe1);
416             m_number = new BigDecimal(0.0);
417             return m_number;
418         }
419         BigDecimal firstNo = new BigDecimal(firstNumber.toString());
420
421         // intermediate result
422
m_number = firstNo;
423
424         // only one number
425
if (!st.hasMoreTokens())
426             return m_number;
427
428         // now we should get an operand
429
token = st.nextToken();
430         if (OPERANDS.indexOf(token) == -1)
431         {
432             Log.error("Calculator.evaluate - Unknown token: " + token);
433             return m_number;
434         }
435         // get operand
436
char op = token.charAt(0);
437
438         // no second number
439
if (!st.hasMoreTokens())
440             return m_number;
441
442         token = st.nextToken();
443         Number JavaDoc secondNumber;
444         try
445         {
446             secondNumber = m_format.parse(token);
447         }
448         catch (ParseException pe2)
449         {
450             Log.error("Calculator.evaluate - token: " + token, pe2);
451             m_number = new BigDecimal(0.0);
452             return m_number;
453         }
454         BigDecimal secondNo = new BigDecimal(secondNumber.toString());
455
456         // Check the next operant
457
char op2 = 0;
458         if (st.hasMoreTokens())
459         {
460             token = st.nextToken();
461             if (OPERANDS.indexOf(token) == -1)
462             {
463                 Log.error("Calculator.evaluate - Unknown token: " + token);
464                 return m_number;
465             }
466             // get operand
467
op2 = token.charAt(0);
468         }
469
470         // Percent operation
471
if (op2 == '%')
472             secondNo = firstNo.multiply(secondNo).divide(new BigDecimal(100.0), m_format.getMaximumFractionDigits(), BigDecimal.ROUND_HALF_UP);
473
474         switch (op)
475         {
476             case '/':
477                 m_number = firstNo.divide(secondNo, m_format.getMaximumFractionDigits(), BigDecimal.ROUND_HALF_UP);
478                 break;
479             case '*':
480                 m_number = firstNo.multiply(secondNo);
481                 break;
482             case '-':
483                 m_number = firstNo.subtract(secondNo);
484                 break;
485             case '+':
486                 m_number = firstNo.add(secondNo);
487                 break;
488             default:
489                 break;
490         }
491         return m_number.setScale(m_format.getMaximumFractionDigits(), BigDecimal.ROUND_HALF_UP);
492     } // evaluate
493

494
495     /**
496      * Display or don't display Currency
497      */

498     private void toggleCurrency()
499     {
500         if (currencyPanel.isVisible())
501             currencyPanel.setVisible(false);
502         else
503         {
504             if (!m_currencyOK)
505                 loadCurrency();
506             currencyPanel.setVisible(true);
507         }
508         pack();
509     } // toggleCurrency
510

511     /**
512      * Load Currency
513      */

514     private void loadCurrency()
515     {
516         // Get Default
517
int C_Currency_ID = Env.getContextAsInt(Env.getCtx(), m_WindowNo, "C_Currency_ID");
518         if (C_Currency_ID == 0)
519             C_Currency_ID = Env.getContextAsInt(Env.getCtx(), "$C_Currency_ID");
520
521         String JavaDoc sql = "SELECT C_Currency_ID, ISO_Code FROM C_Currency "
522             + "WHERE IsActive='Y' ORDER BY 2";
523         KeyNamePair defaultValue = null;
524         try
525         {
526             Statement stmt = DB.createStatement();
527             ResultSet rs = stmt.executeQuery(sql);
528             while (rs.next())
529             {
530                 int id = rs.getInt("C_Currency_ID");
531                 String JavaDoc s = rs.getString("ISO_Code");
532                 KeyNamePair p = new KeyNamePair(id, s);
533                 curFrom.addItem(p);
534                 curTo.addItem(p);
535                 // Default
536
if (id == C_Currency_ID)
537                     defaultValue = p;
538             }
539             rs.close();
540             stmt.close();
541         }
542         catch (SQLException e)
543         {
544             Log.error("Calculator.loadCurrency", e);
545         }
546
547         // Set Defaults
548
if (defaultValue != null)
549         {
550             curFrom.setSelectedItem(defaultValue);
551             curTo.setSelectedItem(defaultValue);
552         }
553         // Set Listener
554
curTo.addActionListener(this);
555         m_currencyOK = true;
556     } // loadCurrency
557

558
559     /**
560      * Return Number
561      * @return result
562      */

563     public BigDecimal getNumber()
564     {
565         if (m_abort)
566             return null;
567
568         return m_number;
569     } // getNumber
570

571     /*************************************************************************/
572
573     /**
574      * KeyPressed Listener
575      * @param e event
576      */

577     public void keyPressed(KeyEvent e)
578     {
579         // sequence: pressed - typed(no KeyCode) - released
580

581         char input = e.getKeyChar();
582         int code = e.getKeyCode();
583
584         e.consume(); // does not work on JTextField
585

586         if (code == KeyEvent.VK_DELETE)
587             input = 'A';
588         else if (code == KeyEvent.VK_BACK_SPACE)
589             input = 'C';
590         else if (code == KeyEvent.VK_ENTER)
591             input = '=';
592         // abort
593
else if (code == KeyEvent.VK_CANCEL || code == KeyEvent.VK_ESCAPE)
594         {
595             m_abort = true;
596             dispose();
597             return;
598         }
599         handleInput(input);
600     }
601
602     /**
603      * KeyTyped Listener (nop)
604      * @param e event
605      */

606     public void keyTyped(KeyEvent e) {}
607     /**
608      * KeyReleased Listener (nop)
609      * @param e event
610      */

611     public void keyReleased(KeyEvent e) {}
612
613 } // Calculator
614

615
Popular Tags