在 Java 中使用动作侦听器的最有效方式?

Most efficient way of using an action listener in Java?

我的任务是创建一个显示数字键盘(如 phone 上的键盘)的程序,并有一个屏幕显示所选择的数字。还包括一个清除屏幕的清除按钮。

在创建我的程序时,我创建了三个 classes。 Phone class 只是创建一个 JFrame,将 PhonePanel 添加到屏幕。 PhonePanel class 添加了一个用作屏幕的 JLabel,一个用作清除按钮的 JButton,以及一个用作数字键的 JButtons 的 GridLayout 的 KeypadPanel。

清除按钮和数字按钮都使用单独的动作侦听器。这是最有效的方法吗?有没有一种方法可以使用一个动作侦听器而不是两个?

// ******************************************************************************************
// Phone.java
// David Read
// This class creates a JFrame that contains a PhonePanel. The PhonePanel provides a
// user interface that allows one to input numeric symbols on a screen and allows clearing
// of the screen.
// ******************************************************************************************

package lab5;

import javax.swing.JFrame;

public class Phone {

    public static void main(String[] args) 
    {
        // Create a JFrame object.
        JFrame frame = new JFrame ("Phone");

        // Set the default close operation for the JFrame.
        frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

        // Add a Phone panel to the screen.
        frame.getContentPane().add(new PhonePanel());
        frame.pack();
        frame.setVisible(true);
    }

}



// ******************************************************************************************
// PhonePanel.java
// David Read
// This class creates a JPanel that includes an output label which displays inputed numeric
// symbols, a clear button that clears what is displayed on the output label, and a KeypadPanel
// which displays a GridLayout of buttons that when pressed, display their corresponding symbols
// on the output label.
// ******************************************************************************************

package lab5;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class PhonePanel extends JPanel 
{
    private static JLabel labelOutput;
    private JButton buttonClear;

    //-----------------------------------------------------------------------
    // Creates a JPanel that arranges three objects in a Border layout. The
    // north component contains a JLabel, the east component contains a JButton
    // and the center component contains a KeypadPanel.
    //-----------------------------------------------------------------------
    public PhonePanel()
    {
        // Set the layout manager, size and background color of the Phone Panel.
        setLayout(new BorderLayout());
        setPreferredSize (new Dimension(400, 200));
        setBackground (Color.yellow);

        // Output label created.
        labelOutput = new JLabel(" ");

        // Clear button created, assigned a button title and assigned an action listener.
        buttonClear = new JButton();
        buttonClear.setText("Clear");
        buttonClear.addActionListener(new ClearButtonListener());

        // Add the JLabel, JButton and KeypadPanel to the PhonePanel.
        add(labelOutput, BorderLayout.NORTH);
        add(buttonClear, BorderLayout.EAST);
        add(new KeypadPanel(), BorderLayout.CENTER);        
    }

    //-----------------------------------------------------------------------
    // Adds the specified symbol to the output label.
    //-----------------------------------------------------------------------
    public static void addToOutputLabel(String input)
    {
        // Create a String object to hold the current value of the output label.
        String label = labelOutput.getText();

        // Append the inputed String onto the String.
        label += input;

        // Update the output label with the appended String.
        labelOutput.setText(label);
    }

    //-----------------------------------------------------------------------
    // Listens for the clear button to be pressed. When pressed, the output
    // label is reassigned as blank.
    //-----------------------------------------------------------------------
    private class ClearButtonListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            labelOutput.setText(" ");
        }
    }
}



// ******************************************************************************************
// KeypadPanel.java
// David Read
// This class creates a JPanel that contains several buttons which when pressed, adds their
// corresponding numeric symbol to the output label in the PhonePanel.
// ******************************************************************************************

package lab5;

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

import javax.swing.JButton;
import javax.swing.JPanel;


public class KeypadPanel extends JPanel
{
    private JButton button1, button2, button3, button4, button5, button6, button7, button8, button9, buttonStar, button0, buttonNumber;

