1 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 33 public final class Calculator extends JDialog 34 implements ActionListener, KeyListener 35 { 36 44 public Calculator(Frame frame, String title, int displayType, 45 DecimalFormat format, BigDecimal number) 46 { 47 super(frame, title, true); 48 setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 49 m_WindowNo = Env.getWindowNo(frame); 51 m_DisplayType = displayType; 53 if (!DisplayType.isNumeric(m_DisplayType)) 54 m_DisplayType = DisplayType.Number; 55 m_format = format; 57 if (m_format == null) 58 m_format = DisplayType.getNumberFormat(m_DisplayType); 59 m_number = number; 61 if (m_number == null) 62 m_number = new BigDecimal(0.0); 63 try 65 { 66 jbInit(); 67 finishSetup(); 68 } 69 catch(Exception ex) 70 { 71 Log.error("Calculator" + ex); 72 } 73 } 75 79 public Calculator(Frame frame) 80 { 81 this (frame, Msg.getMsg(Env.getCtx(), "Calculator"), DisplayType.Number, null, null); 82 } 84 89 public Calculator(Frame frame, BigDecimal number) 90 { 91 this (frame, Msg.getMsg(Env.getCtx(), "Calculator"), DisplayType.Number, null, number); 92 } 94 private BigDecimal m_number; private String m_display = ""; 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 OPERANDS = "/*-+%"; 103 private char m_decimal = '.'; 104 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 144 void jbInit() throws Exception 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 ("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 } 235 238 private void finishSetup() 239 { 240 Insets in = new Insets(2, 2, 2, 2); 241 242 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 toggleCurrency(); 256 257 m_decimal = m_format.getDecimalFormatSymbols().getDecimalSeparator(); 259 260 m_display = m_format.format(m_number); 262 display.setText(m_display); 263 } 265 269 public void actionPerformed(ActionEvent e) 270 { 271 if (e.getSource() instanceof JButton) 273 { 274 String cmd = e.getActionCommand(); 275 if (cmd != null && cmd.length() > 0) 276 handleInput(cmd.charAt(0)); 277 } 278 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 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 } 295 299 public void handleInput(char c) 300 { 301 switch (c) 303 { 304 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 case '.': 314 case ',': 315 m_display += m_decimal; 316 break; 317 318 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 case 'C': 337 if (m_display.length() > 0) 338 m_display = m_display.substring(0, m_display.length()-1); 339 break; 340 341 case 'A': 343 m_display = ""; 344 break; 345 346 case '$': 348 m_display = m_format.format(evaluate()); 349 toggleCurrency(); 350 break; 351 352 case '=': 354 m_display = m_format.format(evaluate()); 355 m_abort = false; 356 dispose(); 357 break; 358 359 default: 361 ADialog.beep(); 362 break; 363 } 365 if (m_display.equals("")) 366 m_display = "0"; 367 368 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.setText(m_display); 375 } 377 382 private BigDecimal evaluate() 383 { 384 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 String token = st.nextToken(); 395 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 Number 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 m_number = firstNo; 423 424 if (!st.hasMoreTokens()) 426 return m_number; 427 428 token = st.nextToken(); 430 if (OPERANDS.indexOf(token) == -1) 431 { 432 Log.error("Calculator.evaluate - Unknown token: " + token); 433 return m_number; 434 } 435 char op = token.charAt(0); 437 438 if (!st.hasMoreTokens()) 440 return m_number; 441 442 token = st.nextToken(); 443 Number 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 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 op2 = token.charAt(0); 468 } 469 470 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 } 494 495 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 } 511 514 private void loadCurrency() 515 { 516 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 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 s = rs.getString("ISO_Code"); 532 KeyNamePair p = new KeyNamePair(id, s); 533 curFrom.addItem(p); 534 curTo.addItem(p); 535 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 if (defaultValue != null) 549 { 550 curFrom.setSelectedItem(defaultValue); 551 curTo.setSelectedItem(defaultValue); 552 } 553 curTo.addActionListener(this); 555 m_currencyOK = true; 556 } 558 559 563 public BigDecimal getNumber() 564 { 565 if (m_abort) 566 return null; 567 568 return m_number; 569 } 571 572 573 577 public void keyPressed(KeyEvent e) 578 { 579 581 char input = e.getKeyChar(); 582 int code = e.getKeyCode(); 583 584 e.consume(); 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 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 606 public void keyTyped(KeyEvent e) {} 607 611 public void keyReleased(KeyEvent e) {} 612 613 } 615 | Popular Tags |