简体   繁体   English

我可以将ActionListener添加到未明确定义的JButton吗?

[英]Can I add an ActionListener to a JButton that is not explicitely defined?

I'm trying to make a chess-board kind of thing with each tile being a JButton. 我正在尝试制作一种棋盘式的东西,每个图块都是一个JButton。 I want to add the same actionListener to every button. 我想将相同的actionListener添加到每个按钮。 Here's the code: 这是代码:

package checker;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class mainClass extends JFrame   {

JPanel board = new JPanel();
ActionListener btnPrs = new btnPressed();


    public mainClass()
    {

        board.setLayout(new GridLayout(8,8,0,0));
        for(int i = 0; i<8; i++)
            for(int j = 0; j<8; j++)
            {
                if( i%2 == 0 && j%2 == 0 || i%2 == 1 && j%2 == 1)
                {   
                    board.add(new DrawWhite());
                    //board.add(new DrawWhite().addActionListener(btnPrs));

                }
                else board.add(new DrawBlack());
            }

        add(board);
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        mainClass frame = new mainClass();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400,400);
        frame.setVisible(true);
        frame.setTitle("Checker");
        frame.setLocationRelativeTo(null);

    }

    class DrawWhite extends JButton
    {
        protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);

            g.setColor(Color.WHITE);
            g.fillRect(0,0, 50,50);
            }       
    }

    class DrawBlack extends JButton
    {
    protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);

            g.setColor(Color.BLACK);
            g.fillRect(0, 0, 50, 50);

        }
    }


    class btnPressed implements ActionListener
    {

        @Override
        public void actionPerformed(ActionEvent e) {

            System.out.println("pressed!");

        }
     }

     }

I don't want to explicitly define 64 buttons and add ActionListeners to each of them manually. 我不想显式定义64个按钮,并手动将ActionListeners添加到每个按钮。 I tried they way that is included as a comment on line 23. Is there a proper way to do it? 我尝试过将它们包含在第23行的注释中。是否有适当的方法?

Any help would be highly appreciated. 任何帮助将不胜感激。

Just store the button in a temporary variable: 只需将按钮存储在一个临时变量中:

DrawWhite dw = new DrawWhite();
dw.addActionListener(btnPrs);
board.add(dw);

If you really want " each tile being a JButton " then yes, you will need to define 64 JButtons, since the same component can't be added twice to its parent. 如果您确实希望“ 每个图块都是JButton ”,那么您将需要定义64个JButton,因为同一组件不能两次添加到其父级。

But if what you really need is that each tile is clickable, you will need to add no JButton at all. 但是,如果您真正需要的是每个图块都是可单击的,则根本不需要添加JButton。 Use just a custom JPanel for the whole board, overriding its paintComponent method to drawd black and white squares. 整个板只使用一个自定义的JPanel ,覆盖其paintComponent方法以绘制黑色和白色正方形。 A single mouseListener attached to this JPanel could tell black from white tiles based on the x and y coordinates. 附加到此JPanel单个mouseListener可以根据x和y坐标区分白色瓷砖中的黑色。

Working code follows: 工作代码如下:

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

public class mainClass extends JFrame   {

JPanel board = new BoardPanel();
MouseListener btnPrs = new btnPressed();


    public mainClass()
    {
        board.addMouseListener(btnPrs);
        add(board);
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        mainClass frame = new mainClass();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400,400);
        frame.setVisible(true);
        frame.setTitle("Checker");
        frame.setLocationRelativeTo(null);

    }

    private Color blackOrWhite(int i, int j) {
        return (i + j) % 2 == 0 ? 
                Color.WHITE
                : Color.BLACK;
    }


    class BoardPanel extends JPanel
    {
        protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);

            for (int i = 0; i < 8; i++) {
                for (int j = 0; j < 8; j++) {
                    Color color = blackOrWhite(i, j);

                        g.setColor(color);
                        g.fillRect(i * 50, j * 50, 50, 50);

                    }
                }
            }
    }

    class btnPressed extends MouseAdapter
    {

        @Override
        public void mouseClicked(MouseEvent e) {
            int x = e.getX();
            int y = e.getY();
            System.out.println("pressed!");
            System.out.println(blackOrWhite(x/50, y/50));
        }
     }

}

Bad thing is that you loose the "resizability" of JButton s in a BorderLayout . 不好的是,您在BorderLayout失去了JButton的“可调整大小”。 Also, you can no longer activate a tile by keyboard (as you could with JButton s), just by mouse clicks. 而且,您不再能够通过键盘(就像使用JButton )通过键盘来激活磁贴。 Good thing is that you now have way less Objects instantiated, which brings a better memory footprint. 好消息是,您现在减少了实例化对象的方式,这带来了更好的内存占用。

Hope it's useful. 希望它有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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