I wrote a class called Creature.java that creates a random creature object with various body stats. The Creature class extends MonsterGUI.
I used Netbeans to create a new jFrame form, called MonsterGUI.java to create a GUI to display the creature objects' stats using jLabels.
In MonsterGUI I have a private jLabel called jLabel4 that is originally set to "--------".

The Creatures class has methods - getting/returning an int - called setWidth() to set the Width, and getWidth() to return the Width of the Creature.
Under the MonsterGUI main method, I can create a Creature object, and call the getWidth() and setWidth() methods:

public static void main(String args[]) {

        Creature ant = new Creature();
        ant.randCreatureGenerator(); 
        ant.creatureStats();         
        ant.setWidth(8);
        System.out.println(ant.getWidth());

I want to change MonsterGUI's jLabel4 to what the newly created Creature object's getWidth() method returns.

I have tried doing this by creating a MonsterGUI private method:

private void Changer(java.beans.PropertyChangeEvent evt) {
    String label = Integer.toString(getWidth()); //cast the int to a string for jLabel4 to use
    jLabel4.setText(label); //sets jLabel4 to String label
}

This changes jLabel4 to "132" which shows that I am not accessing the newly creatued Creature object's getWidth() method.

Could someone please help me understand how to access the new Creature objects' methods to change the MonsterGUI's private variables?

Thanks,

Recommended Answers

All 17 Replies

Could you make a small, complete program that compiles, executes and shows the problem?

Below is the Creature.java class file:

package javaapplication12;

    public class Creature extends JavaApplication12
    { 
       private int width = 1; // how large the creature is

    @Override
        public int getWidth()
            {
            return width;
        }

         public void setWidth(int changeWidth) 
            {
            if(changeWidth > 0)
                    {
                width = changeWidth;
            } else 
                        {
                width = 1;
                        }
            }
    }

Below is the JavaApplication12.java GUI file:

package javaapplication12;

 package javaapplication12;

       public class JavaApplication12 extends javax.swing.JFrame {

        public JavaApplication12() {
            initComponents();
        }

        /**
         * This method is called from within the constructor to initialize the form.
         * WARNING: Do NOT modify this code. The content of this method is always
         * regenerated by the Form Editor.
         */
        @SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">
        private void initComponents() {

            jLabel1 = new javax.swing.JLabel();
            jSeparator1 = new javax.swing.JSeparator();
            jLabel2 = new javax.swing.JLabel();
            jLabel3 = new javax.swing.JLabel();
            jLabel4 = new javax.swing.JLabel();
            jLabel5 = new javax.swing.JLabel();

            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

            jLabel1.setFont(new java.awt.Font("Tahoma", 1, 36)); // NOI18N
            jLabel1.setText("Monsters");

            jLabel2.setText("Width");

            jLabel3.setText("Length");

            jLabel4.setText("--------");
            jLabel4.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
                public void propertyChange(java.beans.PropertyChangeEvent evt) {
                    Changer(evt);
                }
            });

            jLabel5.setText("jLabel5");

            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
            getContentPane().setLayout(layout);
            layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                            .addGap(0, 39, Short.MAX_VALUE)
                            .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 305, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGap(46, 46, 46))
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(jSeparator1)
                            .addContainerGap())))
                .addGroup(layout.createSequentialGroup()
                    .addGap(30, 30, 30)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jLabel2)
                        .addComponent(jLabel4))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addComponent(jLabel5)
                        .addComponent(jLabel3))
                    .addGap(20, 20, 20))
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addGap(48, 48, 48)
                    .addComponent(jLabel1)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGap(61, 61, 61)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel2)
                        .addComponent(jLabel3))
                    .addGap(18, 18, 18)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel4)
                        .addComponent(jLabel5))
                    .addContainerGap(85, Short.MAX_VALUE))
            );

            pack();
        }// </editor-fold>

        private void Changer(java.beans.PropertyChangeEvent evt) {
            // TODO add your handling code here:
            String label = Integer.toString(getWidth());
            //jLabel4.setText(label);
            //System.out.println(label);
            //String label = "Label";
            jLabel4.setText(label);
            System.out.println("The label is " + label);
        }

        /**
         * @param args the command line arguments
         */
        public static void main(String args[]) {

            Creature ant = new Creature();           
            ant.setWidth(8);
            System.out.println(ant.getWidth());

            /*
             * Set the Nimbus look and feel
             */
            //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
            /*
             * If Nimbus (introduced in Java SE 6) is not available, stay with the
             * default look and feel. For details see
             * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
             */
            try {
                for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                    if ("Nimbus".equals(info.getName())) {
                        javax.swing.UIManager.setLookAndFeel(info.getClassName());
                        break;
                    }
                }
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
                java.util.logging.Logger.getLogger(JavaApplication12.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
            }
            //</editor-fold>

            /*
             * Create and display the form
             */
            java.awt.EventQueue.invokeLater(new Runnable() {

                public void run() {
                    new JavaApplication12().setVisible(true);
                }
            });
        }

        // Variables declaration - do not modify
        private javax.swing.JLabel jLabel1;
        private javax.swing.JLabel jLabel2;
        private javax.swing.JLabel jLabel3;
        private javax.swing.JLabel jLabel4;
        private javax.swing.JLabel jLabel5;
        private javax.swing.JSeparator jSeparator1;
        // End of variables declaration
    }

