Java 为什么调用了paintComponents但没有看到?
我有一个网格布局的单元格,每个单元格都扩展了JComponent。 GridLayout管理扩展JPanel的Board类,Board对象/面板与其他两个面板一起添加到主面板 下面是Cell类: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
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
xrow*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=新单元格[游戏行][游戏列];