Java 为什么调用了paintComponents但没有看到?

Java 为什么调用了paintComponents但没有看到?,java,swing,grid-layout,jcomponent,Java,Swing,Grid Layout,Jcomponent,我有一个网格布局的单元格,每个单元格都扩展了JComponent。 GridLayout管理扩展JPanel的Board类,Board对象/面板与其他两个面板一起添加到主面板 下面是Cell类: public class Cell extends JComponent{ private int row; private int col; private int rowHeight; private int colWidth; private bool

我有一个网格布局的单元格,每个单元格都扩展了JComponent。 GridLayout管理扩展JPanel的Board类,Board对象/面板与其他两个面板一起添加到主面板

下面是Cell类:

public class Cell extends JComponent{

    private int row;
    private int col;

    private int rowHeight;
    private int colWidth;

    private boolean active = false;

    private Color color;

    public Cell(int row, int col, Color color) {
        this.row = row;
        this.col = col;

        this.color = color;
    }

    public Cell(int row, int col, int rowHeight, int colWidth, Color color) {
        this.row = row;
        this.col = col;

        this.rowHeight = rowHeight;
        this.colWidth = colWidth;

        this.color = color;
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        paintSquare(g);
    }

    private void paintSquare(Graphics g) {
        g.setColor(color);
        g.fillRoundRect(
            (int) (col * colWidth),
            (int) (row * rowHeight),
            (int) (rowHeight),
            (int) (colWidth),
            10,
            10);

    }

    public int getCol()
    {
        return col;
    }

    public int getRow()
    {
        return row;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }
}
下面是Board课程:

public class Board extends JPanel {

    public Cell[][] gameBoard;

    public final int GAME_ROWS;
    public final int GAME_COLUMNS;

    public int rowHeight;
    public int columnWidth;

    public Color selectedColor;

    public Board(int GAME_ROWS, int GAME_COLUMNS) {
        this.GAME_COLUMNS = GAME_COLUMNS;
        this.GAME_ROWS = GAME_ROWS;

        calculateDimensions();

        createGameBoard();

        setUpBoardPanel();
    }

    private void calculateDimensions() {
        rowHeight = (int) this.getHeight() / GAME_ROWS;
        columnWidth = (int) this.getWidth() / GAME_COLUMNS;
    }

    private void createGameBoard() {
        Random random = new Random();
        int cellColor;
        gameBoard = new Cell[GAME_ROWS][GAME_COLUMNS];
        for (int row = 0; row < GAME_ROWS; row++) {
            for (int col = 0; col < GAME_COLUMNS; col++) {
                cellColor = random.nextInt(Properties.COLORS.length);
                Cell newCell = new Cell(row, col, rowHeight, 
                    columnWidth,Properties.COLORS[cellColor]);
                gameBoard[row][col] = newCell;
            }
        }
    }

    private void setUpBoardPanel() {
        setLayout(new GridLayout(GAME_ROWS, GAME_COLUMNS));
        setPreferredSize(Properties.BOARD_TABLE_SIZE);
        setBorder(new EmptyBorder(20, 10, 0, 0));
        setBackground(Properties.BACKGROUND_COLOR);

        addBoardPanelComponents();
    }

    private void addBoardPanelComponents() {
        for(int r = 0; r < GAME_ROWS; r++) {
            for(int c = 0; c < GAME_COLUMNS; c++) {
                add(gameBoard[r][c]);
            }
        }
    }
}
公共类板扩展JPanel{
公共单元[][]游戏板;
公开决赛整场比赛;
公开最终int GAME_专栏;
公众身高;
公共int列宽度;
公共颜色选择颜色;
公用板(整块游戏行,整块游戏列){
this.GAME\u COLUMNS=GAME\u COLUMNS;
this.GAME\u ROWS=GAME\u ROWS;
计算尺寸();
createGameBoard();
setUpBoardPanel();
}
私有无效计算维度(){
rowHeight=(int)this.getHeight()/GAME\u ROWS;
columnWidth=(int)this.getWidth()/GAME\u COLUMNS;
}
私有void createGameBoard(){
随机=新随机();
细胞色素;
gameBoard=新单元格[游戏行][游戏列];
对于(int row=0;row
主面板上的所有内容都显示得非常完美,我可以看到板面板被添加了,因为当我更改其背景时,它显示为设置好的

我已经看过了很多教程,我称之为超级正确,所以我不确定如何正确地添加和调用组件,而只是不显示

要查看完整的程序代码,您可以转到my,但相关代码在上面。蒂亚

核心问题是,您不了解组件的坐标空间是如何工作的

组件的
x
/
y
位置相对于其父组件。任何组件/容器的左上角总是
0x0

所以当你做这样的事情时

g.fillRoundRect(
                (int) (col * colWidth),
                (int) (row * rowHeight),
                (int) (rowHeight),
                (int) (colWidth),
                10,
                10);
g.fillRoundRect(
                0,
                0,
                getWidth() - 1,
                getHeight() - 1,
                10,
                10);
您的意思是,相对于组件本身的左上角(始终为
0x0
),填充一个从
col*width
x
row*rowHeight
开始的矩形

你应该做的事情更像这样

g.fillRoundRect(
                (int) (col * colWidth),
                (int) (row * rowHeight),
                (int) (rowHeight),
                (int) (colWidth),
                10,
                10);
g.fillRoundRect(
                0,
                0,
                getWidth() - 1,
                getHeight() - 1,
                10,
                10);
这将填充组件的整个可见区域

但是为什么要使用
getWidth
getHeight
。在这种情况下,这可以确保组件的整个可见区域都被填充,但是如何影响组件的大小呢

首选方法是重写组件的
getPreferredSize
方法,并返回“首选”大小(所有条件都相同)

这将向父布局管理器提供有关组件“希望”布局方式的提示

另一个问题是

    private void calculateDimensions() {
        rowHeight = (int) this.getHeight() / GAME_ROWS;
        columnWidth = (int) this.getWidth() / GAME_COLUMNS;
    }
这是毫无意义的,因为在组件完成布局传递之前,它的大小是
0x0
,因此,基本上您是说
行高和
列宽应该是
0x0
:/

老实说,最好还是把它扔掉。如果需要,可直接将已知值植入
单元格

可运行的示例。。。

导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.Graphics;
导入java.awt.GridLayout;
导入java.util.Random;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
导入javax.swing.border.EmptyBorder;
导入javax.swing.border.LineBorder;
公开课考试{
公共静态void main(字符串[]args){
新测试();
}
公开考试(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
例如printStackTrace();
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
添加(新板(10,10));
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共课程委员会扩展JPanel{
公共单元[][]游戏板;
公开决赛整场比赛;
公开最终int GAME_专栏;
公共int行高=50;
公共int列宽度=50;
公共颜色选择颜色;
公用板(整块游戏行,整块游戏列){
this.GAME\u COLUMNS=GAME\u COLUMNS;
this.GAME\u ROWS=GAME\u ROWS;
createGameBoard();
setUpBoardPanel();
}
私有void createGameBoard(){
随机=新随机();
细胞色素;
Color[]colors=新颜色[]{Color.BLUE、Color.青色、Color.GRAY、Color.GRAY、Color.GREEN、Color.GREEN、Color.GREEN、Color.GREEN、Color.GRAY、Color.GREEN、Color.浅灰、Color.洋红、Color.橙色、Color;
gameBoard=新单元格[游戏行][游戏列];