148+ lines of code is not really a small program. Where in the code is the problem? Could you add some comments there and direct us to those comments so we can see the relevant code and not have to look through 148 lines of code.

Line 91 you call getWidth() without an explicit object, so that's the same as this.getWidth().
"this" is the current instance of JavaApplication12, which extends JFrame and inherits getWidth() from it. So 132 seems like a perfectly reasonable value.
You will see a different result if you call ant.setVisible(); rather than making and displaying a new instance of JavaApplication. In that case you will be looking at an instance of Creature, with its own getWidth. However, by overriding set/getWidth from JFrame you may screw up the size of the frame.
IMHO making Creature a subclass of JFrame is almost certainly a bad idea.

Can you explain what the code does wrong/in correctly when it executes?
It does ....
I want it to do ....

Sorry about the long code NormR1 - I am new to Swing, and didn't know how or what to cut out for pasting here. That is why I am using NetBeans to create the JFrame Form for me.

Using the code above, whenever I try to change jLabel4, using the Creature's ant.getWidth() method that was set with the ant.setWidth(8) method - line 105, and then call the method Changer() - lines 89 thru 97 - to make that happen, the Changer() method actually returns the numbers 132. I am looking for guidance on how to make the Changer() method actually change jLabel4 to display the integer 8, or whatever number I set the Creature object's width to (in this case, ant.setWidth(8).

JamesCherrill, I think you understand where I am messing up! I understand what you are suggesting about calling ant.setVisible(true), but I am not sure how or where to add it in the code above, or if I need to comment out line 140.

I think if I can figure this out, I will be ready for my next Java class coming up this week; my training is going to be over writing Swing applications...

Thanks you two for the help!

change jLabel4 to display the integer 8,

The Creature object's width variable has that value. You need a reference to that object so you can call its getWidth() method.

The first thing that threw me off was that I was using in Creature.java the method getWidth() which just happens to be a method used to get the actual width of a jLabel.

I understand what you are saying about needing a reference to the Creature object's getWidth() method, but I am stumped as to how to make that happen. Any suggestions using the rather long code above?

As James said, the way those classes are coded is not workable.
If an instance of the Creature class were created in the JavaApplication12 class and saved in a class variable, then the changer() method would have access to it.

Before I start changing around the two classes, let me make sure I understand what you and James are suggesting. I need to leave the code for JavaApplication12 pretty much intact, but place the Creature class inside JavaApplication12 as an inner class, and then instantiate it under the main method. This should then allow me to pass the ant.getWidth() returned integer value to the JavaApplication12's private jLabel4. using the Changer() method. Is this correct?

instantiate it under the main method.

Not in main(), inside of an instance of the JavaApplication12 class as a class variable. Maybe in the constructor.

The changer() method could then use that class varaible to call the class's getWidth() method.

Why am I not seeing what you are describing? Are you talking about something like this:

try {
      Class theClass  = Class.forName(Creature);

I'm not understanding what you mean by "instance of the JavaApplication12 class as a class variable." Would you mind giving me an example of what I need to do here?

I have roughly 700+ lines of code in the Creature.java file. Should I be trying to place that code inside the GUI class as an inner class?

In the JavaApplication12 class:
Creature crtr; // define as class variable

in the JavaApplication12 constructor:
crtr = new Creature(); // give class variable a value

in the changer() method:
crtr.getWidth() // use the variable to get value from the Creature object

I don't know why the Creature classt would need to be an inner class.

Thought I had it licked - with your help NormR1, but ran into issues with assigning the class variable a value. The only place I can find to place the constructor-suggested code and have it compile successfully is in the changer() method, which I know is wrong.

Below is a new posting of a slimmed down version of the GUI, and another copy of the original Creature.java file.

I defined the class variable on line 90.
I recreated the Changer() method on lines 45 thru 51 to reflect your suggestions with calling the Creature ant's getWidth() method.
If I try placing the suggested line of assigning a value to the class variable anywhere in the code - other than in the Changer() method - I am stuck in some type of loop. I placed it here on line 10 in the constructor.

GUI.java

package ant;

public class GUI extends javax.swing.JFrame {


    //CLASS CONSTRUCTOR
    public GUI() {
        initComponents();
    //ASSIGNED variable to class as suggested - doesn't run properly.
        ant = new Creature();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jLabel1.setText("--------");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(192, Short.MAX_VALUE)
                .addComponent(jLabel1)
                .addGap(176, 176, 176))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(129, 129, 129)
                .addComponent(jLabel1)
                .addContainerGap(157, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>

    //CHANGER() METHOD TO CONVERT ANT.GETWIDTH() TO STRING AND ASSIGN
    //IT TO JLABEL1.
    public void Changer()
    {
        ant.setWidth(8);
        String label = Integer.toString(ant.getWidth());
        System.out.println(label + "The integer inside ant's width: " + ant.getWidth());
        jLabel1.setText(label);
    }

    public static void main(String args[]) {


        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new GUI().setVisible(true);

            }
        });
    }

    //DEFINE A CLASS VARIABLE AS SUGGESTED
    Creature ant;
    // Variables declaration - do not modify
    private javax.swing.JLabel jLabel1;
    // End of variables declaration
}

