JButton sub-class 被初始化到 JPanel 的左上角

JButton sub-class is initialized to top-left corner of JPanel

我有一个按钮矩阵,它们是 JButton 的子class,全部位于 JFrame 的 JPanel 的 GridLayout 中。我最初在每个按钮上使用了空布局和 setBounds,但在阅读了一些暗示空布局可能会导致问题的帖子后更改为 GridLayout(在下面粘贴的代码中留下了空布局相关代码的注释)。两种布局都会出现此问题。当使用标准 JButton 而不是我的 sub-class 时,问题不会发生。请让我知道我可以提供但可能遗漏的其他信息。我只是在学习 Swing,所以我确定我可能遗漏了一些明显的东西,但在谷歌搜索/搜索 YouTube 寻找解决方案后我迷路了。谢谢!

JFrame class:

package com.company;

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

public class swingUI extends JFrame implements ActionListener {
    public static void main(String[] args) {
        new swingUI();
    }

    public swingUI(){

        this.setSize(400,400);

        //this.setLocationRelativeTo(null);

        Toolkit tk = Toolkit.getDefaultToolkit();
        Dimension dim = tk.getScreenSize();

        int xPos = (dim.width / 2) - (this.getWidth() / 2);
        int yPos = (dim.height / 2) - (this.getHeight() / 2);

        this.setLocation(xPos, yPos);

        this.setResizable(true);

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.setTitle("My Frame");

        this.setLayout(null);

        this.addKeypadUI(6,4);
        //this.addDisplay();

        this.setVisible(true);
    }

    private void addKeypadUI(int rows, int cols){
        JPanel panel = new JPanel();
        panel.setBackground(Color.red);
        panel.setBounds(0,0,200,300);
        GridLayout gridLayout = new GridLayout(rows, cols);
        panel.setLayout(gridLayout);
        for (int c = 0; c < rows; c++) {
            for (int r = 0; r < cols; r++) {

                KeypadButton button = new KeypadButton(r,c);
                button.setBackground(Color.BLACK);
                //button.setBounds(25 * r + 10, 25 * c + 10, 20, 20);
                button.setName(String.format("btn_%d_%d",r,c));
                button.addActionListener(this);
                panel.add(button);
            }
        }

        this.add(panel);
    }

//    private void addDisplay(){
//        JLabel jLabel = new JLabel();
//        jLabel.setText("Hello?");
//        jLabel.setForeground(Color.BLACK);
//        jLabel.setBackground(Color.BLACK);
//        jLabel.setBounds(250,20,110,110);
//        this.add(jLabel);
//
//    }

    @Override
    public void actionPerformed(ActionEvent e) {
        KeypadButton o = (KeypadButton) e.getSource();
        String name = o.getName();
        System.out.println(name);
        System.out.println(String.format("x: %d",o.getX()));
        System.out.println(String.format("y: %d",o.getY()));
    }
}

按钮子Class:

package com.company;

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

public class KeypadButton extends JButton {
    private int x;
    private int y;

    KeypadButton(int x, int y){
        this.x = x;
        this.y = y;
    }

    public int getX(){
        return this.x;
    }

    public int getY(){
        return this.y;
    }
}  

Class javax.swing.JComponent 有一个 getX() 方法和一个 getY() 方法。 JButtonJComponent 的子 class,因此继承了这些方法。因此,您的 KeypadButton class 覆盖 这些方法并返回不正确的值。您希望 x 成为网格中按钮的行,而 y 成为列,因此只需更改方法的名称,甚至像:

public int get_X() {
    return this.x;
}

public int get_Y() {
    return this.y;
}