Reputation: 107
I've created a JFrame
which contains a JPanel
in a MigLayout
.
Within that layout, I have 5 columns and 4 rows, each has a 'Big Cell' in them.
The 'Big Cell' extends JPanel
and has a border color, and within the 'Big cell' is a 'small cell' which also extends JPanel
and has a border color. 16x16 grid within the big cell of the small cells.
I am trying to draw an image, but it only draws the image after everything else is drawn (borders, backgrounds, etc.)
But I want to draw the image first, and draw the borders after.
I can't use setIcon for the individual cells because it doesn't draw the image (not sure why) and it makes my grid 10x bigger and the program overflows so big that it wouldn't even fit on a 4k resolution.
Here's a picture of what it looks like
I want each black 'box' or 'Big Cell' to have it's own background image which is painted or rendered behind the little cells with the orange border.
And here's what it looks like with the image painted
You might not be able to tell, but that's the image rendered in each 'big cell' as it should except it's in front of everything. It looks like it just 1 image but don't be fooled because it's a seamless image.
Here's the 'BigCell' class which I'm assuming is the root of the issue.
package com.michaelgates.dev.OldLeaf.gui.components;
import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.*;
public class BigCell extends JPanel
{
int column;
int row;
Cell[][] children;
JPanel parent;
Image image;
public BigCell(int column, int row, JPanel parent)
{
this.column = column;
this.row = row;
this.parent = parent;
setLayout(new GridLayout(16, 16, 0, 0));
setBorder(new LineBorder(Color.DARK_GRAY, 2));
children = new Cell[16][16];
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
Cell cell = new Cell(i, j, this);
add(cell);
children[i][j] = cell;
}
}
image = Toolkit.getDefaultToolkit().getImage(getClass().getClassLoader().getResource("img/acre/acre_0.png"));
}
@Override
public void paint(Graphics g)
{
if (image != null)
{
g.drawImage(image, 0, 0, (int) getSize().getWidth() - 0, (int) getSize().getHeight() - 0, this);
}
super.paint(g);
}
}
And the 'Cell' class which is the tiny box with an orange border
package com.michaelgates.dev.OldLeaf.gui.components;
import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.*;
public class Cell extends JPanel
{
int column;
int row;
BigCell parent;
public Cell(int column, int row, BigCell parent)
{
this.column = column;
this.row = row;
this.parent = parent;
setBorder(new LineBorder(Color.orange, 1));
//setBackground(Color.LIGHT_GRAY);
}
}
Upvotes: 1
Views: 956
Reputation: 347204
Change...
@Override
public void paint(Graphics g)
{
if (image != null)
{
g.drawImage(image, 0, 0, (int) getSize().getWidth() - 0, (int) getSize().getHeight() - 0, this);
}
super.paint(g);
}
to
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
g.drawImage(image, 0, 0, (int) getSize().getWidth() - 0, (int) getSize().getHeight() - 0, this);
}
}
paintComponent
is called before paintBorder
and paintChildren
, so it's the perfect place to paint a background image
Then add setOpaque(false);
to your Cell
's constructor
Take a look at Performing Custom Painting and Painting in AWT and Swing for more details about how painting works in Swing
Upvotes: 1