Creature.java

package ant;

    public class Creature extends GUI
    { 
       private int width = 1; // how large the creature is

@Override
        public int getWidth()
            {
            return width;
        }

         public void setWidth(int changeWidth) 
            {
            if(changeWidth > 0)
                    {
                width = changeWidth;
            } else 
                        {
                width = 1;
                        }
            }
    }

If you put a println in the constructors for both classes you will see that they call each other forever.
Creature's consturctor calls GUI's which calls Creature which calls GUI etc.

Creature can not extend GUI and have GUI create an instance of Creature.

You are a GENIUS NormR1! Thanks for all the help...

I couldn't figure out why the loop was happening until you explained it.
I found that I had to make a call to the Changer() method from GUI's constructor to make it all work. This is completely different from what I had originally envisioned on my first post.

For completeness, here is my final code for GUI.java:

package ant;
public class GUI extends javax.swing.JFrame {
    //CLASS CONSTRUCTOR
    public GUI() {
        initComponents();
    //ASSIGNED VARIABLE TO CLASS AS SUGGESTED
        ant = new Creature();
    //CALL PRIVATE METHOD CHANGER() FROM THE CONSTRUCTOR TO CHANGE JLABEL1    
        Changer();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jLabel1.setText("--------");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(192, Short.MAX_VALUE)
                .addComponent(jLabel1)
                .addGap(176, 176, 176))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(129, 129, 129)
                .addComponent(jLabel1)
                .addContainerGap(157, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                        

    //CHANGER() METHOD TO CONVERT ANT.GETWIDTH() TO STRING AND ASSIGN
    //IT TO JLABEL1. 
    public void Changer()
    {
        ant.setWidth(8);
        String label = Integer.toString(ant.getWidth());
        System.out.println(label + "The integer inside ant's width: " + ant.getWidth());
        jLabel1.setText(label);
    }

    public static void main(String args[]) {        

        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(GUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new GUI().setVisible(true); 
            }
        });
    }
    //DEFINE A CLASS VARIABLE AS SUGGESTED
    Creature ant;
    // Variables declaration - do not modify                     
    private javax.swing.JLabel jLabel1;
    // End of variables declaration                   
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.