简体   繁体   中英

Drawing objects from another class to the same JFrame

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]

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:

样本输出

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM