学习Java:无法调用方法

时间:2013-12-06 22:45:15

标签: java class object methods

我对应用程序开发很新,所以我希望你们能教一两件事。

我有1 JFrame和1 JTextField。我使用的方法每次单击按钮时都会返回一个数字,并将其写入JTextfield

有效!但是,问题在于我希望方法拥有自己的类。

我在我的方法课中得到了这个:

打包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;
    }
}

这是我班上的Jbutton和`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                   
}

问题1)我可以运行应用程序,但按下按钮时没有任何反应。这是为什么?当我在课堂上工作时,有什么必须记住的黄金法则吗?

谢谢!

编辑:解决了。

3 个答案:

答案 0 :(得分:0)

我对你的代码发表评论,我不知道这是否有帮助。 您正在Class2中使用Class1的聚合,但是在Class1中您进行了继承。如果关系不是继承,则应删除继承。

请将你的问题放在class2里面的jTextField1中,让我能够知道你是如何得到它的,以及在调用方法testing()之前你在哪里设置它;

答案 1 :(得分:0)

您正在setText的错误实例上调用class2。这是我看到的调用堆栈:

  1. main方法创建一个class2实例。
  2. (我假设你点击这里的按钮)
  3. class2实例中的事件处理程序会创建class1实例
  4. 新的class1实例会创建一个新的class2实例(main创建的实例分开
  5. class2实例在testing()实例上调用class1
  6. class1实例调用其内部class2实例上的方法。这会在class2实例上设置不可见的文本。
  7. 如果您的testing()方法需要在单独的类中,但影响主class2实例,则应将class2实例传递给构造函数中的class1

    public class class1 extends class2 {
    
      // NO! class2 testingobj = new class2();
    
      private class2 testingobj;
      public class1(class2 dependency) {
        testingobj = dependency;
      }
    

答案 2 :(得分:0)

据我所知,您在这里混合了面向对象和简单的模块原则。 我想,你主要想要的是一个模块(你已经意识到class1)和一个模块,你已经意识到它是class2

鉴于此,您正在尝试将两个模块绑定在一起的不同机制。 您正在使用class1 extends class2,并且您正在使用键入为class1class2的属性/字段/变量。

在继续之前,请考虑您的问题的评论:java中的类名以大写字母开头,例如Class2,或MyWindowMyFrame(两者都比前者更好)。

现在继承的东西。你有class2扩展JFrame,这没关系。您希望class2成为“框架”(窗口,就此而言)。

但你也写class1延伸class2,所以class1也是JFrame,因为class2JFrame。这不是你想要的。

您的意图是拥有一个单独的模块,因此您应该将class1(或MyController再次声明为更好的名称)

public class class1 {
   ...
}

没有扩展的东西。

接下来,您需要了解,类只是实际“对象”的抽象“模板”。要将类创建为实际对象,请调用构造函数(例如,new class1())。可以将构造函数视为一个特殊方法,该方法使用new关键字调用,并返回给定类型的 new 对象(在此示例中为class1)。

您需要和想要的是将两个类连接在一起。目前,您的main创建了class2的实例,该实例创建了class1的实例,该实例再次创建class2的(不同!)实例。在您的代码中,每个对象只知道其他对象,它使用new创建,但不知道创建对象的对象。

所以main知道class2的第一个实例。这知道class1的实例。而且它知道class2的第二个实例,它为其设置了文本字段。但由于class2的第二个实例不可见(因为setVisible()仅为第一个实例调用),因此按下按钮时看不到任何内容。

您应该做的是实施class1,如下所示:

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;
    }
}

class2你应该写

class1 testing2ndobj = new class1(this);

而不是

class1 testing2ndobj = new class1();

这会将 class1的引用提供给class2,以便它可以访问正确的JTextField