简体   繁体   English

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

[英]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.正如@camickr在评论中所写,通常的方法是让板组件绘制其中的内容。

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 ).在具有图形用户界面的程序中(以及在其他程序中),您通常应该将您的绘画代码(视图)与您知道要绘画的代码( model )分开。 This idea is called Model-View-Controller .这个想法被称为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.在此处实施 MVC 意味着您的Board class 应该知道要绘制什么或如何绘制它,但不能同时知道两者。 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. BoardPainter extends JPanel ,视图:知道如何自己绘制事物,对于石头可以 go 的每个位置都有一个StonePainter (它也扩展了JPanel )。 It does not keep information on what to paint where;保存关于在哪里画什么的信息; instead, it asks this information from a MancalaState every time it needs it.相反,它会在每次需要时从MancalaState询问此信息。 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. MancalaState将是 model,它知道每个地方有多少石头,应该移动谁,决定游戏何时结束,等等。 If you implement a toString() here, you can easily test that the whole game works correctly regardless of how it is painted.如果你在这里实现一个toString() ,你可以很容易地测试整个游戏是否正常工作,不管它是如何绘制的。

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.要将花盆( StonePainter s)放置在BoardPainter中的正确位置,您可以使用现有的LayoutManager (甚至嵌套 JPanel),编写自己的LayoutManager ,或者直接不使用StonePainter并直接从BoardPainter在它们的位置绘制它们正确的位置。 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:样品 output:

样本输出

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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