    //-----------------------------------------------------------------------
    // Creates a JPanel that arranges several JButtons in a GridLayout. Each
    // of the buttons are assigned button titles, action listeners and
    // action commands.
    //-----------------------------------------------------------------------
    public KeypadPanel()
    {
        // Set layout to a GridLayout with 4 rows and 3 columns.
        setLayout(new GridLayout(4,3));

        // Create new JButtons.
        button1 = new JButton();
        button2 = new JButton();
        button3 = new JButton();
        button4 = new JButton();
        button5 = new JButton();
        button6 = new JButton();
        button7 = new JButton();
        button8 = new JButton();
        button9 = new JButton();
        buttonStar = new JButton();
        button0 = new JButton();
        buttonNumber = new JButton();

        // Assign button titles to the JButtons.
        button1.setText("1");       
        button2.setText("2");       
        button3.setText("3");       
        button4.setText("4");       
        button5.setText("5");       
        button6.setText("6");       
        button7.setText("7");       
        button8.setText("8");       
        button9.setText("9");       
        buttonStar.setText("*");        
        button0.setText("0");       
        buttonNumber.setText("#");

        // Create a new KeypadButtonListener.
        KeypadButtonListener listener = new KeypadButtonListener();

        // Assign the listener as an action listener for all of the JButton objects.
        button1.addActionListener(listener);
        button2.addActionListener(listener);
        button3.addActionListener(listener);
        button4.addActionListener(listener);
        button5.addActionListener(listener);
        button6.addActionListener(listener);
        button7.addActionListener(listener);
        button8.addActionListener(listener);
        button9.addActionListener(listener);
        buttonStar.addActionListener(listener);
        button0.addActionListener(listener);
        buttonNumber.addActionListener(listener);

        // Set the action commands for all of the JButtons.
        button1.setActionCommand("1");
        button2.setActionCommand("2");
        button3.setActionCommand("3");
        button4.setActionCommand("4");
        button5.setActionCommand("5");
        button6.setActionCommand("6");
        button7.setActionCommand("7");
        button8.setActionCommand("8");
        button9.setActionCommand("9");
        buttonStar.setActionCommand("*");
        button0.setActionCommand("0");
        buttonNumber.setActionCommand("#");

        // Add the JButtons to the KeypadPanel.
        add(button1);
        add(button2);
        add(button3);
        add(button4);
        add(button5);
        add(button6);
        add(button7);
        add(button8);
        add(button9);
        add(buttonStar);
        add(button0);
        add(buttonNumber);
    }

    //-----------------------------------------------------------------------
    // Listens for all of the buttons to be pressed. When a particular button
    // is pressed, the addToOutputLabel method of the PhonePanel is called
    // with the input being the action command of the button pressed.
    //-----------------------------------------------------------------------
    private class KeypadButtonListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            // Add the action command string to the output label.
            PhonePanel.addToOutputLabel(e.getActionCommand());
        }
    }
}

在这种情况下,最好使用两个单独的动作侦听器,因为清除按钮和数字按钮的功能不同。 在开发 类 时,使用单一责任原则 (https://en.wikipedia.org/wiki/Single_responsibility_principle) 被认为是最佳实践。这将使您的代码更易于维护,更易于阅读和修改。

这里最好使用多个 ActionListener,但是,如果您仍然希望使用一个 ActionListener,您可以单独 class 来处理与此类似的所有操作。

public class KeyListener implements ActionListener {

@Override
public void actionPerformed(ActionEvent e) {

    //Get the name of the ActionEvent
    String cmd = e.getActionCommand();

    //Here the Actionevent is only checked to see if it is a "Clear" or not
    //If you need to impliment more then a switch statment may be appropriate 
    if(cmd.equals("Clear")) {
        //Clear Label with additional setter method
        PhonePanel.clearLabel();
    }
    else {
        PhonePanel.addToOutputLabel(e.getActionCommand());
    }

}