Java 覆盖paintcomponent仅适用于GridLayout的第一个按钮

Java 覆盖paintcomponent仅适用于GridLayout的第一个按钮,java,swing,jbutton,paintcomponent,Java,Swing,Jbutton,Paintcomponent,大家好,我刚开始编写一个小游戏,并在上面使用java JButtons,我创建了一个JButton herited类,它覆盖了paintcomponent,每个按钮都放置在一个带有网格布局的JPanel中,按钮外观都是默认的,除了第一个按钮(在左上角),如何让每个按钮都按照我在paintcomponent方法中的定义进行绘制? 目前,我使用两个类: package main; import java.awt.BorderLayout; import java.awt.Dimension; im

大家好,我刚开始编写一个小游戏,并在上面使用java JButtons,我创建了一个JButton herited类,它覆盖了paintcomponent,每个按钮都放置在一个带有网格布局的JPanel中,按钮外观都是默认的,除了第一个按钮(在左上角),如何让每个按钮都按照我在paintcomponent方法中的定义进行绘制? 目前,我使用两个类:

package main;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class World {

private Square[][] map;

public World() {

    // Panels settings

    JPanel mapHUD = new JPanel();
    mapHUD.setPreferredSize(new Dimension(400, 400));
    mapHUD.setLayout(new GridLayout(8, 8));

    JPanel blueTeamHUD = new JPanel();
    blueTeamHUD.setPreferredSize(new Dimension(100, 400));

    JPanel redTeamHUD = new JPanel();
    redTeamHUD.setPreferredSize(new Dimension(100, 400));

    JPanel spellsHUD = new JPanel();
    spellsHUD.setPreferredSize(new Dimension(600, 200));

    // Map settings

    map = new Square[8][8];
    for (int j = 0; j < 8; j++)
        for (int i = 0; i < 8; i++) {
            map[i][j] = new Square(i, j, i + "" + j);
            mapHUD.add(map[i][j]);
        }

    // Frame settings

    JFrame frame = new JFrame();
    frame.setTitle("Koko");
    frame.setSize(600, 600);
    frame.setResizable(false);
    frame.setLocationRelativeTo(null);

    frame.setLayout(new BorderLayout());
    frame.getContentPane().add(mapHUD, BorderLayout.CENTER);
    frame.getContentPane().add(blueTeamHUD, BorderLayout.WEST);
    frame.getContentPane().add(redTeamHUD, BorderLayout.EAST);
    frame.getContentPane().add(spellsHUD, BorderLayout.SOUTH);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

}
}

package main;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JButton;

public class Square extends JButton implements MouseListener {

private static final long serialVersionUID = 1L;

private int x;
private int y;

public Square(int x, int y, String name) {
    super(name);
    this.addMouseListener(this);
    this.x = x;
    this.y = y;
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    g2.setPaint(Color.BLACK);
    g2.fillRect((int) this.getLocation().getX(), (int) this.getLocation().getY(), this.getWidth(),             
this.getHeight());
}

// MouseListener methods

@Override
public void mouseClicked(MouseEvent arg0) {
    // TODO Auto-generated method stub

}

@Override
public void mouseEntered(MouseEvent arg0) {
    // TODO Auto-generated method stub
    this.setBackground(Color.BLACK);
}

@Override
public void mouseExited(MouseEvent arg0) {
    // TODO Auto-generated method stub
    this.setBackground(Color.RED);
}

@Override
public void mousePressed(MouseEvent arg0) {
    // TODO Auto-generated method stub

}

@Override
public void mouseReleased(MouseEvent arg0) {
    // TODO Auto-generated method stub

}

}
packagemain;
导入java.awt.BorderLayout;
导入java.awt.Dimension;
导入java.awt.GridLayout;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共阶级世界{
私人广场【】【】地图;
公共世界(){
//面板设置
JPanel mapud=新的JPanel();
设置首选尺寸(新尺寸(400400));
setLayout(新的GridLayout(8,8));
JPanel blueTeamHUD=新的JPanel();
blueTeamHUD.setPreferredSize(新尺寸(100400));
JPanel redTeamHUD=新的JPanel();
设置PreferredSize(新尺寸(100400));
JPanel spellsHUD=新的JPanel();
spellsHUD.setPreferredSize(新维度(600200));
//地图设置
地图=新广场[8][8];
对于(int j=0;j<8;j++)
对于(int i=0;i<8;i++){
map[i][j]=新正方形(i,j,i+“”+j);
mapHUD.add(map[i][j]);
}
//帧设置
JFrame=新JFrame();
帧。设置标题(“Koko”);
框架。设置尺寸(600600);
frame.setresizeable(false);
frame.setLocationRelativeTo(空);
frame.setLayout(新的BorderLayout());
frame.getContentPane().add(mapud,BorderLayout.CENTER);
frame.getContentPane().add(blueTeamHUD,BorderLayout.WEST);
frame.getContentPane().add(redTeamHUD,BorderLayout.EAST);
frame.getContentPane().add(spellsHUD,BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
主包装;
导入java.awt.Color;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.event.MouseEvent;
导入java.awt.event.MouseListener;
导入javax.swing.JButton;
公共类Square扩展JButton实现MouseListener{
私有静态最终长serialVersionUID=1L;
私人INTX;
私营企业;
公共正方形(整数x,整数y,字符串名){
超级(姓名);
这个。addMouseListener(这个);
这个.x=x;
这个。y=y;
}
@凌驾
公共组件(图形g){
超级组件(g);
图形2d g2=(图形2d)g;
g2.setPaint(颜色为黑色);
g2.fillRect((int)this.getLocation().getX(),(int)this.getLocation().getY(),this.getWidth(),
这个是.getHeight());
}
//MouseListener方法
@凌驾
公共无效鼠标单击(鼠标事件arg0){
//TODO自动生成的方法存根
}
@凌驾
公共无效鼠标事件(鼠标事件arg0){
//TODO自动生成的方法存根
这个.背景(颜色.黑色);
}
@凌驾
public void mouseexitted(MouseEvent arg0){
//TODO自动生成的方法存根
这个.挫折背景(颜色.红色);
}
@凌驾
public void mousePressed(MouseEvent arg0){
//TODO自动生成的方法存根
}
@凌驾
公共无效MouseEvent arg0{
//TODO自动生成的方法存根
}
}
这是非常错误的:

g2.fillRect((int) this.getLocation().getX(), int) this.getLocation().getY(), 
    this.getWidth(), this.getHeight());
获取的位置是组件(按钮)相对于其容器的位置,即JPanel。您需要相对于组件本身从0、0开始绘制,依此类推:

g2.fillRect(0, 0, this.getWidth(), this.getHeight());
这是你需要的


这实际上就是为什么只有第一个按钮的绘图有效:对于第一个按钮,位置是相对于JPanel的0,0。

非常感谢@保尔·杜布雷特:不客气。请注意,如果你给那个正方形类
public int getX()
public int getY()
方法,你会遇到问题,因为JButton(和所有组件)已经有了这些方法,如果你不小心覆盖了它们,你的按钮会被放置在奇怪的位置,将您的x和y类变量更改为更有意义的变量,这样可以避免以后的麻烦。