Java 使用 for 循环时向 JButton 添加动作

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20245674/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 00:32:58  来源:igfitidea点击:

Adding action to a JButton when using a for loop

javaswingarraylistjpaneljbutton

提问by Wbcreators Crea

I'm trying to dynamically add buttons (JButtons), which changes names everytime. I doing it with a for loop and is not really problematic. but when adding an action listener or identifying which button got pressed, that is when things don't work so good.

我正在尝试动态添加按钮(JButtons),它每次都会更改名称。我用 for 循环来做,并没有真正的问题。但是当添加一个动作侦听器或识别哪个按钮被按下时,事情就不太好了。

MyFrame.java

我的框架

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

public class MyFrame extends JFrame implements ActionListener 
{
    private JPanel panel;
    private static JButton[] buttons  = new JButton[18];
    // set all static calculate JButtons
    private static JButton equalsBtn, addBtn, subBtn, multiBtn, divBtn, clearBtn, plusMinusBtn, decimalBtn;
    // set all static number JBtuttons
    private static JButton zeroBtn, oneBtn, twoBtn, threeBtn, fourBtn, fiveBtn, sixBtn, sevenBtn, eightBtn, nineBtn;
    private static JTextField resultField;
    // numOne is the first row of figures en the second numSecond is the second row
    private static double numOne, numSecond, result;
    private static double plusMinus;
    private static int addClick = 0, subClick = 0, multiClick = 0, divClick = 0;
    private static int clearField;

    public MyFrame() {
        // configure the JFrame
        super("Rekennen maar!");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setSize(230, 370);
        setLocationRelativeTo(null);

        // confugure the JPanel
        panel = new JPanel();
        panel.setSize(230, 370);
        panel.setLayout(new GridLayout(5, 0));

        // array string whit all the button names
        String a_btnNames[] = {"clearBtn", "plusMinusBtn", "divBtn", "multiBtn", "sevenBtn", "eightBtn", "nineBtn", "subBtn", "fourBtn", "fiveBtn", "sixBtn",                               "addBtn", "oneBtn", "twoBtn", "threeBtn", "equalsBtn", "zeroBtn", "decimalBtn"};
        // array String whit all button characters
        String a_btnCharts[] = {"C", "+/-", "/", "*", "7", "8", "9", "-", "4", "5", "6", "+", "1", "2", "3", "=", "0", "."};

        for(int i = 0; i < buttons.length; i++)
        {
            // make new button name 
            buttons[i]  = new JButton(a_btnNames[i]);
            // add button to panel
            panel.add(new JButton(a_btnCharts[i]));
            //System.out.println(buttons[i]);
        }

        // add panel when he's filled 
        add(panel);
        setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
        // press the button
        if ( e.getSource() == ...... ) {
            System.out.println("123");  
        }   
    } 
}

Main.java

主程序

public class Main {
    public static void main(String[] arg) {
        MyFrame mf = new MyFrame();
    }
}

采纳答案by Mike M

There is nothing listening for when the buttons are pressed. When you create each button, you must give them action listeners.

按下按钮时没有任何声音。创建每个按钮时,必须为它们提供动作侦听器。

Also, you should be adding the same button that you create.

此外,您应该添加与您创建的按钮相同的按钮。

buttons[i] = new JButton("" + a_btnNames[i]);
//buttons[i] should now be added to the panel

New for loop should be...

新的 for 循环应该是...

for(int i = 0; i < buttons.length; i++){
    buttons[i] = new JButton("" + a_btnNames[i]); //create button & add to array
    buttons[i].addActionListener(this); //add an action listener to the current button
    panel.add(buttons[i]); //add that same button to the panel

}

回答by Rayf

Alter the loop, to something like this.

改变循环,像这样。

for(int i = 0; i < buttons.length; i++)
    {
        // make new button name 
        JButton btn = new JButton("" + a_btnNames[i]);
        buttons[i]  = btn;
        btn.addActionListener(this);
        // add button to panel
        panel.add(btn);
        //System.out.println(buttons[i]);
    }

And then have an actionPerformed() like this.

然后有一个这样的 actionPerformed()。

public void actionPerformed(ActionEvent evt) {
   Object src = evt.getSource();
   if (src == buttons[0]) {
     //First button actions
   } else if (src == buttons[1]) {
     //Second button actions
   }
}

