0

my code runs, but the stone is not seen on top of the board this is what my output look like when I run my code

can anyone help pls!! my goal is to get stones on the board [ like the game mancala]

  • 2
    You're using a flow layout, and you're adding your stone to the flow layout. It doesn't have a preferred/min/max size so the content pane is giving it 0 space. – matt Apr 14 '21 at 20:00
  • @matt so how do i give it space? – codingxsigh Apr 14 '21 at 20:03
  • @matt a final int space because I want the stones to always be the same size – codingxsigh Apr 14 '21 at 20:03
  • For starters you cannot use a FlowLayout. It will not stack components. You could use a JLayeredPane if you want to stack components. – matt Apr 14 '21 at 20:05
  • The [JLayeredPane](https://docs.oracle.com/javase/tutorial/uiswing/components/layeredpane.html) has a pretty good tutorial. – matt Apr 14 '21 at 20:12
  • @matt cool ill check it out, thx – codingxsigh Apr 14 '21 at 21:21
  • Typically you would draw all the shapes on a single panel. This will allow you to easily stack shapes. The last shape painted will be painted on top of other shapes. Create an ArrayList of shapes to draw and then the paintComponent() method iterates through the ArrayList to paint each shape. – camickr Apr 14 '21 at 23:06
  • @camickr the thing is Board is its own object and Stones are own object... how do I make them related and draw on the same component? – codingxsigh Apr 14 '21 at 23:10
  • 1
    Board is a panel. You override the paintComponent() method of the Board to paint the stones as described above. See: https://stackoverflow.com/questions/54028090/get-width-and-height-of-jpanel-outside-of-the-class/54028681#54028681 for an example. – camickr Apr 14 '21 at 23:14
  • ok will try this and check that link out.. thank you! @camickr – codingxsigh Apr 14 '21 at 23:17
  • @camickr i updated my code but i am getting the same output... just the board – codingxsigh Apr 15 '21 at 03:57

1 Answers1

1

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 (StonePainters) 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:

Sample output

tucuxi
  • 17,561
  • 2
  • 43
  • 74