Hello people,

I created an innter class like this

public class OuterClass{

   int attribute=0;

   class InnerClass {
      public void method1(){
        attribute++;
      }

      public void method2(){
        System.out.println(attribute);
      }
   }

My problem is when I call method2() in a correct way, it displays 0 and not 1 as I wanted. Can you help to fix this ? Thank you very much
}

How would the value of attribute get changed to 1? Your posted code does not show any reason that the value would not be 0 when you call method2.

Can you show your code that will cause the value to get changed?
Add a println statement after where the value is changed to print out the value immediately after it is changed.

How would the value of attribute get changed to 1? Your posted code does not show any reason that the value would not be 0 when you call method2.

Can you show your code that will cause the value to get changed?
Add a println statement after where the value is changed to print out the value immediately after it is changed.

Hello,

Here is my full code:

When I call System.out.println(openF.displayListSize()); it prints the initial value of listeSize (=45), so apparently it was not incremented within the public void actionPerformed() method:

import java.awt.Color;


import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.ImageIcon;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JLabel;

import java.util.List;
import java.util.ArrayList;

@SuppressWarnings("serial")
public class Labyrinthe extends JFrame{
	
	int nbOfColumns;/*Store the number of the columns of the matrix contained in my file*/
	int nbOfRows;/*Store the number of the rows of the matrix contained in my file*/
	int listeSize=45;/*Size of the long string that results from reading the matrix contained in my file*/
	
	/*List containing all the numbers of my text file */
	List<String> myNumbers=new ArrayList<String>();
	/*Array containing all the numbers of my text file retrieved from myNumbers List*/
	int tableau[]; 
	/*Matrix that stores faithfully the 2 dimension array saved in my file*/
	int matrixOfLabyrinthe[][];
	
	JTextArea textArea=new JTextArea(50,50);
	JScrollPane scrollLab=new JScrollPane(textArea);
	
	
	class OpenF implements ActionListener{
		   public void actionPerformed(ActionEvent ae){
		     JFileChooser chooser = new JFileChooser();
		     chooser.setMultiSelectionEnabled(true);
		     int option = chooser.showOpenDialog(Labyrinthe.this);
		     if (option == JFileChooser.APPROVE_OPTION) {
		       File[] sf = chooser.getSelectedFiles();
		       String filelist = "nothing";
		       if (sf.length > 0) filelist = sf[0].getName();
		       for (int i = 1; i < sf.length; i++) {
		         filelist += ", " + sf[i].getName();
		       }
		      // statusLabel.setText("You chose " + filelist);
		        
		        // Read in data file to JTextArea
		        try{
		        String strLine;	        
		        File selectedFile = chooser.getSelectedFile();
		        FileInputStream in = new FileInputStream(selectedFile);
		        BufferedReader br = new BufferedReader(new InputStreamReader(in));
		        while ((strLine = br.readLine()) != null) {
		        	textArea.append(strLine+"\n");
		        	myNumbers.add(strLine);         
		        	listeSize++;
		        	
		            
		        }
		        }catch(Exception e){
		           System.out.println("Ouch, I fell over! " + e);
		        }
		        
		     }
		     /*else {
		       statusLabel.setText("You canceled.");
		     }*/
		   	
			}/*END OF actionPerformed(ActionEvent ae) method*/
		   
		   public int displayListSize(){
			   return listeSize;
		   }
		   
		}/*END OF OpenF */
	
	
	public Labyrinthe(){
		initUI();
	}
	
