简体   繁体   中英

Adding ActionListener with a loop

package javaapplication2;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;



public class Calc extends JFrame implements ActionListener {

private JButton b1, b2, b3, b4,b5,b6,b7,b8,b9,b0;
JButton[] label = {b1, b2, b3, b4, b5,b6,b7,b8,b9,b0};
String[] numKeys = {"1","2","3","4","5","6","7","8","9","0"};
JPanel numPad;
JPanel opPad;
JTextField displayPanel;

 public Calc() {
 super("Calculator");
 setSize(250,200);
    setDefaultCloseOperation(EXIT_ON_CLOSE);    
    setVisible(true);

    displayPanel = new JTextField(20);
    numPad = new JPanel();
    numPad.setLayout(new GridLayout(4, 3));  
    opPad = new JPanel();
    opPad.setLayout(new GridLayout(4, 1));
    getContentPane().setLayout(new BorderLayout());
    getContentPane().add(numPad,BorderLayout.LINE_START);
    getContentPane().add(displayPanel, BorderLayout.PAGE_START);

    for (int i = 0; i <label.length;i++) {
        label[i] = new JButton(numKeys[i]);
        numPad.add(label[i]);
        label[i].addActionListener(this);


    }


    b2.addActionListener(this);

 }
 public void actionPerformed(ActionEvent a) {
    if (a.getSource() == b1)                     
            displayPanel.setText("1");
}


    public static void main(String args[]) {
Calc c = new Calc();






}
}

Hi, I've attempted to add numbered Jbuttons and add the action listener within a single loop in my attempt to make a calculator, The buttons are created and added to the panel however pressing "1" has no effect when it should display a 1 on the text field

private JButton b1, b2, b3, b4,b5,b6,b7,b8,b9,b0;
JButton[] label = {b1, b2, b3, b4, b5,b6,b7,b8,b9,b0};

b1-b0 are null by default. In this code:

for (int i = 0; i <label.length;i++) {
    label[i] = new JButton(numKeys[i]);
    numPad.add(label[i]);
    label[i].addActionListener(this);
}

you assign the buttons to the label array, but not to the variables b1-b0. Therefore you are actually checking for == null here

if (a.getSource() == b1)

The solution: remove those b1-b0 variables (you got the array anyway) and check like this:

if (a.getSource() == label[0])

First you initialize the buttons to null and fill the label array with those null references.

During the loop, you create new objects and replace them in the label array. The original references are still pointing to null.

In the action event you compare source = the new buttons with the old references which are pointing to null. This is fault.

Just initialize the buttons before you add them to the label array, and don't create new buttons in your loop. Fixed!

I would recommend using actioncommand in for loop and then checking the same in action listener, label[i].setActionCommand(numKeys[i]); and then in action listener something like this if (a.getActionCommand().equals("1"))

Check out this SO question, Java Button Action Command , it explains usage of ActionCommand

Hope this helps !!!

I do not think it a good idea to store buttons in array but if you do still want it is better to use Arrais.asList ()

    import java.awt.*;
    import java.awt.event.*;
    import java.util.Arrays;
    import java.util.Collection;
    import javax.swing.*;

    class Calc extends JFrame {
      Collection<JButton> buttons = Arrays.asList(
        new JButton("1"),
        new JButton("2"),
        new JButton("3"),
        new JButton("4"),
        new JButton("5"),
        new JButton("6"),
        new JButton("7"),
        new JButton("8"),
        new JButton("9"),
        new JButton("0"));
      JPanel numPad;
      JPanel opPad;
      JTextField displayPanel;

      public Calc() {
        super("Calculator");
        setSize(250, 200);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);    

        displayPanel = new JTextField(20);
        numPad = new JPanel();
        numPad.setLayout(new GridLayout(4, 3));
        opPad = new JPanel();
        opPad.setLayout(new GridLayout(4, 1));
        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(numPad, BorderLayout.LINE_START);
        getContentPane().add(displayPanel, BorderLayout.PAGE_START);    

        for (final JButton button : buttons) {
          button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
              displayPanel.setText(displayPanel.getText() + button.getText());
            }
          });
          numPad.add(button);
        }
      }

  public static void main(String args[]) {
    Calc c = new Calc();
  }
}

Write a generic Action so you don't have to use nested if statements:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

public class CalculatorPanel extends JPanel
{
    private JTextField display;

    public CalculatorPanel()
    {
        Action numberAction = new AbstractAction()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                display.replaceSelection(e.getActionCommand());
            }
        };

        setLayout( new BorderLayout() );

        display = new JTextField();
        display.setEditable( false );
        display.setHorizontalAlignment(JTextField.RIGHT);
        add(display, BorderLayout.NORTH);

        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout( new GridLayout(0, 5) );
        add(buttonPanel, BorderLayout.CENTER);

        for (int i = 0; i < 10; i++)
        {
            String text = String.valueOf(i);
            JButton button = new JButton( text );
            button.addActionListener( numberAction );
            button.setBorder( new LineBorder(Color.BLACK) );
            button.setPreferredSize( new Dimension(50, 50) );
            buttonPanel.add( button );

            InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
            inputMap.put(KeyStroke.getKeyStroke(text), text);
            inputMap.put(KeyStroke.getKeyStroke("NUMPAD" + text), text);
            button.getActionMap().put(text, numberAction);
        }
    }

    private static void createAndShowUI()
    {
//      UIManager.put("Button.margin", new Insets(10, 10, 10, 10) );

        JFrame frame = new JFrame("Calculator Panel");
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.add( new CalculatorPanel() );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

This example also uses Key Bindings , so you can press "1" on the keyboard or click the "1" button.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM