Java Swing为一组按钮添加鼠标Listener(内部类)会导致故障

时间:2015-10-01 23:10:20

标签: java arrays swing button mouseevent

好的,所以我想要构建的程序很简单。有五个按钮,命名为0到4.如果按下任何按钮,则在控制台中打印数字0到4。

enter image description here

我使用GridLayout将按钮放在框架中。为了设置每个按钮,我创建了一个方法inicializarIG()

这个inicializarIG()方法创建了一个包含5个按钮的数组,并在for循环中执行:

  • 为按钮数组中的每个单元格创建一个按钮实例。
  • 为每个按钮设置一个mouseListener。每个Listener中打印的值是不同的,它由循环的索引决定(我想通过使用索引来做!)。
  • 将按钮添加到主框架。

令人惊讶的是,这个简单的程序无法正常工作。无论按下什么按钮,它总是打印数字“5”:

enter image description here

注意:我必须将index var放在inicializarIG()方法之外,以便实现监听器的var范围。我不知道问题是否有关,只是说因为它可能会有所帮助。

代码:

import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JFrame;


public class IGrafica {

    private JFrame frame;
    public int index=0;



    public IGrafica(){
        frame = new JFrame();
        configureFrame();
        inicializarIG();

    }

    public void configureFrame(){
        frame.setBounds(100,100,400,400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new GridLayout(1,5)); //
    }


    public void inicializarIG(){

        //Buttons

        JButton [] botones = new JButton [5];

        //Loop to set up buttons and add the mouseListener
        for (index = 0; index < botones.length; index++) {
            botones[index] = new JButton(Integer.toString(index));


            //Set up each listener 
            botones[index].addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    System.out.println(index);
                    //texto.setBackground(colores[index]);
                }           
            });

            //Add the button
            frame.getContentPane().add(botones[index]);

        }       
    }



    public void visualizate(){
        frame.setVisible(true);
    }



    public static void main(String[] args) {        
        IGrafica window = new IGrafica();
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                window.visualizate();
            }
        });

    }
}

提前谢谢你。任何想法都会受到欢迎。

赫苏斯

1 个答案:

答案 0 :(得分:5)

首先,不要使用MouseListener,而是使用ActionListener,因为这最适合按钮。接下来,你需要记住你的监听器是它自己的一个类,它需要一个自己的变量来存储它自己的索引,否则它使用循环索引的最终值,这不是你想要的。要么是这个,要么使用ActionEvent的actionCommand属性,该属性将与按钮的文本匹配。所以:

botones[index].addActionListener(new MyActionListener(index));

// a private inner class
private class MyActionListener implements ActionListener {
    private int index;

    public MyActionListener(int index) {
        this.index = index;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("index is: " + index);
        System.out.println("Action Command is: " + e.getActionCommand());
    }
}

或者如果你想使用匿名内部类:

        botones[index].addActionListener(new ActionListener() {
            private int myIndex;

            {
                this.myIndex = index;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("index is: " + myIndex);
            }
        });