	public final void initUI(){
		JFrame frame=new JFrame("Projet IA");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		JLabel label=new JLabel();
		
		JMenuBar jmBar=new JMenuBar();
		Container container=frame.getContentPane();
		container.setLayout(new FlowLayout());
		container.setBackground(Color.BLUE);
		
		ImageIcon iconExit=new ImageIcon(getClass().getResource("exit.jpeg"));
		ImageIcon iconAbout=new ImageIcon(getClass().getResource("help.png"));
		ImageIcon iconOpen=new ImageIcon(getClass().getResource("open.jpeg"));
		
		JMenu jmFile=new JMenu("File");
		jmFile.setMnemonic('F');
		JMenu jmHelp=new JMenu("Help");
		jmHelp.setMnemonic('H');
		
		JMenuItem jmiNew=new JMenuItem("New",iconOpen);
		jmiNew.setMnemonic('N');
		jmiNew.addActionListener(new OpenF());
		JMenuItem jmiExit=new JMenuItem("Exit",iconExit);
		jmiExit.setMnemonic('E');
		JMenuItem jmiAbout=new JMenuItem("About",iconAbout);
		jmiAbout.setMnemonic('A');
		jmiExit.add(new JSeparator());
		
		jmiExit.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				System.exit(0);
			}
		});
		
		jmFile.add(jmiNew);
		jmFile.add(jmiExit);
		jmHelp.add(jmiAbout);
		
		jmBar.add(jmFile);
		jmBar.add(jmHelp);
		
		
		container.add(label);
		container.add(scrollLab);
		frame.setJMenuBar(jmBar);
		frame.pack();
		frame.setVisible(true);
		
	}/*END OF initUI() */
	
	
	public static void main(String[]args){
		Labyrinthe labyrinthe=new Labyrinthe();
		Labyrinthe.OpenF openF=labyrinthe.new OpenF();
		System.out.println(openF.displayListSize());
	}
}

Your code calls displayListSize as part of the startup code in main, but the actionPerformed method isn't executed until you click the "new" menu some time later, so the two calls are in the wrong order.

Your code calls displayListSize as part of the startup code in main, but the actionPerformed method isn't executed until you click the "new" menu some time later, so the two calls are in the wrong order.

Please, tell me how to call them in order to have the incrementation effect ?

actionPerformed is called when you click the menu item, so that's sensible.
You tell me, when do you want displayListSize to be called?

actionPerformed is called when you click the menu item, so that's sensible.
You tell me, when do you want displayListSize to be called?

Thank you,

Yes, I want to perform actionPerformed when I click on New

I want to call displayListSize() in the public void main(String[]args){}

That's what you do now, and you already said it's NOT what you want!
My question was when do you want to call displayListSize, not where.

That's what you do now, and you already said it's NOT what you want!
My question was when do you want to call displayListSize, not where.

As I said, I want to display the value of that variable after incrementation.

Then call it at the end of your actionPerformed method, because that's where it gets incremented.

So the incrementation does not affect the int listeSize=45; variable ? My goal is to incremente and upadate its new value to the incremented value. Can you tell me how to do that, please ?

No, I never said anything like that. Time to stop and think this through clearly.
You have an actionPerformed method that is called each time the menu item is selected. It appears to read from a file and increment listeSize. There may be bugs in there, I don't know, but the idea is right.
Unless there are other bugs that we haven't found yet, your actionPerformed should be updating listeSize correctly.
You also have a displayListSize method that lets you check the current value of listeSize. That looks OK as well.
Your only problem here is that you don't know when to call displayListSize.
If you call it in main you are calling it before actionPerformed, so you see the value before it is incremented. You have to call it after you have executed actionPerformed if you want to see the incremented value.

No, I never said anything like that. Time to stop and think this through clearly.
You have an actionPerformed method that is called each time the menu item is selected. It appears to read from a file and increment listeSize. There may be bugs in there, I don't know, but the idea is right.
Unless there are other bugs that we haven't found yet, your actionPerformed should be updating listeSize correctly.
You also have a displayListSize method that lets you check the current value of listeSize. That looks OK as well.
Your only problem here is that you don't know when to call displayListSize.
If you call it in main you are calling it before actionPerformed, so you see the value before it is incremented. You have to call it after you have executed actionPerformed if you want to see the incremented value.

Thank you very much. I understand what is the problem you explained to me, but I don't know which parameter I will pass to actionPerformed(ActionEvent ae) method within the main method ?

Why are you talking about calling actionPerformed yourself? You don't do that. Swing will call actionPerformed when you select your "New" menu item. The only correct way to execute your actionPerformed is by clicking the New menu item when your application is running.

Why are you talking about calling actionPerformed yourself? You don't do that. Swing will call actionPerformed when you select your "New" menu item. The only correct way to execute your actionPerformed is by clicking the New menu item when your application is running.

