Ok, so I am making a monopoly game. I so far have a JFrame
, with a JPanel
acting as a board. I have loaded all necessary images. I create a P
There are a couple of ways you can achieve this, personally, the simplest would be to use custom painting directly and not bother with using Swing based components for the players.
The basic problem you have is JPanel
uses a FlowLayout
by default, which means that you will always be fighting layout manager. In this case you might consider using a custom layout manager, for example...
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LayoutManager2;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Monopoly {
public static void main(String[] args) {
new Monopoly();
}
public Monopoly() {
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 MonopolyBoard());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MonopolyBoard extends JPanel {
private List<JLabel> players;
public MonopolyBoard() {
setLayout(new MonopolyBoardLayout());
players = new ArrayList<>(2);
try {
players.add(makePlayer("/Dog.png"));
players.add(makePlayer("/Car.png"));
for (JLabel player : players) {
add(player, new Integer(0));
}
} catch (IOException exp) {
exp.printStackTrace();
}
Timer timer = new Timer(1000, new ActionListener() {
private int count = 0;
private Random rnd = new Random();
@Override
public void actionPerformed(ActionEvent e) {
int playerIndex = count % players.size();
JLabel player = players.get(playerIndex);
MonopolyBoardLayout layout = (MonopolyBoardLayout) getLayout();
int position = layout.getPosition(player);
position += rnd.nextInt(5) + 1;
if (position > 35) {
position -= 35;
}
layout.setPosition(player, position);
revalidate();
repaint();
count++;
}
});
timer.start();
}
protected JLabel makePlayer(String path) throws IOException {
JLabel label = new JLabel(new ImageIcon(ImageIO.read(getClass().getResource(path))), JLabel.CENTER);
return label;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int width = getWidth();
int height = getHeight();
for (int index = 0; index < 36; index++) {
Rectangle bounds = MonopolyBoardLayoutHelper.getCellBounds(index, width, height);
g2d.draw(bounds);
}
g2d.dispose();
}
}
public static class MonopolyBoardLayoutHelper {
private static Map<Integer, Point> mapBoardCells;
static {
mapBoardCells = new HashMap<>(25);
mapBoardCells.put(10, new Point(0, 8));
mapBoardCells.put(11, new Point(0, 7));
mapBoardCells.put(12, new Point(0, 6));
mapBoardCells.put(13, new Point(0, 5));
mapBoardCells.put(14, new Point(0, 4));
mapBoardCells.put(15, new Point(0, 3));
mapBoardCells.put(16, new Point(0, 2));
mapBoardCells.put(17, new Point(0, 1));
mapBoardCells.put(18, new Point(0, 0));
mapBoardCells.put(0, new Point(9, 9));
mapBoardCells.put(1, new Point(8, 9));
mapBoardCells.put(2, new Point(7, 9));
mapBoardCells.put(3, new Point(6, 9));
mapBoardCells.put(4, new Point(5, 9));
mapBoardCells.put(5, new Point(4, 9));
mapBoardCells.put(6, new Point(3, 9));
mapBoardCells.put(7, new Point(2, 9));
mapBoardCells.put(8, new Point(1, 9));
mapBoardCells.put(9, new Point(0, 9));
mapBoardCells.put(19, new Point(1, 0));
mapBoardCells.put(20, new Point(2, 0));
mapBoardCells.put(21, new Point(3, 0));
mapBoardCells.put(22, new Point(4, 0));
mapBoardCells.put(23, new Point(5, 0));
mapBoardCells.put(24, new Point(6, 0));
mapBoardCells.put(25, new Point(7, 0));
mapBoardCells.put(26, new Point(8, 0));
mapBoardCells.put(27, new Point(9, 0));
mapBoardCells.put(28, new Point(9, 1));
mapBoardCells.put(29, new Point(9, 2));
mapBoardCells.put(30, new Point(9, 3));
mapBoardCells.put(31, new Point(9, 4));
mapBoardCells.put(32, new Point(9, 5));
mapBoardCells.put(33, new Point(9, 6));
mapBoardCells.put(34, new Point(9, 7));
mapBoardCells.put(35, new Point(9, 8));
}
public static Rectangle getCellBounds(int index, int width, int height) {
Rectangle bounds = new Rectangle(0, 0, 0, 0);
int size = Math.min(width, height);
int cellSize = size / 10;
int xOffset = (width - size) / 2;
int yOffset = (height - size) / 2;
Point point = mapBoardCells.get(index);
if (point != null) {
int x = xOffset + (point.x * cellSize);
int y = yOffset + (point.y * cellSize);
bounds = new Rectangle(x, y, cellSize, cellSize);
}
return bounds;
}
}
public static class MonopolyBoardLayout implements LayoutManager2 {
public static final int DEFAULT_CELL_SIZE = 64;
private Map<Component, Integer> cellConstraints;
public MonopolyBoardLayout() {
cellConstraints = new HashMap<>(5);
}
public Integer getPosition(Component comp) {
return cellConstraints.get(comp);
}
public void setPosition(Component comp, int position) {
cellConstraints.put(comp, position);
}
@Override
public void addLayoutComponent(Component comp, Object constraints) {
if (constraints instanceof Integer) {
int cell = (int) constraints;
if (cell >= 0 && cell <= 35) {
cellConstraints.put(comp, cell);
} else {
throw new IllegalArgumentException(constraints + " is not within the bounds of a valid cell reference (0-35)");
}
} else {
throw new IllegalArgumentException(constraints + " is not a valid cell reference (integer within 0-35)");
}
}
@Override
public Dimension maximumLayoutSize(Container target) {
return new Dimension(DEFAULT_CELL_SIZE * 10, DEFAULT_CELL_SIZE * 10);
}
@Override
public float getLayoutAlignmentX(Container target) {
return 0.5f;
}
@Override
public float getLayoutAlignmentY(Container target) {
return 0.5f;
}
@Override
public void invalidateLayout(Container target) {
}
@Override
public void addLayoutComponent(String name, Component comp) {
}
@Override
public void removeLayoutComponent(Component comp) {
cellConstraints.remove(comp);
}
@Override
public Dimension preferredLayoutSize(Container parent) {
return new Dimension(DEFAULT_CELL_SIZE * 10, DEFAULT_CELL_SIZE * 10);
}
@Override
public Dimension minimumLayoutSize(Container parent) {
return new Dimension(DEFAULT_CELL_SIZE * 10, DEFAULT_CELL_SIZE * 10);
}
@Override
public void layoutContainer(Container parent) {
int width = parent.getWidth();
int height = parent.getHeight();
Map<Integer, List<Component>> components = new HashMap<>(25);
for (Component child : parent.getComponents()) {
Integer cell = cellConstraints.get(child);
if (cell != null) {
List<Component> children = components.get(cell);
if (children == null) {
children = new ArrayList<>(4);
components.put(cell, children);
}
children.add(child);
} else {
child.setBounds(0, 0, 0, 0);
}
}
for (Map.Entry<Integer, List<Component>> entry : components.entrySet()) {
int index = entry.getKey();
Rectangle bounds = MonopolyBoardLayoutHelper.getCellBounds(index, width, height);
List<Component> comp = entry.getValue();
int xDelta = 0;
int yDelta = 0;
int availableWidth = bounds.width;
int availableHeight = bounds.height;
switch (comp.size()) {
case 2:
availableWidth /= 2;
xDelta = availableWidth;
break;
case 3:
case 4:
availableWidth /= 2;
xDelta = availableWidth;
availableHeight /= 2;
yDelta = availableHeight;
break;
}
int x = bounds.x;
int y = bounds.y;
for (int count = 0; count < comp.size() && count < 4; count++) {
Component child = comp.get(count);
child.setSize(availableWidth, availableHeight);
child.setLocation(x, y);
x += xDelta;
if (x >= bounds.x + bounds.width) {
x = bounds.x;
y += yDelta;
}
}
}
}
}
}
As you can see, this becomes real complicated real quick. This example currently only allows 4 players per cell, so if you want more, then you're going to have to create your own algorithim