NullPointerException - Cannot get the value from variable f_cashGiven
In SubCheckout.java (a POS), what I want is when Payment button (f_cashPayment) is pressed, the action "Cash" is performed, get the value from Cash Given (f_cashGiven), do the subtraction and post the value as Cash Return (f_cashReturn). The code is filled in actionPerformed. But I cannot get the value by using f_cashGiven.getValue() from VNumber class. It returns NULL.This should be quite straight forward, but I do not know what is wrong. Please help!
Enclosed please find the source code of SubCheckout.java and VNumber.java
This is the code of SubCheckout.java :
/******************************************************************************
* The contents of this file are subject to theCompiere License Version 1.1
* ("License"); You may not use this file except in compliance with the License
* You may obtain a copy of the License at http://www.compiere.org/license.html
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
* The Original Code is Compiere ERP & CRM Smart Business Solution. The Initial
* Developer of the Original Code is Jorg Janke. Portions created by Jorg Janke
* are Copyright (C) 1999-2005 Jorg Janke.
* All parts are Copyright (C) 1999-2005 ComPiere, Inc. All Rights Reserved.
* Contributor(s): __.
*****************************************************************************/
package org.compiere.pos;
import java.awt.*;
import java.awt.event.*;
import java.math.BigDecimal;
import javax.swing.border.*;
import org.compiere.grid.ed.*;
import org.compiere.swing.*;
import org.compiere.util.*;
/**
*POS Checkout Sub Panel
*
* @author Jorg Janke
* @version $Id: SubCheckout.java,v 1.3 2005/03/11 20:28:22 jjanke Exp $
*/
publicclass SubCheckoutextends PosSubPanelimplements ActionListener
{
/**
* Constructor
*@param posPanel POS Panel
*/
public SubCheckout (PosPanel posPanel)
{
super (posPanel);
}//PosSubCheckout
private CButton f_register =null;
private CButton f_summary =null;
private CButton f_process =null;
private CButton f_print =null;
private CLabel f_lcreditCardNumber =null;
private CTextField f_creditCardNumber =null;
private CLabel f_lcreditCardExp =null;
private CTextField f_creditCardExp =null;
private CLabel f_lcreditCardVV =null;
private CTextField f_creditCardVV =null;
private CButton f_cashPayment =null;
private CLabel f_lcashGiven =null;
private VNumber f_cashGiven =null;
private CLabel f_lcashReturn =null;
private VNumber f_cashReturn =null;
private CButton f_creditPayment =null;
/**Logger*/
privatestatic CLogger log = CLogger.getCLogger(SubCheckout.class);
/**
* Initialize
*/
publicvoid init()
{
//Title
TitledBorder border =new TitledBorder(Msg.getMsg(Env.getCtx(),"Checkout"));
setBorder(border);
//Content
setLayout(new GridBagLayout());
GridBagConstraints gbc =new GridBagConstraints();
gbc.insets = INSETS2;
//--0
gbc.gridx = 0;
f_register = createButtonAction("Register",null);
gbc.gridy = 0;
add (f_register, gbc);
//
f_summary = createButtonAction("Summary",null);
gbc.gridy = 1;
add (f_summary, gbc);
//
f_process = createButtonAction("Process",null);
gbc.gridy = 2;
add (f_process, gbc);
//
f_print = createButtonAction("Print",null);
gbc.gridy = 3;
add (f_print, gbc);
//--1 -- Cash
gbc.gridx = 1;
gbc.gridheight = 2;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = .1;
CPanel cash =new CPanel(new GridBagLayout());
cash.setBorder(new TitledBorder(Msg.getMsg(Env.getCtx(),"Cash")));
gbc.gridy = 0;
add (cash, gbc);
GridBagConstraints gbc0 =new GridBagConstraints();
gbc0.insets = INSETS2;
gbc0.anchor = GridBagConstraints.WEST;
//
f_lcashGiven =new CLabel(Msg.getMsg(Env.getCtx(),"CashGiven"));
cash.add (f_lcashGiven, gbc0);
f_cashGiven =new VNumber("CashGiven", false, false, true, DisplayType.Amount,
Msg.translate(Env.getCtx(),"CashGiven"));
f_cashGiven.addActionListener(this);
f_cashGiven.setColumns(10, 25);
cash.add (f_cashGiven, gbc0);
f_cashGiven.setValue(Env.ZERO);
//
f_lcashReturn =new CLabel(Msg.getMsg(Env.getCtx(),"CashReturn"));
cash.add (f_lcashReturn, gbc0);
f_cashReturn =new VNumber("CashReturn", false, true, false, DisplayType.Amount,
"CashReturn");
f_cashReturn.setColumns(10, 25);
cash.add (f_cashReturn, gbc0);
f_cashReturn.setValue(Env.ZERO);
//
f_cashPayment = createButtonAction("Payment",null);
f_cashPayment.setActionCommand("Cash");
gbc0.anchor = GridBagConstraints.EAST;
gbc0.weightx = 0.1;
cash.add (f_cashPayment, gbc0);
//--1 -- Creditcard
CPanel creditcard =new CPanel(new GridBagLayout());
creditcard.setBorder(new TitledBorder(Msg.translate(Env.getCtx(),"CreditCardType")));
gbc.gridy = 2;
add (creditcard, gbc);
GridBagConstraints gbc1 =new GridBagConstraints();
gbc1.insets = INSETS2;
gbc1.anchor = GridBagConstraints.WEST;
gbc1.gridx = 0;
gbc1.gridy = 0;
f_lcreditCardNumber =new CLabel(Msg.translate(Env.getCtx(),"CreditCardNumber"));
creditcard.add (f_lcreditCardNumber, gbc1);
gbc1.gridy = 1;
f_creditCardNumber =new CTextField(18);
creditcard.add (f_creditCardNumber, gbc1);
gbc1.gridx = 1;
gbc1.gridy = 0;
f_lcreditCardExp =new CLabel(Msg.translate(Env.getCtx(),"CreditCardExp"));
creditcard.add (f_lcreditCardExp, gbc1);
gbc1.gridy = 1;
f_creditCardExp =new CTextField(5);
creditcard.add (f_creditCardExp, gbc1);
gbc1.gridx = 2;
gbc1.gridy = 0;
f_lcreditCardVV =new CLabel(Msg.translate(Env.getCtx(),"CreditCardVV"));
creditcard.add (f_lcreditCardVV, gbc1);
gbc1.gridy = 1;
f_creditCardVV =new CTextField(5);
creditcard.add (f_creditCardVV, gbc1);
//
gbc1.gridx = 3;
gbc1.gridy = 0;
gbc1.gridheight = 2;
f_creditPayment = createButtonAction("Payment",null);
f_creditPayment.setActionCommand("CreditCard");
gbc1.anchor = GridBagConstraints.EAST;
gbc1.weightx = 0.1;
creditcard.add (f_creditPayment, gbc1);
}//init
/**
* Get Panel Position
*/
public GridBagConstraints getGridBagConstraints()
{
GridBagConstraints gbc = super.getGridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 3;
return gbc;
}//getGridBagConstraints
/**
* Dispose - Free Resources
*/
publicvoid dispose()
{
super.dispose();
}//dispose
/**
* Action Listener
*@param e event
*/
publicvoid actionPerformed (ActionEvent e)
{
String action = e.getActionCommand();
if (action ==null || action.length() == 0)
return;
log.info("PosSubCheckout - actionPerformed: " + action);
if (e.getSource() == f_cashGiven){
f_cashGiven.setValue(f_cashGiven.getValue());
System.out.println("f_cashGiven"+f_cashGiven.getDisplay());
}
//Register
//Summary
if (action.equals("Cash")){
BigDecimal CashGiven, GrandTotal, CashReturn;
System.out.println("Cash given is "+f_cashGiven.getDisplay());
CashGiven = (BigDecimal)f_cashGiven.getValue();
GrandTotal = (BigDecimal)p_posPanel.f_curLine.getOrder().getGrandTotal();
CashReturn = CashGiven.subtract(GrandTotal);
f_cashReturn.setValue(CashReturn);
}
//Cash (Payment)
//CreditCard (Payment)
}//actionPerformed
}//PosSubCheckout
This is the code of VNumber.java :
/******************************************************************************
* The contents of this file are subject to theCompiere License Version 1.1
* ("License"); You may not use this file except in compliance with the License
* You may obtain a copy of the License at http://www.compiere.org/license.html
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
* The Original Code is Compiere ERP & CRM Smart Business Solution. The Initial
* Developer of the Original Code is Jorg Janke. Portions created by Jorg Janke
* are Copyright (C) 1999-2005 Jorg Janke.
* All parts are Copyright (C) 1999-2005 ComPiere, Inc. All Rights Reserved.
* Contributor(s): __.
*****************************************************************************/
package org.compiere.grid.ed;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.math.*;
import java.text.*;
import java.util.logging.*;
import javax.swing.*;
import javax.swing.text.*;
import org.compiere.apps.*;
import org.compiere.model.*;
import org.compiere.swing.*;
import org.compiere.util.*;
/**
*Number Control
*
* @author Jorg Janke
* @version $Id: VNumber.java,v 1.41 2005/09/03 01:57:16 jjanke Exp $
*/
publicfinalclass VNumberextends JComponent
implements VEditor, ActionListener, KeyListener, FocusListener
{
/**Number of Columns (12)*/
publicfinalstaticint SIZE = 12;
/**
* IDE Bean Constructor
*/
public VNumber()
{
this("Number", false, false, true, DisplayType.Number,"Number");
}// VNumber
/**
*Create right aligned Number field.
*no popup, if WindowNo == 0 (for IDs)
* @param columnName column name
* @param mandatory mandatory
* @param isReadOnly read only
* @param isUpdateable updateable
* @param displayType display type
* @param title title
*/
public VNumber(String columnName,boolean mandatory,boolean isReadOnly,boolean isUpdateable,
int displayType, String title)
{
super();
super.setName(columnName);
m_columnName = columnName;
m_title = title;
setDisplayType(displayType);
//
LookAndFeel.installBorder(this,"TextField.border");
this.setLayout(new BorderLayout());
//this.setPreferredSize(m_text.getPreferredSize());//causes r/o to be the same length
//int height = m_text.getPreferredSize().height;
//setMinimumSize(new Dimension (30,height));
//***Text***
m_text.setBorder(null);
m_text.setHorizontalAlignment(JTextField.TRAILING);
m_text.addKeyListener(this);
m_text.addFocusListener(this);
//Background
setMandatory(mandatory);
this.add(m_text, BorderLayout.CENTER);
//***Button***
m_button.setIcon(Env.getImageIcon("Calculator10.gif"));
m_button.setMargin(new Insets(0, 0, 0, 0));
m_button.setFocusable(false);
m_button.addActionListener(this);
this.add (m_button, BorderLayout.EAST);
//Prefereed Size
this.setPreferredSize(this.getPreferredSize());//causes r/o to be the same length
// Size
setColumns(SIZE, CComboBox.FIELD_HIGHT-4);
//ReadWrite
if (isReadOnly || !isUpdateable)
setReadWrite(false);
else
setReadWrite(true);
}//VNumber
/**
* Dispose
*/
publicvoid dispose()
{
m_text =null;
m_button =null;
m_mField =null;
}// dispose
/**
*Set Document
* @param doc document
*/
protectedvoid setDocument(Document doc)
{
m_text.setDocument(doc);
}//getDocument
private Stringm_columnName;
protectedintm_displayType;// Currency / UoM via Context
private DecimalFormatm_format;
private Stringm_title;
privatebooleanm_setting;
private Stringm_oldText;
private Stringm_initialText;
privatebooleanm_rangeSet =false;
private Doublem_minValue;
private Doublem_maxValue;
privatebooleanm_modified =false;
/** The Field*/
private CTextFieldm_text =new CTextField(SIZE);//Standard
/** The Button*/
private CButtonm_button =new CButton();
private MField m_mField =null;
/**Logger*/
privatestatic CLogger log = CLogger.getCLogger(VNumber.class);
/**
* Set no of Columns
*@param columns columns
*/
publicvoid setColumns (int columns,int height)
{
m_text.setPreferredSize(null);
m_text.setColumns(columns);
Dimension size = m_text.getPreferredSize();
if (height > size.height)//default 16
size.height = height;
if (CComboBox.FIELD_HIGHT-4 > size.height)
size.height = VLookup.FIELD_HIGHT-4;
this.setPreferredSize(size);//causes r/o to be the same length
this.setMinimumSize(new Dimension (columns*10, size.height));
m_button.setPreferredSize(new Dimension(size.height, size.height));
}//setColumns
/**
*Set Range with min & max
* @param minValue min value
* @param maxValue max value
*@return true, if accepted
*/
publicboolean setRange(Double minValue, Double maxValue)
{
m_rangeSet =true;
m_minValue = minValue;
m_maxValue = maxValue;
return m_rangeSet;
}//setRange
/**
*Set Range with min & max = parse US style number w/o Gouping
* @param minValue min value
* @param maxValue max value
* @return true if accepted
*/
publicboolean setRange(String minValue, String maxValue)
{
if (minValue ==null || maxValue ==null)
returnfalse;
try
{
m_minValue = Double.valueOf(minValue);
m_maxValue = Double.valueOf(maxValue);
}
catch (NumberFormatException nfe)
{
returnfalse;
}
m_rangeSet =true;
return m_rangeSet;
}//setRange
/**
* Set and check DisplayType
* @param displayType display type
*/
publicvoid setDisplayType (int displayType)
{
m_displayType = displayType;
if (!DisplayType.isNumeric(displayType))
m_displayType = DisplayType.Number;
m_format = DisplayType.getNumberFormat(displayType);
m_text.setDocument (new MDocNumber(displayType, m_format, m_text, m_title));
}// setDisplayType
/**
*Set ReadWrite
* @param value value
*/
publicvoid setReadWrite (boolean value)
{
if (m_text.isReadWrite() != value)
m_text.setReadWrite(value);
if (m_button.isReadWrite() != value)
m_button.setReadWrite(value);
//Don't show button if not ReadWrite
if (m_button.isVisible() != value)
m_button.setVisible(value);
}//setReadWrite
/**
*IsReadWrite
* @return true if rw
*/
publicboolean isReadWrite()
{
return m_text.isReadWrite();
}//isReadWrite
/**
*Set Mandatory (and back bolor)
* @param mandatory mandatory
*/
publicvoid setMandatory (boolean mandatory)
{
m_text.setMandatory(mandatory);
}//setMandatory
/**
*Is it mandatory
* @return true if mandatory
*/
publicboolean isMandatory()
{
return m_text.isMandatory();
}//isMandatory
/**
*Set Background
* @param color color
*/
publicvoid setBackground(Color color)
{
m_text.setBackground(color);
}//setBackground
/**
*Set Background
* @param error error
*/
publicvoid setBackground (boolean error)
{
m_text.setBackground(error);
}//setBackground
/**
* Set Foreground
* @param fg foreground
*/
publicvoid setForeground(Color fg)
{
m_text.setForeground(fg);
}// setForeground
/**
*Set Editor to value
* @param value value
*/
publicvoid setValue(Object value)
{
log.finest("Value=" + value);
if (value ==null)
m_oldText ="";
else
m_oldText = m_format.format(value);
//only set when not updated here
if (m_setting)
return;
m_text.setText (m_oldText);
m_initialText = m_oldText;
m_modified =false;
}//setValue
/**
* Property Change Listener
* @param evt event
*/
publicvoid propertyChange (PropertyChangeEvent evt)
{
if (evt.getPropertyName().equals(org.compiere.model.MField.PROPERTY))
setValue(evt.getNewValue());
}// propertyChange
/**
*Return Editor value
* @return value value (big decimal or integer)
*/
public Object getValue()
{
if (m_text ==null || m_text.getText() ==null || m_text.getText().length() == 0)
returnnull;
String value = m_text.getText();
//return 0 if text deleted
if (value ==null || value.length() == 0)
{
if (!m_modified)
returnnull;
if (m_displayType == DisplayType.Integer)
returnnew Integer(0);
return Env.ZERO;
}
if (value.equals(".") || value.equals(",") || value.equals("-"))
value ="0";
try
{
Number number = m_format.parse(value);
value = number.toString();//converts it to US w/o thousands
BigDecimal bd =new BigDecimal(value);
if (m_displayType == DisplayType.Integer)
returnnew Integer(bd.intValue());
if (bd.signum() == 0)
return bd;
return bd.setScale(m_format.getMaximumFractionDigits(), BigDecimal.ROUND_HALF_UP);
}
catch (Exception e)
{
log.log(Level.SEVERE,"Value=" + value, e);
}
if (m_displayType == DisplayType.Integer)
returnnew Integer(0);
return Env.ZERO;
}//getValue
/**
* Return Display Value
* @return value
*/
public String getDisplay()
{
return m_text.getText();
}// getDisplay
/**
* Get Title
*@return title
*/
public String getTitle()
{
return m_title;
}//getTitle
/**
* Plus - add one.
* Also sets Value
*@return new value
*/
public Object plus()
{
Object value = getValue();
if (value ==null)
{
if (m_displayType == DisplayType.Integer)
value =new Integer(0);
else
value = Env.ZERO;
}
//Add
if (valueinstanceof BigDecimal)
value = ((BigDecimal)value).add(Env.ONE);
else
value =new Integer(((Integer)value).intValue() + 1);
//
setValue(value);
return value;
}//plus
/**
* Minus - subtract one, but not below minimum.
* Also sets Value
*@param minimum minimum
*@return new value
*/
public Object minus (int minimum)
{
Object value = getValue();
if (value ==null)
{
if (m_displayType == DisplayType.Integer)
value =new Integer(minimum);
else
value =new BigDecimal(minimum);
setValue(value);
return value;
}
//Subtract
if (valueinstanceof BigDecimal)
{
BigDecimal bd = ((BigDecimal)value).subtract(Env.ONE);
BigDecimal min =new BigDecimal(minimum);
if (bd.compareTo(min) < 0)
value = min;
else
value = bd;
}
else
{
int i = ((Integer)value).intValue();
i--;
if (i < minimum)
i = minimum;
value =new Integer(i);
}
//
setValue(value);
return value;
}//minus
/**************************************************************************
*Action Listener
* @param e event
*/
publicvoid actionPerformed (ActionEvent e)
{
log.config(e.getActionCommand());
if (ValuePreference.NAME.equals(e.getActionCommand()))
{
if (MRole.getDefault().isShowPreference())
ValuePreference.start (m_mField, getValue());
return;
}
if (e.getSource() == m_button)
{
m_button.setEnabled(false);
String str = startCalculator(this, m_text.getText(), m_format, m_displayType, m_title);
m_text.setText(str);
m_button.setEnabled(true);
try
{
fireVetoableChange (m_columnName, m_oldText, getValue());
}
catch (PropertyVetoException pve){}
m_text.requestFocus();
}
}//actionPerformed
/**************************************************************************
*Key Listener Interface
* @param e event
*/
publicvoid keyTyped(KeyEvent e){}
publicvoid keyPressed(KeyEvent e){}
/**
*Key Listener.
*- Escape - Restore old Text
*- firstChange- signal change
* @param e event
*/
publicvoid keyReleased(KeyEvent e)
{
log.finest("Key=" + e.getKeyCode() +" - " + e.getKeyChar()
+" -> " + m_text.getText());
// ESC
if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
m_text.setText(m_initialText);
m_modified =true;
m_setting =true;
try
{
if (e.getKeyCode() == KeyEvent.VK_ENTER)//10
{
fireVetoableChange (m_columnName, m_oldText, getValue());
fireActionPerformed();
}
else//indicate change
fireVetoableChange (m_columnName, m_oldText,null);
}
catch (PropertyVetoException pve){}
m_setting =false;
}//keyReleased
/**
*Focus Gained
* @param e event
*/
publicvoid focusGained (FocusEvent e)
{
if (m_text !=null)
m_text.selectAll();
}//focusGained
/**
*Data Binding to MTable (via GridController.vetoableChange).
* @param e event
*/
publicvoid focusLost (FocusEvent e)
{
//log.finest(e.toString());
//APanel - Escape
if (e.getOppositeComponent()instanceof AGlassPane)
{
m_text.setText(m_initialText);
return;
}
try
{
fireVetoableChange (m_columnName, m_initialText, getValue());
fireActionPerformed();
}
catch (PropertyVetoException pve){}
}// focusLost
/**
*Invalid Entry - Start Calculator
* @param jc parent
* @param value value
* @param format format
* @param displayType display type
* @param title title
* @return value
*/
publicstatic String startCalculator(Container jc, String value,
DecimalFormat format,int displayType, String title)
{
log.config("Value=" + value);
BigDecimal startValue =new BigDecimal(0.0);
try
{
if (value !=null && value.length() > 0)
{
Number number = format.parse(value);
startValue =new BigDecimal (number.toString());
}
}
catch (ParseException pe)
{
log.info("InvalidEntry - " + pe.getMessage());
}
//Find frame
Frame frame = Env.getFrame(jc);
//Actual Call
Calculator calc =new Calculator(frame, title,
displayType, format, startValue);
AEnv.showCenterWindow(frame, calc);
BigDecimal result = calc.getNumber();
log.config("Result=" + result);
//
calc =null;
if (result !=null)
return format.format(result);
else
return value;//original value
}//startCalculator
/**
* Set Field/WindowNo for ValuePreference
* @param mField field
*/
publicvoid setField (MField mField)
{
m_mField = mField;
/**
if (m_mField != null
&& MRole.getDefault().isShowPreference())
ValuePreference.addMenu (this, popupMenu);
**/
}// setField
/**************************************************************************
* Remove Action Listner
* @param l Action Listener
*/
publicvoid removeActionListener(ActionListener l)
{
listenerList.remove(ActionListener.class, l);
}//removeActionListener
/**
* Add Action Listner
* @param l Action Listener
*/
publicvoid addActionListener(ActionListener l)
{
listenerList.add(ActionListener.class, l);
}//addActionListener
/**
* Fire Action Event to listeners
*/
protectedvoid fireActionPerformed()
{
int modifiers = 0;
AWTEvent currentEvent = EventQueue.getCurrentEvent();
if (currentEventinstanceof InputEvent)
modifiers = ((InputEvent)currentEvent).getModifiers();
elseif (currentEventinstanceof ActionEvent)
modifiers = ((ActionEvent)currentEvent).getModifiers();
ActionEvent ae =new ActionEvent (this, ActionEvent.ACTION_PERFORMED,
"VNumber", EventQueue.getMostRecentEventTime(), modifiers);
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2)
{
if (listeners[i]==ActionListener.class)
{
((ActionListener)listeners[i+1]).actionPerformed(ae);
}
}
}//fireActionPerformed
/**/
}//VNumber

