java.lang.StackOverflowError

Hi,
   I'm getting a java.lang.StackOverflowError when I try to make dispose of a JInternalFrame.  The ViewItems
class gets called from another class which has a menu and creates an instance of the ViewItems class
when it is selected on the menu.  

What I wanted to happen here is if there is nothing in the Category array I dont want to display the JInternalFrame
and dispaly the message "No categories exist, have to add categories before you can proceed".
That works fine for me but I am getting a StackOverflowError anyone got any idea why?

As far as I can see I call the setClosed(true) method of the JInternalFrame and this fires the internalFrameClosed of
the added addInternalFrameListener once???? but it seems to be in a recursive loop somewhere.  Because if I put a
System.out.println("In Closed method") in the internalFrameClosed method, it keeps outputing prints to the console
and then a StackOverFlowError message is printed.


ViewAllItems.java is as follows:

public class ViewItems extends JInternalFrame implements ItemListener {

      super ("View All Items", false, true, false, true);

     //Constructor
      public ViewItems() {
               this.addInternalFrameListener(new InternalFrameAdapter(){        
                       public void internalFrameClosed(InternalFrameEvent e) {
                               ((JInternalFrame)e.getSource()).dispose();
                       }
                });
      }

     if(!(category == null)){
             //This function displays add the JTextFields etc and sets the JInternalFrame to visible  
             DisplayComponents();

     }
     else{

              JOptionPane.showMessageDialog(this, "No categories exist, have to add categories before you can proceed");
              try{
              setClosed(true);
              }
              catch(Exception ex){
              System.out.println(ex.getMessage());                  
              }      
     }

     //rest of  code here
}

BourkeAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

BourkeAuthor Commented:
Ment to sayin above post, Any help would be grateful
Thanks
V
0
sudhakar_koundinyaCommented:
when you are calling setClosed(true) tghen there is no need to call  InternalFrameAdapter Listener
0
sudhakar_koundinyaCommented:
It is always a better option to call setClosed(true);
which will trigger the internalFrameClosing event.
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

sudhakar_koundinyaCommented:
remove addInternalFrameListener code from your class
0
sciuriwareCommented:
How can you have instrructions outside a method?
The code you posted is impossible.

StackOverFlow is only attained from infinite recursion (a method always calling itself).
<*>
0
sudhakar_koundinyaCommented:
>>The code you posted is impossible
>>StackOverFlow is only attained from infinite recursion (a method always calling itself).

It is possible

See this code

import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;
public class InternalFrame extends javax.swing.JInternalFrame implements ActionListener{
   

    public InternalFrame() {
        initComponents();
       
        this.addInternalFrameListener(new InternalFrameAdapter(){
            public void internalFrameClosed(InternalFrameEvent e) {
                System.err.println("Hello");
               ((JInternalFrame)e.getSource()).dispose();
               
            }
        });
       
        JButton b=new JButton("test");
        getContentPane().add(b);
        b.addActionListener(this);
       
        setSize(100,100);
        show();
       
       
       
       
    }
   
   
    private void initComponents() {
       
        pack();
    }
   
    public void actionPerformed(ActionEvent e) {
        try {
            this.setClosed(true);
            System.err.println("Hello");
        }
        catch(Exception ex) {
            System.err.print(ex);
        }
    }
   
   
   
   
}


and also this link
https://lists.xcf.berkeley.edu/lists/advanced-java/2000-November/014090.html

Regards
Sudhakar
0
sudhakar_koundinyaCommented:
((JInternalFrame)e.getSource()).dispose();

calls the setClosed(true) again which internally calls internalFrameClosed method hence it is recursed

Regards
Sudhakar
0
BourkeAuthor Commented:
Hi All,
  I've tried the suggestions you have made above.  But still no solution.  I have a menu and View All Items is choice
on one of the menu options.  When I click on it and there are no categories then "No categories exist, have to add categories before you can proceed" should be displayed.

I have a check in the class where the menu is

else if(e.getActionCommand() == "View All Items"){
                  
          //Check to see if the frame is already open, if it is dont open a new frame                  
          boolean b = CheckFrameOpen ("View All Items");

          System.out.println("Already open = " + b);
                  
           if (b == false) {
         ViewAllItems view = new ViewAllItems(this.user, this.con);
         theDesktop.add (view);
         view.show();
           }
}
                  
