Reputation: 25
I have a JFrame with a JPanel, that's only displaying when I resize my window(making it smaller still displays everything, so not fitting is not an issue). I tried calling revalidate() and validate() after, and made sure to set setVisible(true) after adding everything, however this seemed to do nothing.
Here is my JFrame code (It's a monopoly game):
public class BoardWindow extends JFrame
{
/** Constructor
*
*/
Board board;
public BoardWindow(Player[] players)
{
super("MONOPOLY GameBoard");
setLayout(new FlowLayout());
board = new Board(players);
add(board);
add(new JButton("Refresh"));
setSize(900, 900);
//setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
}
Here is my JFrame code
class Board extends JPanel {
public Player players[];
Board(Player[] players)
{
this.players = players;
setVisible(true)
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
setPreferredSize(new Dimension(800, 800));
ImageIcon boardPic = new ImageIcon("images/board.png");
boardPic.paintIcon(this, g, 0, 0);
setBackground(Color.WHITE);
int x = 0;
int y = 0;
for(Player i: this.players)
{
g.setColor(i.getColor());
int position = i.getGamePosition();
if(position == 0)
{
x = 25;
y = 700;
}
else if (position > 0 && position < 9)
{
x = 25;
y = ((10-position)*63)+31;
}
else if (position == 9)
{
x = 25;
y = 25;
}
else if (position > 9 && position < 18)
{
y = 25;
x = ((position-9)*63)+98;
}
else if(position == 18)
{
x = 750;
y = 10;
}
else if(position > 18 && position < 27)
{
x = 745;
y = ((position-18)*63)+95;
}
else if (position == 27)
{
x = 750;
y = 660;
}
else if(position > 27)
{
x = ((20-position)*63)+1105;
y= 700;
}
g.fillRect(x, y, 40, 40);
}
}
}
Upvotes: 2
Views: 75
Reputation: 285430
You're doing much too much within paintComponent. Never read in images there, and instead read them in once at the start, such as in your class's constructor. Don't set preferredSize or set background from within this method either. Else you risk hamstringing your method override. This method should be for drawing and drawing only and nothing else.
e.g.,
class Board extends JPanel {
public Player players[];
private BufferedImage boardPic; // use a BufferedImage
Board(Player[] players) {
this.players = players;
setPreferredSize(new Dimension(800, 800));
setBackground(Color.WHITE);
// much better to use resources and not files
// you'll need to handle an exception here.
boardPic = new ImageIO.read(new File("images/board.png"));
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(boardPic, 0, 0, this);
int x = 0;
int y = 0;
for(Player i: this.players) {
g.setColor(i.getColor());
int position = i.getGamePosition();
if(position == 0) {
x = 25;
y = 700;
} else if (position > 0 && position < 9) {
x = 25;
y = ((10-position)*63)+31;
} else if (position == 9) {
x = 25;
y = 25;
} else if (position > 9 && position < 18) {
y = 25;
x = ((position-9)*63)+98;
} else if(position == 18) {
x = 750;
y = 10;
} else if(position > 18 && position < 27) {
x = 745;
y = ((position-18)*63)+95;
} else if (position == 27) {
x = 750;
y = 660;
} else if(position > 27) {
x = ((20-position)*63)+1105;
y= 700;
}
g.fillRect(x, y, 40, 40);
}
}
}
More:
I would read the image in using something similar to this:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class MyMonopoly extends JPanel {
private static final String IMG_PATH = "http://dl.gamesradar.com/photos/gameopoly/monopoly_original.jpg";
private static final int PREF_W = 900;
private static final int PREF_H = PREF_W;
private BufferedImage board = null;
public MyMonopoly() throws IOException {
URL url = new URL(IMG_PATH);
board = ImageIO.read(url);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (board != null) {
g.drawImage(board, 0, 0, getWidth(), getHeight(), this);
}
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
MyMonopoly mainPanel = null;
try {
mainPanel = new MyMonopoly();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
JFrame frame = new JFrame("My Monopoly");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
Only I'd have it as a resource in my JAR file.
I would also create a custom layout for the JPanel and then place my piece sprites into ImageIcons, those into JLabels and then move them into my JPanel by way of its custom layout.
Upvotes: 3