Reputation: 43
my code runs, but the stone is not seen on top of the board
can anyone help pls!! my goal is to get stones on the board [ like the game mancala]
Upvotes: 0
Views: 81
Reputation: 17945
As @camickr writes in comments, the normal way to do this is to have the board-component paint the things that are in it.
In programs that have a graphical user interface (and also in others), you should generally separate your painting code (the view) from your knowing-what-to-paint code (the model). This idea is called Model-View-Controller.
Implementing MVC here would mean that your Board
class should either know what to paint, or how to paint it, but not both. I propose having a
BoardPainter extends JPanel
, the view: knows how to paint things itself, has a StonePainter
(which also extends JPanel
) for each of the locations where stones can go. It does not keep information on what to paint where; instead, it asks this information from a MancalaState
every time it needs it. When the game is further along, you will also generate moves here: click on source, click on destination,MancalaState
would be the model, which knows how many stones are in each place, who is supposed to move, decides when the game is over, and so on. If you implement a toString()
here, you can easily test that the whole game works correctly regardless of how it is painted.To place the pots (StonePainter
s) in their correct places in the BoardPainter
, you can either work with an existing LayoutManager
(even nesting JPanels), write your own LayoutManager
, or directly not use a StonePainter
and draw them directly from your BoardPainter
at their correct locations. The easiest alternative, from my point of view, would be the the 1st:
import javax.swing.*;
import java.awt.*;
import java.util.*;
public class Demo {
/** paints a full board */
public static class BoardPainter extends JPanel {
private ArrayList<PotPainter> pots = new ArrayList<>();
private java.util.List<Integer> mancalaBoard; // <-- this would be an actual class
public BoardPainter(java.util.List<Integer> mancalaBoard) {
this.mancalaBoard = mancalaBoard;
setLayout(new BorderLayout());
// a 2x6 grid in the center
JPanel center = new JPanel();
center.setLayout(new GridLayout(2, 6));
for (int i=0; i<12; i++) {
PotPainter p = new PotPainter();
pots.add(p);
center.add(p);
}
add(center, BorderLayout.CENTER);
// one side
PotPainter east = new PotPainter();
pots.add(east);
add(east, BorderLayout.EAST);
east.setPreferredSize(new Dimension(100, 0));
// the other side
PotPainter west = new PotPainter();
pots.add(west);
add(west, BorderLayout.WEST);
west.setPreferredSize(new Dimension(100, 0));
}
public void paint(Graphics g) {
for (int i=0; i<mancalaBoard.size(); i++) {
pots.get(i).setStones(mancalaBoard.get(i));
}
super.paint(g);
}
}
/** paints a pot */
public static class PotPainter extends JPanel {
private static final int MARGIN = 2;
private static final int STONE_SIZE = 10;
private int stones = 0;
public void setStones(int stones) {
this.stones = stones;
}
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.BLACK);
g.drawOval(MARGIN, MARGIN, getWidth()-MARGIN*2, getHeight()-MARGIN*2);
Random r = new Random();
int d = Math.min(getWidth(), getHeight()) / 2;
Point center = new Point(getWidth()/2, getHeight()/2);
for (int i=0; i<stones; i++) {
g.drawOval(center.x + r.nextInt(d) - d/2, center.y + r.nextInt(d) - d/2,
STONE_SIZE, STONE_SIZE);
}
}
}
public static void main(String ...args) {
SwingUtilities.invokeLater(() -> {
JFrame jf = new JFrame("demo");
jf.add(new BoardPainter(new ArrayList<>(
Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 4, 2))));
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setSize(800, 300);
jf.setVisible(true);
});
}
}
Sample output:
Upvotes: 1