The first time I select it on the menu "Already open = false" is written to the console and the message
No categories exist, have to add categories before you can proceed" is displayed.
The second time I select it on the menu "Already open = true" is written to the console and no message is displayed.
So, as far as I can see the JInternalFrame is still open and putting setClosed(true) in the else part of the check for
if(!(category == null)) does not seem to work.

Thanks for your help
V
0
sudhakar_koundinyaCommented:
>>if(!(category == null)) does not seem to work.

what is the type of object

before that try printing category value and let me kniow.

System.err.println(category). so yhat i can analyse your problem.

Regards
0
BourkeAuthor Commented:
Sorry I worded the last part of my comment above wrong.

The if(!(category == null))  works fine.  
What I ment to say is if I do the following:
if(!(category == null)){
         //This function displays add the JTextFields etc and sets the JInternalFrame to visible  
         DisplayComponents();
}
else{

        JOptionPane.showMessageDialog(this, "No categories exist, have to add categories before you can proceed");
         try{
             setClosed(true);
         }
         catch(Exception ex){}    
}

setClosed(true) does not close the JInternalFrame! it seems to be still open in Memory.  So when I go to the menu and click on "View All Items" again JOptionPane.showMessageDialog(this, "No categories exist, have to add categories before you can proceed") does not appear and the console prints out  "Already open = true" saying the InternalFrame is still open! I need to close this so the "No Categories exist " message will appear again.

Thanks
V

     
0
sudhakar_koundinyaCommented:
OK

I suggest slight modifications in your ViewAllItems class

JComponent comp;
ViewAllItems(JComponent comp,....and other arguments goes here)
{
  this.comp=comp;

}

and in your else part


             setClosed(true);
              comp.remove(this);

and in your menu events initialse view object something like this

  ViewAllItems view = new ViewAllItems(this,this.user, this.con);
0
BourkeAuthor Commented:
Hi,
  I did as you suggested above but the line below I had to change to:

                  ViewAllItems view = new ViewAllItems(this.theDesktop, this.user, this.con);

Afraid it still didnt work?????
I'm baffled!

thanks
V


0
BourkeAuthor Commented:
Ment to say also theDestop is a JDestopPane
0
BourkeAuthor Commented:
What I'll do if anyone wouldn't mind trying to run these two class is I'll paste in cut down versions.
The CatalogueSystem.class below has the main method in it to run.
Thanks very much for all the help
V

ViewAllItems.java

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

import java.sql.*;
import java.util.*;
import javax.swing.event.TableModelEvent;
import javax.swing.table.DefaultTableModel;
import javax.swing.event.TableModelListener;

public class ViewAllItems extends JInternalFrame implements ItemListener {

      private JPanel pItem = new JPanel ();

      private JLabel lblCategory;
      private JComboBox cboCategory;
      //private String category[] = {"Computers", "Science", "History", "General"};      //ComboBox Items.
      private String category[][];
      
      private JScrollPane scroller;
      private JTable table;      //Table for Displaying Records.
      private Statement stmt;      //Statement for Getting the Required Table.

      private int rec = 0;
      private int total = 0;

      private String rowRec[][];      //String Type Array use to Load Records into File.
      
      private Connection con;
      private String user;
      
      
      private JComponent comp;


      //Constructor of Class.

      public ViewAllItems (JComponent comp) {
            
            
            //super (Title, Resizable, Closable, Maximizable, Iconifiable)
            super ("View All Items", false, true, false, true);
            
            this.con = con;
            this.user = user;
            this.comp = comp;

            getCategory();
            if(!(category == null)){
                  

                  
                  setSize (510, 300);
                  pItem.setLayout (null);

                  lblCategory = new JLabel ("Select Category to Show Item Records:");
                  lblCategory.setForeground (Color.black);
                  lblCategory.setBounds (20, 18, 275, 25);

                  cboCategory = new JComboBox ();
                  cboCategory.addItemListener (this);
                  cboCategory.setBounds (300, 18, 170, 25);

                  scroller = new JScrollPane (table);      
                  scroller.setBounds (20, 50, 460, 200);      
      
                  pItem.add (lblCategory);
                  pItem.add (cboCategory);
                  pItem.add (scroller);


                  getContentPane().add (pItem);
                  setVisible (true);
            }
            else
            {
                  
                  JOptionPane.showMessageDialog(this, "No categories exist, have to add categories before you can proceed");
                  
                  try{
                        setClosed(true);
                  }
                  catch(Exception ex){
                        
                  }      
                  
                  comp.remove(this);
                                    
            }      
      }

