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

//Print

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

[46703 byte] By [ng_terrya] at [2007-10-2 9:39:44]
# 1
hellohe code you have posted is too long for me (and probably anyone else) to bother with
centurionsa at 2007-7-16 23:45:45 > top of Java-index,Developer Tools,Debugging and Profiling Tool APIs...
# 2

If getValue() returns null, you need to trace the execution of the code and figure out which sequence of code is leading to the return of null. This method looks complex - a lot of if statements. If you do not have a debugger, put System.out.println statements inside the method to figure out what's going on.

atmguya at 2007-7-16 23:45:45 > top of Java-index,Developer Tools,Debugging and Profiling Tool APIs...