Why are the paintComponents being called but not seen?
I have a GridLayout of Cells that each extends JComponent.
The GridLayout manages a Board class that extends JPanel and the Board object/panel is added to the main panel with two other panels.
Here's the Cell Class:
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;
}
}
Here's the Board Class:
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]);
}
}
}
}
Everything on the main panel is showing up perfectly, and I can see that the Board panel was added because I when I change its background it shows up as it's set.
I've looked through a bunch of tutorials and am calling super right so I'm not sure how the components could be added and called correctly and just not show up.
To see the full program code you can go to my github, but the relevant code is above. TIA!
java swing grid-layout jcomponent
|
show 3 more comments
I have a GridLayout of Cells that each extends JComponent.
The GridLayout manages a Board class that extends JPanel and the Board object/panel is added to the main panel with two other panels.
Here's the Cell Class:
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;
}
}
Here's the Board Class:
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]);
}
}
}
}
Everything on the main panel is showing up perfectly, and I can see that the Board panel was added because I when I change its background it shows up as it's set.
I've looked through a bunch of tutorials and am calling super right so I'm not sure how the components could be added and called correctly and just not show up.
To see the full program code you can go to my github, but the relevant code is above. TIA!
java swing grid-layout jcomponent
When overwriting paintComponent to draw on a component, you should do it on a JPanel, not on a JComponent
– Snowy_1803
Jan 1 at 2:14
@Snowy_1803 Can you explain further?
– Sarah Cohen
Jan 1 at 2:18
Your Cell class should extend JPanel, it’s not a new component type. Developers shouldn’t overwrite painting on any other component than JPanel and JLabel.
– Snowy_1803
Jan 1 at 2:26
1
@Snowy_1803 Where are you getting that information from? ExtendingJComponent
should be fine. Even though it's common to find code snippets online where people are extendingJPanel
for custom painting, it doesn't really make sense because it breaks the Liskov substitution principle. (JPanel
is supposed to be a container for other components.) OverridingpaintComponent
on aJLabel
frankly sounds like a pretty bad idea.
– Radiodef
Jan 1 at 2:32
My first thought is that this is a layout issue. Since you're using a grid layout, I'd recommend overridinggetPreferredSize
on theCell
class, and then avoid using any explicit sizing methods likesetPreferredSize
.
– Radiodef
Jan 1 at 2:37
|
show 3 more comments
I have a GridLayout of Cells that each extends JComponent.
The GridLayout manages a Board class that extends JPanel and the Board object/panel is added to the main panel with two other panels.
Here's the Cell Class:
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;
}
}
Here's the Board Class:
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]);
}
}
}
}
Everything on the main panel is showing up perfectly, and I can see that the Board panel was added because I when I change its background it shows up as it's set.
I've looked through a bunch of tutorials and am calling super right so I'm not sure how the components could be added and called correctly and just not show up.
To see the full program code you can go to my github, but the relevant code is above. TIA!
java swing grid-layout jcomponent
I have a GridLayout of Cells that each extends JComponent.
The GridLayout manages a Board class that extends JPanel and the Board object/panel is added to the main panel with two other panels.
Here's the Cell Class:
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;
}
}
Here's the Board Class:
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]);
}
}
}
}
Everything on the main panel is showing up perfectly, and I can see that the Board panel was added because I when I change its background it shows up as it's set.
I've looked through a bunch of tutorials and am calling super right so I'm not sure how the components could be added and called correctly and just not show up.
To see the full program code you can go to my github, but the relevant code is above. TIA!
java swing grid-layout jcomponent
java swing grid-layout jcomponent
asked Jan 1 at 2:02
Sarah CohenSarah Cohen
9717
9717
When overwriting paintComponent to draw on a component, you should do it on a JPanel, not on a JComponent
– Snowy_1803
Jan 1 at 2:14
@Snowy_1803 Can you explain further?
– Sarah Cohen
Jan 1 at 2:18
Your Cell class should extend JPanel, it’s not a new component type. Developers shouldn’t overwrite painting on any other component than JPanel and JLabel.
– Snowy_1803
Jan 1 at 2:26
1
@Snowy_1803 Where are you getting that information from? ExtendingJComponent
should be fine. Even though it's common to find code snippets online where people are extendingJPanel
for custom painting, it doesn't really make sense because it breaks the Liskov substitution principle. (JPanel
is supposed to be a container for other components.) OverridingpaintComponent
on aJLabel
frankly sounds like a pretty bad idea.
– Radiodef
Jan 1 at 2:32
My first thought is that this is a layout issue. Since you're using a grid layout, I'd recommend overridinggetPreferredSize
on theCell
class, and then avoid using any explicit sizing methods likesetPreferredSize
.
– Radiodef
Jan 1 at 2:37
|
show 3 more comments
When overwriting paintComponent to draw on a component, you should do it on a JPanel, not on a JComponent
– Snowy_1803
Jan 1 at 2:14
@Snowy_1803 Can you explain further?
– Sarah Cohen
Jan 1 at 2:18
Your Cell class should extend JPanel, it’s not a new component type. Developers shouldn’t overwrite painting on any other component than JPanel and JLabel.
– Snowy_1803
Jan 1 at 2:26
1
@Snowy_1803 Where are you getting that information from? ExtendingJComponent
should be fine. Even though it's common to find code snippets online where people are extendingJPanel
for custom painting, it doesn't really make sense because it breaks the Liskov substitution principle. (JPanel
is supposed to be a container for other components.) OverridingpaintComponent
on aJLabel
frankly sounds like a pretty bad idea.
– Radiodef
Jan 1 at 2:32
My first thought is that this is a layout issue. Since you're using a grid layout, I'd recommend overridinggetPreferredSize
on theCell
class, and then avoid using any explicit sizing methods likesetPreferredSize
.
– Radiodef
Jan 1 at 2:37
When overwriting paintComponent to draw on a component, you should do it on a JPanel, not on a JComponent
– Snowy_1803
Jan 1 at 2:14
When overwriting paintComponent to draw on a component, you should do it on a JPanel, not on a JComponent
– Snowy_1803
Jan 1 at 2:14
@Snowy_1803 Can you explain further?
– Sarah Cohen
Jan 1 at 2:18
@Snowy_1803 Can you explain further?
– Sarah Cohen
Jan 1 at 2:18
Your Cell class should extend JPanel, it’s not a new component type. Developers shouldn’t overwrite painting on any other component than JPanel and JLabel.
– Snowy_1803
Jan 1 at 2:26
Your Cell class should extend JPanel, it’s not a new component type. Developers shouldn’t overwrite painting on any other component than JPanel and JLabel.
– Snowy_1803
Jan 1 at 2:26
1
1
@Snowy_1803 Where are you getting that information from? Extending
JComponent
should be fine. Even though it's common to find code snippets online where people are extending JPanel
for custom painting, it doesn't really make sense because it breaks the Liskov substitution principle. (JPanel
is supposed to be a container for other components.) Overriding paintComponent
on a JLabel
frankly sounds like a pretty bad idea.– Radiodef
Jan 1 at 2:32
@Snowy_1803 Where are you getting that information from? Extending
JComponent
should be fine. Even though it's common to find code snippets online where people are extending JPanel
for custom painting, it doesn't really make sense because it breaks the Liskov substitution principle. (JPanel
is supposed to be a container for other components.) Overriding paintComponent
on a JLabel
frankly sounds like a pretty bad idea.– Radiodef
Jan 1 at 2:32
My first thought is that this is a layout issue. Since you're using a grid layout, I'd recommend overriding
getPreferredSize
on the Cell
class, and then avoid using any explicit sizing methods like setPreferredSize
.– Radiodef
Jan 1 at 2:37
My first thought is that this is a layout issue. Since you're using a grid layout, I'd recommend overriding
getPreferredSize
on the Cell
class, and then avoid using any explicit sizing methods like setPreferredSize
.– Radiodef
Jan 1 at 2:37
|
show 3 more comments
1 Answer
1
active
oldest
votes
The "core" issue is, you don't understand how the coordinate space of a component works.
The x
/y
position of component is relative to its parent. The top/left corner of any component/container is always 0x0
.
So when you do something like this...
g.fillRoundRect(
(int) (col * colWidth),
(int) (row * rowHeight),
(int) (rowHeight),
(int) (colWidth),
10,
10);
You're saying, fill a rect which starts at col * width
x row * rowHeight
relative to the top left corner of the component itself (which is always 0x0
)
What you should be doing is something more like this...
g.fillRoundRect(
0,
0,
getWidth() - 1,
getHeight() - 1,
10,
10);
This will fill the entire visible area of the component.
But why use getWidth
and getHeight
. Well, in this context, this ensures that the entire visible area of the component is filled, but how do you affect the size of the component?
The preferred way is to override the getPreferredSize
method of the component and return the "preferred" size (all things been equal).
@Override
public Dimension getPreferredSize() {
return new Dimension(colWidth, rowHeight);
}
This provides a hint to the parent layout manager about how the component would "like" to be laid out.
Another issue is...
private void calculateDimensions() {
rowHeight = (int) this.getHeight() / GAME_ROWS;
columnWidth = (int) this.getWidth() / GAME_COLUMNS;
}
This is pointless, because until the component has undergone a layout pass, it's size is 0x0
, so, basically you're saying the rowHeight
and columnWidth
should be 0x0
:/
Honestly, best to just rid of it. If you need to, seed a known value to the Cell
directly
Runnable example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Board(10, 10));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class Board extends JPanel {
public Cell gameBoard;
public final int GAME_ROWS;
public final int GAME_COLUMNS;
public int rowHeight = 50;
public int columnWidth = 50;
public Color selectedColor;
public Board(int GAME_ROWS, int GAME_COLUMNS) {
this.GAME_COLUMNS = GAME_COLUMNS;
this.GAME_ROWS = GAME_ROWS;
createGameBoard();
setUpBoardPanel();
}
private void createGameBoard() {
Random random = new Random();
int cellColor;
Color colors = new Color{Color.BLUE, Color.CYAN, Color.DARK_GRAY, Color.GRAY, Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.RED, Color.YELLOW};
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(colors.length);
Cell newCell = new Cell(row, col, rowHeight,
columnWidth, colors[cellColor]);
gameBoard[row][col] = newCell;
}
}
}
private void setUpBoardPanel() {
setLayout(new GridLayout(GAME_ROWS, GAME_COLUMNS));
setBorder(new EmptyBorder(20, 10, 0, 0));
setBackground(Color.RED);
addBoardPanelComponents();
}
private void addBoardPanelComponents() {
for (int r = 0; r < GAME_ROWS; r++) {
for (int c = 0; c < GAME_COLUMNS; c++) {
add(gameBoard[r][c]);
}
}
}
}
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, int rowHeight, int colWidth, Color color) {
this.row = row;
this.col = col;
this.rowHeight = rowHeight;
this.colWidth = colWidth;
this.color = color;
setBorder(new LineBorder(Color.BLACK));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(colWidth, rowHeight);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
paintSquare(g);
}
private void paintSquare(Graphics g) {
g.setColor(color);
g.fillRoundRect(
0,
0,
getWidth() - 1,
getHeight() - 1,
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;
}
}
}
Thank you so much. That answer was super well written and helpful! It solved my problem like a charm.
– Sarah Cohen
Jan 1 at 3:40
👍.............
– MadProgrammer
Jan 1 at 4:23
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53992610%2fwhy-are-the-paintcomponents-being-called-but-not-seen%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The "core" issue is, you don't understand how the coordinate space of a component works.
The x
/y
position of component is relative to its parent. The top/left corner of any component/container is always 0x0
.
So when you do something like this...
g.fillRoundRect(
(int) (col * colWidth),
(int) (row * rowHeight),
(int) (rowHeight),
(int) (colWidth),
10,
10);
You're saying, fill a rect which starts at col * width
x row * rowHeight
relative to the top left corner of the component itself (which is always 0x0
)
What you should be doing is something more like this...
g.fillRoundRect(
0,
0,
getWidth() - 1,
getHeight() - 1,
10,
10);
This will fill the entire visible area of the component.
But why use getWidth
and getHeight
. Well, in this context, this ensures that the entire visible area of the component is filled, but how do you affect the size of the component?
The preferred way is to override the getPreferredSize
method of the component and return the "preferred" size (all things been equal).
@Override
public Dimension getPreferredSize() {
return new Dimension(colWidth, rowHeight);
}
This provides a hint to the parent layout manager about how the component would "like" to be laid out.
Another issue is...
private void calculateDimensions() {
rowHeight = (int) this.getHeight() / GAME_ROWS;
columnWidth = (int) this.getWidth() / GAME_COLUMNS;
}
This is pointless, because until the component has undergone a layout pass, it's size is 0x0
, so, basically you're saying the rowHeight
and columnWidth
should be 0x0
:/
Honestly, best to just rid of it. If you need to, seed a known value to the Cell
directly
Runnable example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Board(10, 10));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class Board extends JPanel {
public Cell gameBoard;
public final int GAME_ROWS;
public final int GAME_COLUMNS;
public int rowHeight = 50;
public int columnWidth = 50;
public Color selectedColor;
public Board(int GAME_ROWS, int GAME_COLUMNS) {
this.GAME_COLUMNS = GAME_COLUMNS;
this.GAME_ROWS = GAME_ROWS;
createGameBoard();
setUpBoardPanel();
}
private void createGameBoard() {
Random random = new Random();
int cellColor;
Color colors = new Color{Color.BLUE, Color.CYAN, Color.DARK_GRAY, Color.GRAY, Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.RED, Color.YELLOW};
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(colors.length);
Cell newCell = new Cell(row, col, rowHeight,
columnWidth, colors[cellColor]);
gameBoard[row][col] = newCell;
}
}
}
private void setUpBoardPanel() {
setLayout(new GridLayout(GAME_ROWS, GAME_COLUMNS));
setBorder(new EmptyBorder(20, 10, 0, 0));
setBackground(Color.RED);
addBoardPanelComponents();
}
private void addBoardPanelComponents() {
for (int r = 0; r < GAME_ROWS; r++) {
for (int c = 0; c < GAME_COLUMNS; c++) {
add(gameBoard[r][c]);
}
}
}
}
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, int rowHeight, int colWidth, Color color) {
this.row = row;
this.col = col;
this.rowHeight = rowHeight;
this.colWidth = colWidth;
this.color = color;
setBorder(new LineBorder(Color.BLACK));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(colWidth, rowHeight);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
paintSquare(g);
}
private void paintSquare(Graphics g) {
g.setColor(color);
g.fillRoundRect(
0,
0,
getWidth() - 1,
getHeight() - 1,
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;
}
}
}
Thank you so much. That answer was super well written and helpful! It solved my problem like a charm.
– Sarah Cohen
Jan 1 at 3:40
👍.............
– MadProgrammer
Jan 1 at 4:23
add a comment |
The "core" issue is, you don't understand how the coordinate space of a component works.
The x
/y
position of component is relative to its parent. The top/left corner of any component/container is always 0x0
.
So when you do something like this...
g.fillRoundRect(
(int) (col * colWidth),
(int) (row * rowHeight),
(int) (rowHeight),
(int) (colWidth),
10,
10);
You're saying, fill a rect which starts at col * width
x row * rowHeight
relative to the top left corner of the component itself (which is always 0x0
)
What you should be doing is something more like this...
g.fillRoundRect(
0,
0,
getWidth() - 1,
getHeight() - 1,
10,
10);
This will fill the entire visible area of the component.
But why use getWidth
and getHeight
. Well, in this context, this ensures that the entire visible area of the component is filled, but how do you affect the size of the component?
The preferred way is to override the getPreferredSize
method of the component and return the "preferred" size (all things been equal).
@Override
public Dimension getPreferredSize() {
return new Dimension(colWidth, rowHeight);
}
This provides a hint to the parent layout manager about how the component would "like" to be laid out.
Another issue is...
private void calculateDimensions() {
rowHeight = (int) this.getHeight() / GAME_ROWS;
columnWidth = (int) this.getWidth() / GAME_COLUMNS;
}
This is pointless, because until the component has undergone a layout pass, it's size is 0x0
, so, basically you're saying the rowHeight
and columnWidth
should be 0x0
:/
Honestly, best to just rid of it. If you need to, seed a known value to the Cell
directly
Runnable example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Board(10, 10));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class Board extends JPanel {
public Cell gameBoard;
public final int GAME_ROWS;
public final int GAME_COLUMNS;
public int rowHeight = 50;
public int columnWidth = 50;
public Color selectedColor;
public Board(int GAME_ROWS, int GAME_COLUMNS) {
this.GAME_COLUMNS = GAME_COLUMNS;
this.GAME_ROWS = GAME_ROWS;
createGameBoard();
setUpBoardPanel();
}
private void createGameBoard() {
Random random = new Random();
int cellColor;
Color colors = new Color{Color.BLUE, Color.CYAN, Color.DARK_GRAY, Color.GRAY, Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.RED, Color.YELLOW};
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(colors.length);
Cell newCell = new Cell(row, col, rowHeight,
columnWidth, colors[cellColor]);
gameBoard[row][col] = newCell;
}
}
}
private void setUpBoardPanel() {
setLayout(new GridLayout(GAME_ROWS, GAME_COLUMNS));
setBorder(new EmptyBorder(20, 10, 0, 0));
setBackground(Color.RED);
addBoardPanelComponents();
}
private void addBoardPanelComponents() {
for (int r = 0; r < GAME_ROWS; r++) {
for (int c = 0; c < GAME_COLUMNS; c++) {
add(gameBoard[r][c]);
}
}
}
}
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, int rowHeight, int colWidth, Color color) {
this.row = row;
this.col = col;
this.rowHeight = rowHeight;
this.colWidth = colWidth;
this.color = color;
setBorder(new LineBorder(Color.BLACK));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(colWidth, rowHeight);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
paintSquare(g);
}
private void paintSquare(Graphics g) {
g.setColor(color);
g.fillRoundRect(
0,
0,
getWidth() - 1,
getHeight() - 1,
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;
}
}
}
Thank you so much. That answer was super well written and helpful! It solved my problem like a charm.
– Sarah Cohen
Jan 1 at 3:40
👍.............
– MadProgrammer
Jan 1 at 4:23
add a comment |
The "core" issue is, you don't understand how the coordinate space of a component works.
The x
/y
position of component is relative to its parent. The top/left corner of any component/container is always 0x0
.
So when you do something like this...
g.fillRoundRect(
(int) (col * colWidth),
(int) (row * rowHeight),
(int) (rowHeight),
(int) (colWidth),
10,
10);
You're saying, fill a rect which starts at col * width
x row * rowHeight
relative to the top left corner of the component itself (which is always 0x0
)
What you should be doing is something more like this...
g.fillRoundRect(
0,
0,
getWidth() - 1,
getHeight() - 1,
10,
10);
This will fill the entire visible area of the component.
But why use getWidth
and getHeight
. Well, in this context, this ensures that the entire visible area of the component is filled, but how do you affect the size of the component?
The preferred way is to override the getPreferredSize
method of the component and return the "preferred" size (all things been equal).
@Override
public Dimension getPreferredSize() {
return new Dimension(colWidth, rowHeight);
}
This provides a hint to the parent layout manager about how the component would "like" to be laid out.
Another issue is...
private void calculateDimensions() {
rowHeight = (int) this.getHeight() / GAME_ROWS;
columnWidth = (int) this.getWidth() / GAME_COLUMNS;
}
This is pointless, because until the component has undergone a layout pass, it's size is 0x0
, so, basically you're saying the rowHeight
and columnWidth
should be 0x0
:/
Honestly, best to just rid of it. If you need to, seed a known value to the Cell
directly
Runnable example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Board(10, 10));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class Board extends JPanel {
public Cell gameBoard;
public final int GAME_ROWS;
public final int GAME_COLUMNS;
public int rowHeight = 50;
public int columnWidth = 50;
public Color selectedColor;
public Board(int GAME_ROWS, int GAME_COLUMNS) {
this.GAME_COLUMNS = GAME_COLUMNS;
this.GAME_ROWS = GAME_ROWS;
createGameBoard();
setUpBoardPanel();
}
private void createGameBoard() {
Random random = new Random();
int cellColor;
Color colors = new Color{Color.BLUE, Color.CYAN, Color.DARK_GRAY, Color.GRAY, Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.RED, Color.YELLOW};
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(colors.length);
Cell newCell = new Cell(row, col, rowHeight,
columnWidth, colors[cellColor]);
gameBoard[row][col] = newCell;
}
}
}
private void setUpBoardPanel() {
setLayout(new GridLayout(GAME_ROWS, GAME_COLUMNS));
setBorder(new EmptyBorder(20, 10, 0, 0));
setBackground(Color.RED);
addBoardPanelComponents();
}
private void addBoardPanelComponents() {
for (int r = 0; r < GAME_ROWS; r++) {
for (int c = 0; c < GAME_COLUMNS; c++) {
add(gameBoard[r][c]);
}
}
}
}
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, int rowHeight, int colWidth, Color color) {
this.row = row;
this.col = col;
this.rowHeight = rowHeight;
this.colWidth = colWidth;
this.color = color;
setBorder(new LineBorder(Color.BLACK));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(colWidth, rowHeight);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
paintSquare(g);
}
private void paintSquare(Graphics g) {
g.setColor(color);
g.fillRoundRect(
0,
0,
getWidth() - 1,
getHeight() - 1,
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;
}
}
}
The "core" issue is, you don't understand how the coordinate space of a component works.
The x
/y
position of component is relative to its parent. The top/left corner of any component/container is always 0x0
.
So when you do something like this...
g.fillRoundRect(
(int) (col * colWidth),
(int) (row * rowHeight),
(int) (rowHeight),
(int) (colWidth),
10,
10);
You're saying, fill a rect which starts at col * width
x row * rowHeight
relative to the top left corner of the component itself (which is always 0x0
)
What you should be doing is something more like this...
g.fillRoundRect(
0,
0,
getWidth() - 1,
getHeight() - 1,
10,
10);
This will fill the entire visible area of the component.
But why use getWidth
and getHeight
. Well, in this context, this ensures that the entire visible area of the component is filled, but how do you affect the size of the component?
The preferred way is to override the getPreferredSize
method of the component and return the "preferred" size (all things been equal).
@Override
public Dimension getPreferredSize() {
return new Dimension(colWidth, rowHeight);
}
This provides a hint to the parent layout manager about how the component would "like" to be laid out.
Another issue is...
private void calculateDimensions() {
rowHeight = (int) this.getHeight() / GAME_ROWS;
columnWidth = (int) this.getWidth() / GAME_COLUMNS;
}
This is pointless, because until the component has undergone a layout pass, it's size is 0x0
, so, basically you're saying the rowHeight
and columnWidth
should be 0x0
:/
Honestly, best to just rid of it. If you need to, seed a known value to the Cell
directly
Runnable example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class Test {
public static void main(String args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Board(10, 10));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class Board extends JPanel {
public Cell gameBoard;
public final int GAME_ROWS;
public final int GAME_COLUMNS;
public int rowHeight = 50;
public int columnWidth = 50;
public Color selectedColor;
public Board(int GAME_ROWS, int GAME_COLUMNS) {
this.GAME_COLUMNS = GAME_COLUMNS;
this.GAME_ROWS = GAME_ROWS;
createGameBoard();
setUpBoardPanel();
}
private void createGameBoard() {
Random random = new Random();
int cellColor;
Color colors = new Color{Color.BLUE, Color.CYAN, Color.DARK_GRAY, Color.GRAY, Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.RED, Color.YELLOW};
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(colors.length);
Cell newCell = new Cell(row, col, rowHeight,
columnWidth, colors[cellColor]);
gameBoard[row][col] = newCell;
}
}
}
private void setUpBoardPanel() {
setLayout(new GridLayout(GAME_ROWS, GAME_COLUMNS));
setBorder(new EmptyBorder(20, 10, 0, 0));
setBackground(Color.RED);
addBoardPanelComponents();
}
private void addBoardPanelComponents() {
for (int r = 0; r < GAME_ROWS; r++) {
for (int c = 0; c < GAME_COLUMNS; c++) {
add(gameBoard[r][c]);
}
}
}
}
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, int rowHeight, int colWidth, Color color) {
this.row = row;
this.col = col;
this.rowHeight = rowHeight;
this.colWidth = colWidth;
this.color = color;
setBorder(new LineBorder(Color.BLACK));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(colWidth, rowHeight);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
paintSquare(g);
}
private void paintSquare(Graphics g) {
g.setColor(color);
g.fillRoundRect(
0,
0,
getWidth() - 1,
getHeight() - 1,
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;
}
}
}
answered Jan 1 at 3:09
MadProgrammerMadProgrammer
300k17154268
300k17154268
Thank you so much. That answer was super well written and helpful! It solved my problem like a charm.
– Sarah Cohen
Jan 1 at 3:40
👍.............
– MadProgrammer
Jan 1 at 4:23
add a comment |
Thank you so much. That answer was super well written and helpful! It solved my problem like a charm.
– Sarah Cohen
Jan 1 at 3:40
👍.............
– MadProgrammer
Jan 1 at 4:23
Thank you so much. That answer was super well written and helpful! It solved my problem like a charm.
– Sarah Cohen
Jan 1 at 3:40
Thank you so much. That answer was super well written and helpful! It solved my problem like a charm.
– Sarah Cohen
Jan 1 at 3:40
👍.............
– MadProgrammer
Jan 1 at 4:23
👍.............
– MadProgrammer
Jan 1 at 4:23
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53992610%2fwhy-are-the-paintcomponents-being-called-but-not-seen%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
When overwriting paintComponent to draw on a component, you should do it on a JPanel, not on a JComponent
– Snowy_1803
Jan 1 at 2:14
@Snowy_1803 Can you explain further?
– Sarah Cohen
Jan 1 at 2:18
Your Cell class should extend JPanel, it’s not a new component type. Developers shouldn’t overwrite painting on any other component than JPanel and JLabel.
– Snowy_1803
Jan 1 at 2:26
1
@Snowy_1803 Where are you getting that information from? Extending
JComponent
should be fine. Even though it's common to find code snippets online where people are extendingJPanel
for custom painting, it doesn't really make sense because it breaks the Liskov substitution principle. (JPanel
is supposed to be a container for other components.) OverridingpaintComponent
on aJLabel
frankly sounds like a pretty bad idea.– Radiodef
Jan 1 at 2:32
My first thought is that this is a layout issue. Since you're using a grid layout, I'd recommend overriding
getPreferredSize
on theCell
class, and then avoid using any explicit sizing methods likesetPreferredSize
.– Radiodef
Jan 1 at 2:37