簡體   English   中英

另一個類中的Java ActionListener-從主類訪問對象

[英]Java ActionListener in another class - accessing objects from main class

我正在編寫一個簡單的BMI計算器程序。 該應用程序包括ActionListener,它可以處理按鈕單擊,檢查文本字段是否已填充並執行計算。

目前,ActionListener方法是作為主類的子類。 它看起來像這樣:

BMICalc.java

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class BMICalc extends JFrame {

    private JMenuBar menuBar1;
    private JMenu jMenu1;
    private JMenuItem jMenuItem1, jMenuItem2;
    private JButton jButton1;
    private JPanel mainPanel, jPanel1;
    private JLabel jLabel1, jLabel2;
    private JTextField jTextField1, jTextField2;


    private BMICalc() {

        super("BMI Calculator");

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(new Dimension(250, 300));
        setLocationRelativeTo(null);
        setLayout(new BorderLayout(10, 10));


        mainPanel = new JPanel(new BorderLayout(10, 10));
        mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        add(mainPanel);

        jPanel1 = new JPanel(new GridLayout(6,2));
        mainPanel.add(jPanel1, BorderLayout.CENTER);

        menuBar1 = new JMenuBar();

            jMenu1 = new JMenu("Help");
            menuBar1.add(jMenu1);

                jMenuItem1 = new JMenuItem("The purpose");
                jMenu1.add(jMenuItem1);

                jMenuItem2 = new JMenuItem("About");
                jMenu1.add(jMenuItem2);

        setJMenuBar(menuBar1);

        jLabel1 = new JLabel("Enter weight in [kg]:");
        jPanel1.add(jLabel1);

        jTextField1 = new JTextField("");
        jPanel1.add(jTextField1);

        jLabel2 = new JLabel("Enter height in [cm]:");
        jPanel1.add(jLabel2);

        jTextField2 = new JTextField("");
        jPanel1.add(jTextField2);

        jButton1 = new JButton("Calculate");
        mainPanel.add(jButton1, BorderLayout.SOUTH);

        Handler handler = new Handler();
        jButton1.addActionListener(handler);
        jMenuItem1.addActionListener(handler);
        jMenuItem2.addActionListener(handler);
    }


    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                BMICalc bmicalc = new BMICalc();
                bmicalc.setVisible(true);
            }
        });
    }

    private class Handler implements ActionListener {

        public void actionPerformed(ActionEvent event) {

            if (event.getSource() == jButton1) {

                if (jTextField1.getText().equals("") || jTextField2.getText().equals("")) {

                    JOptionPane.showMessageDialog(null, "All fields must be filled in!", "Error", JOptionPane.INFORMATION_MESSAGE);
                }
                else {
                    Calculations calcs = new Calculations();
                    calcs.calculateBMI(jTextField1.getText(), jTextField2.getText());
                    JOptionPane.showMessageDialog(null, "Your BMI: " +calcs.returnBMI());
                }
            }
            else if (event.getSource() == jMenuItem1) {

                JOptionPane.showMessageDialog(null, "The program calculates BMI based on information entered by user." , "The purpose of this program", JOptionPane.INFORMATION_MESSAGE);
            }
            else if (event.getSource() == jMenuItem2) {

                JOptionPane.showMessageDialog(null, "BMI Calc v. 1.0 " , "About", JOptionPane.INFORMATION_MESSAGE);
            }


        }

    }

}

Calculations.java

public class Calculations {

        private double BMI;
        private int weight, height;

        public void calculateBMI(String sWeight, String sHeight) {

            weight = Integer.parseInt(sWeight);
            height = Integer.parseInt(sHeight);
            BMI = weight/(height*height*0.0001);
        }

        public String returnBMI() {

            return String.format("%.2f", BMI);

        }
}

它工作正常,但是我想使代碼“ clenaer”並使Handler在另一個文件中成為一個類,而不是子類。 我創建了一個Handler.java並移動了整個Handler子類,但是該類沒有看到jTextFields和jButton,因為它們是私有的(就我而言,它們應該是私有的)。

如何分隔ActionListener類,訪問其中的這些jObject並仍然對隱私保密?

非常感謝您的回答。

您可以使用構造函數將所需的對象傳遞給Handler類:

public class Handler {