Yes: that is the problem from the beginning: I click on the New, I choose a file to read it and at the end that variable is displayed with its initialized value not by its new incremented value :(

You have not posted any code that displays the value after incrementing, so I can't comment.

No, I displayed that code like here:

System.out.println(openF.displayListSize());

You have only posted that line of code in your main method - and I already explained why that's not going to do what you want. That does NOT display the value after incrementing, only the value before.

You have only posted that line of code in your main method - and I already explained why that's not going to do what you want. That does NOT display the value after incrementing, only the value before.

Yes, I know, and this is why I used this forum to get an answer on how to fix this trouble :)

I've given you both the cause and a solution for your problem. I've tried different ways to explain them to you, but somehow it's not getting through. You're just going round in circles and not responding to what I am actually saying. Maybe someone else can find a way to explain it for you.
Good luck
J

You have only posted that line of code in your main method - and I already explained why that's not going to do what you want. That does NOT display the value after incrementing, only the value before.

if I print the incremented value inside the actionPerformed method it displays it correctly, but at the end, that variable keeps its original value, the incrementation is apparently local :(

I've given you both the cause and a solution for your problem. I've tried different ways to explain them to you, but somehow it's not getting through. You're just going round in circles and not responding to what I am actually saying. Maybe someone else can find a way to explain it for you.
Good luck
J

Thank you anyway

OK, one last try:
The incrementation is NOT local. You HAVE updated the variable. The correct output when you display it inside actionPerformed proves that.

Your print statement in main is not printing at the right time.

All the statements in main execute immediately, including your display. At that time no GUI actions have been performed, your actionPerformed method has not yet been called, no variables have been incremented, so of course you display the initial value.
Some time after main has finished, and you have displayed the initial value, you click the menu, actionPerformed is called, the variable is incremented. But that's not until after you called display, so you never display the latest value of that variable.

Perhaps you can see the timing of events better if you add printlns to your code that print out when the value of the variable is changed. Add the printlnm statement immediately after the statement that changes the value of the variable. The print out will show you the order of the events in your program.

Also add printlns every time that you access the variable and get its value. For example in the displayListSize() method.

Edited 5 Years Ago by NormR1: n/a

Perhaps you can see the timing of events better if you add printlns to your code that print out when the value of the variable is changed. Add the printlnm statement immediately after the statement that changes the value of the variable. The print out will show you the order of the events in your program.

Also add printlns every time that you access the variable and get its value. For example in the displayListSize() method.

I think I have resolved the problem by adding this code inside the class OpenF:

public int test(){	
			   OpenF openMyFile=new OpenF();
			   openMyFile.actionPerformed(null);
			   int n=openMyFile.displayListSize();
			   return n;
		   }

And then, in the main I called it like this:

Labyrinthe labyrinthe=new Labyrinthe();
		Labyrinthe.OpenF openF=labyrinthe.new OpenF();
		labyrinthe.listeSize=openF.test();
		System.out.println(labyrinthe.listeSize);

And it works

But my small trouble now is that the File Chooser Window opens at the start of the application without giving me time to click on 'New' menu: how can I fix this please ?

Change your logic so you do NOT call the file chooser until the user has clicked on the New menu item.

You need to move away from coding the program and think about the events that happen and in what order. Your code presents a GUI, the user does something, the code get control and does something. Look at when each of these events occurs and what data is available at each point in the execution cycle.
Earlier you were trying to get data BEFORE the code that would set the value was being executed. This error was because you did not stop and think about what order the events were happening when your code is executed.

You didn't need to do that. It doesn't help. You should remove it. It's just going to make more problems.
Your code to increment listeSize is working. You don't need to fix it.
Your only problem is that putting your code in main to display listeSize is wrong. listeSize itself is correct and is being incremented.

I need the incremented value of listeSize in order to continue programming my project, this is why I try to display it to check if I can get its correct new value.

I understand your former notes, but I don't know how to fix it

You don't need to fix it. It's not broken. You can continue to program your project using listeSize. It's only your attempt to display it that's wrong.
Here's a suggestion:
print listeSize as part of your exit code

jmiExit.addActionListener(new ActionListener(){
  public void actionPerformed(ActionEvent e){
    System.out.println(listeSize);
    System.exit(0);
  }
  ...

That will show the correct value of listeSize after it has been updated

Edited 5 Years Ago by JamesCherrill: added actual code

This article has been dead for over six months. Start a new discussion instead.