Simple ActionListener within a 2D array of JButtons

荒凉一梦 提交于 2019-11-27 15:54:53

very simple way is add ClientProperty to the JComponent, add to your definition into loop e.g.

buttons[i][j].putClientProperty("column", i);
buttons[i][j].putClientProperty("row", j);
buttons[i][j].addActionListener(new MyActionListener());

rename e to the MyActionListener and change its contents

public class MyActionListener implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {
        JToggleButton btn = (JToggleButton) e.getSource();
        System.out.println("clicked column " + btn.getClientProperty("column")
                + ", row " + btn.getClientProperty("row"));
}

EDIT:

for MinerCraft clone isn't required to implements ony of Listeners, there is only about Icon, find out that in this code (don't implement any of Listeners anf remove used ItemListener)

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

public class ButtonsIcon extends JFrame {

    private static final long serialVersionUID = 1L;
    private Icon errorIcon = UIManager.getIcon("OptionPane.errorIcon");
    private Icon infoIcon = UIManager.getIcon("OptionPane.informationIcon");
    private Icon warnIcon = UIManager.getIcon("OptionPane.warningIcon");

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                ButtonsIcon t = new ButtonsIcon();
            }
        });
    }

    public ButtonsIcon() {
        setLayout(new GridLayout(2, 2, 4, 4));

        JButton button = new JButton();
        button.setBorderPainted(false);
        button.setBorder(null);
        button.setFocusable(false);
        button.setMargin(new Insets(0, 0, 0, 0));
        button.setContentAreaFilled(false);
        button.setIcon((errorIcon));
        button.setRolloverIcon((infoIcon));
        button.setPressedIcon(warnIcon);
        button.setDisabledIcon(warnIcon);
        add(button);

        JButton button1 = new JButton();
        button1.setBorderPainted(false);
        button1.setBorder(null);
        button1.setFocusable(false);
        button1.setMargin(new Insets(0, 0, 0, 0));
        button1.setContentAreaFilled(false);
        button1.setIcon((errorIcon));
        button1.setRolloverIcon((infoIcon));
        button1.setPressedIcon(warnIcon);
        button1.setDisabledIcon(warnIcon);
        add(button1);
        button1.setEnabled(false);

        final JToggleButton toggleButton = new JToggleButton();
        toggleButton.setIcon((errorIcon));
        toggleButton.setRolloverIcon((infoIcon));
        toggleButton.setPressedIcon(warnIcon);
        toggleButton.setDisabledIcon(warnIcon);
        toggleButton.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(ItemEvent e) {
                if (toggleButton.isSelected()) {
                } else {
                }
            }
        });
        add(toggleButton);

        final JToggleButton toggleButton1 = new JToggleButton();
        toggleButton1.setIcon((errorIcon));
        toggleButton1.setRolloverIcon((infoIcon));
        toggleButton1.setPressedIcon(warnIcon);
        toggleButton1.setDisabledIcon(warnIcon);
        toggleButton1.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(ItemEvent e) {
                if (toggleButton1.isSelected()) {
                } else {
                }
            }
        });
        add(toggleButton1);
        toggleButton1.setEnabled(false);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setVisible(true);
    }
}

Just add the row and column data to each listener. You could add an explicit constructor, but I suggest adding a little method (which may have more added to it later).

            buttons[i][j].addActionListener(e(i, j));
...
private ActionListener e(final int i, final int j) {
    return new ActionListener() {
        // i and j available here
        ...

(In JDK8 you should be able to use a lambda to reduce the syntax clutter.)

And then renaming it with a better name.

I made a minesweeper game and ran into a similar problem. One of the only ways you can do it, is to get the absolute location of the clicked button, then divide that by the x and y between buttons, so for me it was

if ((e.getComponent().getX() != (randx) * 25 && e.getComponent().getY() != (randy) * 25) &&bomb[randx][randy] == false) {

This code was to check if the area had bombs. So I had 25 x and y difference between location of bombs. That will just give you a general idea on how to do this.

I believe: (x - x spacing on left side) / buffer - 1 would work.

Instead of 'e.getSource()' you can always call 'e.getActionCommand()'. For each button you can specify this by:

JButton button = new JButton("Specify your parameters here"); /*you get these from getActionCommand*/
button.setText("title here"); /*as far as I remember*/
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!