-
Problem with inner class
I'm a first-year Java student, so please go easy on me.
I'm trying to create a GUI that allows generates a bill for mechanic services. I've defined the Swing components in an outer class, then define an inner class to do the event handling and logic. Problem is, the inner class doesn't recognize any of the components from the outer class, so I can't even get a clean compile.
Here's the code for the GUI/processor. (I actually execute another class containing only a "main" method that instantiates the JoesAuto class.)
----
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class JoesAuto extends JFrame
{
final private double OIL_CHANGE_CHARGE = 26.00;
final private double LUBE_JOB_CHARGE = 18.00;
final private double RAD_FLUSH_CHARGE = 30.00;
final private double TRAN_FLUSH_CHARGE = 80.00;
final private double INSPECTION_CHARGE = 15.00;
final private double MUFFLER_REPL_CHARGE = 100.00;
final private double TIRE_ROTATE_CHARGE = 20.00;
// constructor
public JoesAuto()
{
// superclass constructor
super("Service invoice");
// instantiate a frame
JFrame invoice = new JFrame();
// build a panel for the routine services checkboxes
JPanel routineServicesPanel = new JPanel();
routineServicesPanel.setLayout(new GridLayout(7, 1));
routineServicesPanel.setBorder(BorderFactory.createTitledBorder("Standard Services"));
// build the routine services checkboxes
final JCheckBox oilChange = new JCheckBox("Oil change -- $" + OIL_CHANGE_CHARGE);
final JCheckBox lubeJob = new JCheckBox("Lube job -- $" + LUBE_JOB_CHARGE);
final JCheckBox radFlush = new JCheckBox("Radiator flush -- $" + RAD_FLUSH_CHARGE);
final JCheckBox tranFlush = new JCheckBox("Transmission flush -- $" + TRAN_FLUSH_CHARGE);
final JCheckBox inspection = new JCheckBox("Inspection -- $" + INSPECTION_CHARGE);
final JCheckBox mufflerRepl = new JCheckBox("Muffler replacement -- $" + MUFFLER_REPL_CHARGE);
final JCheckBox tireRotate = new JCheckBox("Tire rotation -- $" + TIRE_ROTATE_CHARGE);
// add the routine services checkboxes to the routine services panel
routineServicesPanel.add(oilChange);
routineServicesPanel.add(lubeJob);
routineServicesPanel.add(radFlush);
routineServicesPanel.add(tranFlush);
routineServicesPanel.add(inspection);
routineServicesPanel.add(mufflerRepl);
routineServicesPanel.add(tireRotate);
// place the routine services panel at the top of the frame
add(routineServicesPanel, BorderLayout.NORTH);
// build a panel for the custom services text fields
JPanel customServicesPanel = new JPanel();
customServicesPanel.setLayout(new GridLayout(2, 3));
customServicesPanel.setBorder(BorderFactory.createTitledBorder("Custom Services"));
// build the custom services text fields
final JTextField customService = new JTextField("Service: ");
final JTextField customParts = new JTextField("Parts: ");
final JTextField customLabor = new JTextField("Labor: ");
final JTextField customTotal = new JTextField("Total: ");
customTotal.setEditable(false);
// add the custom services text fields to the custom services panel
customServicesPanel.add(customService);
customServicesPanel.add(customParts);
customServicesPanel.add(customLabor);
customServicesPanel.add(customTotal);
// place the custom services panel in the center of the frame
add(customServicesPanel, BorderLayout.CENTER);
// build a panel for the total and the action button
JPanel displayPanel = new JPanel();
// build labels and associated text/buttons
final JLabel totalLabel = new JLabel("TOTAL: ");
final JTextField total = new JTextField("$0000.00");
final JButton calculate = new JButton("Calculate");
// add a listener to the calculate button
CalcButtonListener listener = new CalcButtonListener();
// register the button listener
calculate.addActionListener(listener);
// add the display fields to the display panel
displayPanel.add(totalLabel);
displayPanel.add(total);
displayPanel.add(calculate);
// place the display panel at the bottom of the frame
add(displayPanel, BorderLayout.SOUTH);
// complete the frame definition
setSize(700, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setVisible(true);
} // terminates JoesAuto constructor
// build a private inner class to process the interrupt and
// handle the logic
// this class is still within the outer class, but not within the constructor
private class CalcButtonListener implements ActionListener
{
// the interrupt handler if the calculate button is clicked
public void actionPerformed(ActionEvent e)
{
// local variables
double routineCharges = 0;
double customPartsCharges = 0;
double customLaborCharges = 0;
double customTotalCharges = 0;
double totalCharges = 0;
JoesAuto jac = new JoesAuto();
// accumulate charges for the routine services
// ERROR "oilChange cannot be resolved"
// ERROR [this error occurs with lubeJob, radFlush, tranFlush ... as well]
if (oilChange.isSelected())
{
routineCharges =+ OIL_CHANGE_CHARGE;
}
if (lubeJob.isSelected())
{
routineCharges =+ LUBE_JOB_CHARGE;
}
if (radFlush.isSelected())
{
routineCharges =+ RAD_FLUSH_CHARGE;
}
if (tranFlush.isSelected())
{
routineCharges =+ TRAN_FLUSH_CHARGE;
}
if (inspection.isSelected())
{
routineCharges =+ INSPECTION_CHARGE;
}
if (mufflerRepl.isSelected())
{
routineCharges =+ MUFFLER_REPL_CHARGE;
}
if (tireRotate.isSelected())
{
routineCharges =+ TIRE_ROTATE_CHARGE;
}
// calculate custom charges from user entry
// ERROR "customParts cannot be resolved
customPartsCharges = Double.parseDouble(customParts.getText());
// ERROR "customLabor cannot be resolved
customLaborCharges = Double.parseDouble(customLabor.getText()) * 20.0;
customTotalCharges = customPartsCharges + customLaborCharges;
customTotal.setText("Total: " + customTotalCharges);
// sum routine charges and custom charges
totalCharges = customPartsCharges + customLaborCharges + routineCharges;
// display summed charges
// ERROR "displayPanel cannot be resolved
total.setText("Total: " + totalCharges);
} // terminates the actionPerformed method
} // terminates the private inner class
} // terminates JoesAuto class
----
The errors are marked with comments that say ERROR.
Can anybody help me out? I know it's just something stupid, but I can't find it.
Thanks in advance.
-
-
Yo,
You define a class, right? Than you want to acces some variables from the outter class ?
Wel, there is nothing wrong with this except if the variables are not properties of the outter class. What I saw in the code is that in the constructor you create some variables. Well the inner class has no idea of them and run time it will never get any idea.
1. Add reference to the objects you create as property of the outter class.
2. Use the fully qualified name of the variable:
public class JoesAuto extends JFrame {
// some suff
final JCheckBox oilChange;
// or final JCheckBox oilChange = new JCheckBox.....
// other stuff
private class CalcButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
JoesAuto.oilChange.doAnythingYouWant(<params>);
}
}
}
And I am not sure if you do not need to add a static modifier to the inner class.
NewUniverse
-
You're exactly right. The components in the outer class were defined locally to the constructor, but were never defined to the the outer class globally. Duh.
I got that part fixed.
Now I'm getting runtime errors (null pointer exceptions) on the check boxes.
What I want is for the user to be able to check the appropriate boxes for the routine services, add any custom services in the text fields, and then hit the "calculate" button and have everything tallied up. I don't want the system to calculate a total everytime a check box is checked or unchecked, so I didn't register an item listener for each checkbox component because that would trigger an event.
Is that the right way to look at it, or will I have to have those listeners and then code the logic to handle the checkbox event(s) one way and the "calculate" event another?
Thanks for the quick reply, by the way.
-
Specifically, the runtime errors I'm getting now are:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at JoesAuto$CheckBoxListener.itemStateChanged(JoesAuto.java:151)
at javax.swing.AbstractButton.fireItemStateChanged(Unknown Source)
at javax.swing.AbstractButton$Handler.itemStateChanged(Unknown Source)
at javax.swing.DefaultButtonModel.fireItemStateChanged(Unknown Source)
at javax.swing.JToggleButton$ToggleButtonModel.setSelected(Unknown Source)
at javax.swing.JToggleButton$ToggleButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
----
***? This happens if I 1) click any of the checkboxes;
2) enter any of the text fields;
3) click the calculate button.
The "null pointer exception" is coming out of the "oilChange" checkbox (that's Line 151). From what I can deduce, the JRE is trying to fire an ItemStateChanged event when the box is clicked, which passes the event up through the abstract.buttonhandler and the DefaultButton stuff etc.. But they all say "unknown source," which indicates that the don't know where the event came from. That would lead me to believe that the event isn't registered, but all the checkboxes have listeners registered to them in the constructor.
Is this another "duh"?
-
Let me show an even simpler example. This gets the same stupid NullPointerException on the displayTotal.getText().
---
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class CheckTest extends JFrame
{
private JTextField test;
private JTextField display;
private JButton work;
public CheckTest()
{
super("Services Invoice");
JFrame testFrame = new JFrame();
JTextField test = new JTextField(10);
JTextField display = new JTextField(10);
JButton work = new JButton("work");
JPanel testPanel = new JPanel();
testPanel.setLayout(new GridLayout(3, 1));
testPanel.add(test);
testPanel.add(display);
testPanel.add(work);
add(testPanel, BorderLayout.NORTH);
WorkButtonListener listener = new WorkButtonListener();
work.addActionListener(listener);
setSize(700, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setVisible(true);
}
private class WorkButtonListener implements ActionListener
{
// the interrupt handler if the calculate button is clicked
public void actionPerformed(ActionEvent e)
{
String displayTest = new String("");
displayTest = test.getText();
display.setText(displayTest);
}
}
}
----
This is not rocket science, yet the event handler seems to choke and puke on it every time.
Similar Threads
-
By Shailesh C.Rathod in forum .NET
Replies: 2
Last Post: 03-13-2002, 07:53 PM
-
Replies: 6
Last Post: 06-18-2001, 11:47 PM
-
By Patrick Ireland in forum .NET
Replies: 5
Last Post: 05-10-2001, 06:19 PM
-
By Patrick Ireland in forum .NET
Replies: 3
Last Post: 05-07-2001, 03:04 PM
-
Replies: 1
Last Post: 11-29-2000, 11:19 AM
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
Forum Rules
|
Top DevX Stories
Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL
|
Bookmarks