[英]Drawing objects from another class to the same JFrame
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;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.