      public void itemStateChanged (ItemEvent e) {

                  //Code in here            

      }

      private void getCategory(){
                  //Code in here            

      }
}      

CatalogueSystem.java

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

public class CatalogueSystem extends JFrame implements ActionListener{
      
      
      
      private String level;
      private JMenuBar menuBar = new JMenuBar();
      
      private JLabel logo = new JLabel();
      private Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
      
      private JDesktopPane theDesktop = new JDesktopPane ();
   
    private static final int desktopWidth = 900;
    private static final int desktopHeight = 700;

      public static int getDeskTopWidth(){
            
            return desktopWidth;
      }
      
      public static int getDeskTopHeight(){
            
            return desktopHeight;
      }
      
      //Constructor
      public CatalogueSystem(){
            
            super("Catalogue System");
            
            Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
       
                               //Set size and location of the main window
            setSize (desktopWidth, desktopHeight);                              
            setLocation (d.width / 2 - getWidth() / 2, d.height / 2 - getHeight() / 2);
            
            setResizable (false);                                    
          
            SetUpMenu();
            
            getContentPane().add(theDesktop);
            
            Color cl = theDesktop.getBackground ();
            getContentPane().setBackground(cl);
            
            setVisible(true);
            
            
            
      }

      private void SetUpMenu(){

            JMenu itemMenu = new JMenu("Items");
            itemMenu.setMnemonic('I');

            JMenuItem viewAllItems = new JMenuItem("View All Items");
            viewAllItems.setMnemonic('I');
            viewAllItems.addActionListener(this);
            itemMenu.add(viewAllItems);
            
            menuBar.add(itemMenu);
            
            setJMenuBar(menuBar);
      }


      public void actionPerformed(ActionEvent e){
            
      
            //include all actions for menu items            
            if(e.getActionCommand() == "Exit"){
                  System.exit(0);

            }
            
            else if(e.getActionCommand() == "View All Items"){
                  
                  //Check to see if the frame is already open, if it is dont open a new frame                  
                  boolean b = CheckFrameOpen ("View All Items");
                  System.out.println("Already open = " + b);
                  
                  if (b == false) {
                        
                        ViewAllItems view = new ViewAllItems(this.theDesktop);
                        theDesktop.add (view);
                        view.show();
                  }      
            }      
            
      }
      
      private boolean CheckFrameOpen (String title) {

            JInternalFrame[] openFrames = theDesktop.getAllFrames ();                        
            for (int i = 0; i < openFrames.length; i++) {
                  if (openFrames[i].getTitle().equalsIgnoreCase (title)) {                                                        openFrames[i].show ();                                                         return true;
                  }
            }
            return false;

      }
      
      public static void main(String[] args){
            
            CatalogueSystem c = new CatalogueSystem();
      }
      
}

0
sudhakar_koundinyaCommented:
I found the problem in your code


In ViewAllItems.java add this code
 public ViewAllItems (JComponent comp) {
         
          this.comp = comp;
             comp.add(this); //add this line



In CatalogueSystem.Java

in CheckFrameOpen method
change if condition as below suggested.  

if (openFrames[i].getTitle().equalsIgnoreCase (title) && openFrames[i] instanceof ViewAllItems) {      



Hope these two changes will help you

Regards
Sudhakar
0
sudhakar_koundinyaCommented:
Forgot to mention, while you are adding the ViewAllItems instance to desktop pane it is not necessary in menu event

in your menu event remove theDesktop.add

  if (b == false) {
                   
                    ViewAllItems view = new ViewAllItems(theDesktop);
//                    theDesktop.add (view);                  
                    view.show();

               }  
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
BourkeAuthor Commented:
Thank you very much for that...... it works perfect... I went fiddling around with the code as well.
The problem all along was the line you told me to comment out:

                                   theDesktop.add (view);    
           
if I comment this out and put dispose() in the else part as below it works fine as well!

if(!(category == null)){
               
      //code here
}
else
{
               
     JOptionPane.showMessageDialog(this, "No categories exist, have to add categories before you can proceed");
     dispose();
}
               

0
BourkeAuthor Commented:
Again Thank you very much for your help, greatly appreciated :o)
V
0
sudhakar_koundinyaCommented:
Glad, you got it solved  :-)

thanks for the points


0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.