     private JButton button;
     private JTextField textField;

     public Handler(JButton button, JTextField textField) {
          this.button = button;
          this.textField = textField;
     }

}

當實例化該類時,您只需要傳入兩個變量即可:

Handler handler = new Handler(jButton1, jTextField1);

說明:

您的Handler類是BMICalc 內部類。 當嵌套類不是靜態的時(請參見靜態和非靜態嵌套類之間的區別),這意味着這些類的對象存在於父類的對象中。 這就是您的Handler類看到私有字段的原因。

當類是靜態的時,這對我們來說沒有問題。 您只需要以某種方式將這些變量傳遞給Handler (構造函數或setter字段),然后可以將您的類重用於其他按鈕文本字段組合。


編輯:還有另一種方式:

如果您的處理程序僅在此處,僅在此處和代碼中的任何其他地方使用,則可以實例化匿名 Handler並將其分配給該字段(無需在其他地方重復使用)。 因此,例如:

jMenuItem1.addActionListener(new Handler() {
    @Override
    public void actionPerformed(ActionEvent event) {
        JOptionPane.showMessageDialog(null, "The program calculates BMI based on information entered by user." , "The purpose of this program", JOptionPane.INFORMATION_MESSAGE);
    }
});

jMenuItem2.addActionListener(new Handler() {
    @Override
    public void actionPerformed(ActionEvent event) {
        JOptionPane.showMessageDialog(null, "BMI Calc v. 1.0 " , "About", JOptionPane.INFORMATION_MESSAGE);
    }
});

現在,您不必創建一個包含許多字段和ifs的大型Handler。

請注意,您顯示的Handler 不是Main子類 成為子類意味着它繼承。 你所擁有的是一個內部階級

您需要將引用傳遞給處理程序,以便它可以引用它們。 例如:

public class Handler implements ActionListener {
    private final JTextField jTextField1;
    private final JButton jButton1;
    public Handler(final JTextField textField, final JButton button)
        {
        this.jTextField1 = textField;
        this.jButton1 = button;
        }
}

並像這樣創建它:

Handler handler = new Handler(jTextField1, jButton1);

如果要在將處理程序放在另一個類中的同時保護其他類的JTextFieldJMenuItem ,則需要向BMICalc類添加一些方法:

public boolean isButton1(ActionEvent event) {
    return event.getSource() == jButton1;
}

public boolean isJMenuItem1(ActionEvent event) {
    return event.getSource() == jMenuItem1;
}

public boolean isJMenuItem2(ActionEvent event) {
    return event.getSource() == jMenuItem2;
}


public String getJButton1Text() {
    return this.jButton1.getText();
}

public String getJTextField1Text() {
    return jTextField1.getText();
}

public String getJTextField2Text() {
    return jTextField2.getText();
}

然后,您需要具有以下Handler類:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JOptionPane;

public class Handler implements ActionListener {

private final BMICalc calc;

public Handler(BMICalc calc) {
    this.calc = calc;
}

public void actionPerformed(ActionEvent event) {

    if (calc.isButton1(event)) {

        if (calc.getJTextField1Text().equals("") || calc.getJTextField2Text().equals("")) {

            JOptionPane.showMessageDialog(null, "All fields must be filled in!", "Error", JOptionPane.INFORMATION_MESSAGE);
        }
        else {
            Calculations calcs = new Calculations();
            calcs.calculateBMI(calc.getJTextField1Text(), calc.getJTextField2Text());
            JOptionPane.showMessageDialog(null, "Your BMI: " +calcs.returnBMI());
        }
    }
    else if (calc.isJMenuItem1(event)) {

        JOptionPane.showMessageDialog(null, "The program calculates BMI based on information entered by user." , "The purpose of this program", JOptionPane.INFORMATION_MESSAGE);
    }
    else if (calc.isJMenuItem2(event)) {

        JOptionPane.showMessageDialog(null, "BMI Calc v. 1.0 " , "About", JOptionPane.INFORMATION_MESSAGE);
    }


}

}

並在BMICalc在線更改:

Handler handler = new Handler(this);

但是由於處理程序只應處理該視圖(和BMICalc類)的按鈕和輸入,(對我而言)將這個Handler類保持私有狀態並保留在BMICalc類內部會更有意義。 希望這可以幫助 !

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM