2 Replies - 2360 Views - Last Post: 16 August 2011 - 11:17 AM Rate Topic: -----

#1 Charlie IronGleet  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 225
  • Joined: 29-January 09

Local variable accessed from within inner class - needs to be final

Posted 16 August 2011 - 09:09 AM

Hi,

I received the following errors whilst building part of a GUI:

javac "NetConnectMenuBar.java" (in directory: /media/HP v125w/NetConnect8-15)
NetConnectMenuBar.java:67: local variable cardPanel is accessed from within inner class; needs to be declared final
cardLayout.first(cardPanel); ^
NetConnectMenuBar.java:67: local variable cardLayout is accessed from within inner class; needs to be declared final
cardLayout.first(cardPanel);
^

If someone could explain to me why I get these errors despite the fact that I have used the 'final' modifier and how to fix my code, I'd greatly appreciate it. Here is the code:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class NetConnectMenuBar extends JMenuBar { 
	private JMenu fileMenu;
	private JMenu settingsMenu;
	private JMenu helpMenu;
	private JMenu aboutMenu;
	private JMenu productMenu;
	
	private JMenuItem newInquiry, openInquiry, save, saveAs, exit;
	private JMenuItem setPassword, setSubcode, setCustomerID;
	
	final CardLayout cardLayout;
	final JPanel cardPanel;
	
	public NetConnectMenuBar(CardLayout cardLayout, JPanel cardPanel) {
		this.cardLayout = cardLayout;
		this.cardPanel = cardPanel;
		
		
		fileMenu = new JMenu("File");
		settingsMenu = new JMenu("Settings");
		helpMenu = new JMenu("Help Menu");
		aboutMenu = new JMenu("About");
		productMenu = new JMenu("Data Products");
		
		fileMenu.add(newInquiry = new JMenuItem("New Inquiry"));
		fileMenu.add(openInquiry = new JMenuItem("Open Inquiry"));
		fileMenu.add(save = new JMenuItem("Save Data"));
		fileMenu.add(saveAs = new JMenuItem("Save Data As"));
		fileMenu.add(exit = new JMenuItem("Exit"));
		
		settingsMenu.add("Set Password");
		settingsMenu.add("Set Subcode");
		settingsMenu.add("Set Customer ID");
		
		productMenu.add("Credit Report");
		productMenu.add("Credit Report with Score");
		productMenu.add("Criminal Background Check");
		productMenu.add("Insurance Risk Scores");
		productMenu.add("Address Check");
		productMenu.add("Connect Check");
		productMenu.add("Evictions");
		productMenu.add("Skip Tracing");
		productMenu.add("Instant Prescreen");
		productMenu.add("Healthcare Profile");
		productMenu.add("Precise ID");
		
		helpMenu.add("User's Manual");
		helpMenu.add("Technical Support");
		helpMenu.add("New Product Subscription");
		
		aboutMenu.add("...");
		aboutMenu.add("About Net Connect");
		
		add(fileMenu);
		add(settingsMenu);
		add(productMenu);
		add(helpMenu);
		add(aboutMenu);
		
		// Menu Item action listeners below:
		newInquiry.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				cardLayout.first(cardPanel);
			}
		});
	}
}



Thanks Again!!!

This post has been edited by Charlie IronGleet: 16 August 2011 - 09:10 AM


Is This A Good Question/Topic? 0
  • +

Replies To: Local variable accessed from within inner class - needs to be final

#2 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 992
  • Posts: 972
  • Joined: 30-September 10

Re: Local variable accessed from within inner class - needs to be final

Posted 16 August 2011 - 10:35 AM

Hi,

You need to declare the parameters to the constructor as 'final', not the instance variables:

public NetConnectMenuBar(final CardLayout cardLayout, final JPanel cardPanel) {
...
}



The reason for this is because this line:

...new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				cardLayout.first(cardPanel);
			}
		}...


creates an inner class. The actionPerformed method which is inside the inner class uses the 'cardLayout' and the 'cardPanel' parameters. However, those two variables are parameters will 'disappear' after the method (or, more specifically, the constructor in this case) returns, meaning the values will be lost. Therefore, when the actionPerformed() method is called later, the method will try to use variables that no longer exist, with potentially disastrous consequences.

To get around this, the compiler makes copies of the parameters to your constructor for use in the inner class. The values of those parameters shouldn't be changed after the copy has been made, so they must be declared as final.

This post has been edited by CodingSup3rnatur@l-360: 16 August 2011 - 10:53 AM

Was This Post Helpful? 0
  • +
  • -

#3 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8343
  • View blog
  • Posts: 31,890
  • Joined: 06-March 08

Re: Local variable accessed from within inner class - needs to be final

Posted 16 August 2011 - 11:17 AM

This is why I never use anonymous class (which you have, it is not an inner class it is an anonymous class)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1