Should work.

应该管用。

回答by Sage

  1. Well i don't see any problem when you know that evt.getSource()return the source Component of the ActionEvent.

  2. To register an action listener to a component like JButton, we usually do this:

    jButton.addActionListener(anActionListener);
    

    For your context you can pass ActionListenerusing the help of this.

  3. Do not implement ActionListenerinterface to some class which doesn't listen to such Event or have them. If required declare a new class by implementing it and use instance of that class to register the listener.

     class MyActionListener implements ActionListener
     {
         public void actionPerformed(ActionEvent e) {
             // press the button
          }     
      }
    
      MyActionListener actionListener = new MyActionListener();
      jButton1.addActionListener(actionListener);
      jButton2.addActionListener(actionListener);
      jButton3.addActionListener(actionListener);
    
  1. 好吧,当您知道evt.getSource()返回ActionEvent.

  2. 要将动作侦听器注册到像 那样的组件JButton,我们通常这样做:

    jButton.addActionListener(anActionListener);
    

    对于您的上下文,您可以ActionListener使用this.

  3. 不要ActionListener为某些不侦听此类事件或拥有它们的类实现接口。如果需要,通过实现它来声明一个新类并使用该类的实例来注册侦听器。

     class MyActionListener implements ActionListener
     {
         public void actionPerformed(ActionEvent e) {
             // press the button
          }     
      }
    
      MyActionListener actionListener = new MyActionListener();
      jButton1.addActionListener(actionListener);
      jButton2.addActionListener(actionListener);
      jButton3.addActionListener(actionListener);
    

I'm trying to dynamically add buttons (JButtons), which changes names everytime.

我正在尝试动态添加按钮(JButtons),它每次都会更改名称。

But you are probably having misconception about setting name with new JButton("some text"). This doesn't set name of the Button, rather it's text content. You need to use button.setName("aName")instead.

但是您可能对使用new JButton("some text"). 这不会设置按钮的名称,而是文本内容。你需要button.setName("aName")改用。

However, You can always use the either of the getNameor getTextmethod to identify your specific button.

但是,您始终可以使用getNamegetText方法中的任一个来标识您的特定按钮。

public void actionPerformed(ActionEvent e) {
        // press the button

        JButton button = (JButton)e.getSource();
        Syestem.out.println(button.getName()); // get the name
        System.out.println(button.getText()) // get the text content

        if(button.getText().equals("clearBtn"))
            // clear things for me
    } 

回答by vels4j

Few changes

变化不大

for(int i = 0; i < buttons.length; i++)
    {
        // make new button name 
        buttons[i]  = new JButton(a_btnCharts[i]);
        buttons[i].setName(a_btnNames[i]); // assign button name
        buttons[i].addActionListener(this); // assign action listener 
        // add button to panel
        panel.add(buttons[i]);
    }

and

@Override
public void actionPerformed(ActionEvent e) {
    // press the button
      System.out.println(e.getActionCommand()); 
      JButton btn=(JButton)e.getSource();
      System.out.println(btn.getName());  // use name or action command in if statment
} 

Your main method should be

你的主要方法应该是

public static void main(String[] arg) {
    SwingUtilities.invokeLater( new Runnable() {
        @Override
        public void run() {
            MyFrame mf = new MyFrame();
        }
    });
}

Read The Event Dispatch Thread

阅读事件调度线程

回答by Dario

Remember to add the ActionListener to JButtons first. Then, using getSource() this way doesn't help in your case because you are not keeping references to the JButtons you are adding to the panel. You can use getActionCommand() instead - Default behavior is it returns the label of the button but you can override it with setActionCommand(...):

请记住首先将 ActionListener 添加到 JButtons。然后,以这种方式使用 getSource() 对您的情况没有帮助,因为您没有保留对要添加到面板的 JButton 的引用。您可以改用 getActionCommand() - 默认行为是它返回按钮的标签,但您可以使用 setActionCommand(...) 覆盖它:

if ( e.getActionCommand().equals(a_btnCharts[0] ) {

回答by Larois

loop over the JButton array:

循环 JButton 数组:

for (int i = 0; i < buttons.length; ++i) {
if (e.getSource()==buttons[i]){
    System.out.println("Button name: " + a_btnNames[i] +"<> Char:"+ a_btnCharts[i] + " pressed");
}

}

}