从另一个 class 绘制对象到同一个 JFrame

Drawing objects from another class to the same JFrame

我的代码运行了,但是棋盘上没有看到石头

谁能帮忙!!我的目标是让棋盘上的石头 [就像宝石棋一样]

正如 @camickr 在评论中所写,执行此操作的正常方法是让电路板组件绘制其中的内容。

在具有图形用户界面的程序(以及其他程序)中,您通常应该将绘画代码(视图)与您知道要绘画什么分开代码(模型)。这个想法叫做Model-View-Controller.

在这里实施 MVC 意味着您的 Board class 应该知道要绘制什么或如何绘制它,但不能同时知道两者。我建议有一个

  • BoardPainter extends JPanel,视图:知道如何绘制事物本身,对于石头可以到达的每个位置都有一个 StonePainter(它也扩展了 JPanel)。它不会保留有关在何处绘制内容的信息;相反,它会在每次需要时从 MancalaState 中询问此信息。当游戏进行得更远时,您也会在这里生成动作:点击来源,点击目的地,
  • MancalaState 将是模型,它知道每个地方有多少石头,谁应该移动,决定游戏何时结束,等等。如果你在这里实现一个toString(),你可以很容易地测试整个游戏是否正确运行,不管它是如何绘制的。

要将花盆 (StonePainters) 放置在 BoardPainter 中的正确位置,您可以使用现有的 LayoutManager(甚至嵌套 JPanel),编写您自己的LayoutManager,或者直接不使用 StonePainter 并直接从 BoardPainter 中的正确位置绘制它们。从我的角度来看,最简单的选择是第一个:

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);    
        });
    }
}

示例输出: