user3074245 user3074245 - 1 month ago 6
Java Question

Learning Java: cannot call a method

I'm very new to application development, so I hope you guys can teach a thing or two.

I got 1

JFrame
and 1
JTextField
. The method I use returns a number everytime I click the button and writes it in the
JTextfield
.

It works! But, the issue is when I want the method to have its own class.

I got this in my method-class:

package newpackage;

package test;

public class class1 extends class2 {

class2 testingobj = null;

/** this is the constructor. It is given a parameter, so it knows
* about the class2
*/
public class1(class2 frame) {
this.testingobj = frame;
}

private int num = 0;

public int testing(){
if(num <=8){
num ++;
testingobj.jTextField1.setText("" +num);
}
return num;
}
}


And this in my class with
Jbutton
and `JTextField':

/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/

package test;

/**
*
* @author Admin
*/
public class class2 extends javax.swing.JFrame {

class1 testing2ndobj = new class1(this);

/**
* Creates new form class2
*/
public class2() {
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() {

jTextField1 = new javax.swing.JTextField();
jButton1 = new javax.swing.JButton();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

jButton1.setText("jButton1");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(122, 122, 122)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jButton1)
.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 199, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(79, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(73, 73, 73)
.addComponent(jButton1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(173, Short.MAX_VALUE))
);

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

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
testing2ndobj.testing();
}

/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* 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 ex) {
java.util.logging.Logger.getLogger(class2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(class2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(class2.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(class2.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 class2().setVisible(true);
}
});
}

// Variables declaration - do not modify
private javax.swing.JButton jButton1;
public javax.swing.JTextField jTextField1;
// End of variables declaration
}


Question 1) I can run the application, but nothing happens when I press the button. Why is that? Is there any golden rule I must remember, when I work across classes?

Thank you!

EDIT: Solved.

Answer

As far as I can see, you are mixing object-oriented and simple module principles here. I guess, what you primarily intend is have a module (which you have realized as class1) and a module, which you have realized as class2.

Given that, you are using different mechanisms trying to tie both modules together. You are using class1 extends class2 and you are using attributes/fields/variables which are typed as class1 and class2.

Before we continue, please regard the comments for your question: class names in java start with a capital, e.g. Class2, or MyWindow or MyFrame (both of which would be better names than the former).

Now to the inheritance stuff. You have class2 which extends JFrame, which is ok. You want class2 to be a "Frame" (a window, for that matter).

But you also write class1 extends class2, so class1 also is a JFrame, because class2 is a JFrame. This is not what you intend.

What you do intend, is having a separate module, so you should just declare class1 (or MyController as a better name, again) as

public class class1 {
   ...
}

without the extends stuff.

Next up, you need to understand, that classes are only the abstract "templates" of the actual "objects". To make a class into a real object, you invoke the constructor (e.g., new class1()). The constructor can be seen as a special method which is called with the new keyword and which returns a new object of the given type (class1 in this example).

What you need and want is to wire both classes together. Currently, your main creates an instance of class2, which creates an instance of class1, which again creates a (different!) instance of class2. In your code, each object only knows about the other object(s), it creates with new, but not about the object which have created this object.

So main knows about the first instance of class2. This knows about the instance of class1. And that knows about the second instance of class2 for which it sets the text field. But since the second instance of class2 ist not visible (because setVisible() is only called for the first instance), you don't see anything when pressing the button.

What you should do is implement class1 as follows:

public class class1 extends class2 {

    class2 testingobj = null;

    /** this is the constructor. It is given a parameter, so it knows 
     *  about the class2
     */
    public class1(class2 frame) {
        this.testingobj = frame;
    }

    private int num = 0;

    public int testing(){
        if(num <=8){
            num ++;
            testingobj.jTextField1.setText("" +num);
        }
        return num;
    }
}

And in your class2 you should write

class1 testing2ndobj = new class1(this);

instead of

class1 testing2ndobj = new class1();

This will give a reference of this class1 to class2 so that it can access the correct JTextField.

Comments