我遇到了JPanel的问题而且我不知道发生了什么。所以我有一个带有init函数的JFrame,它创建一个名为GamePanel的自定义JPanel,奇怪的是它永远不会出现在paintComponents函数中,即使我在对象上使用重绘。
这是我初始化JPanel(在JFrame中)时的代码:
this.gamePanel = new GamePanel(this.grid, this);
this.panel.add(this.gamePanel, constraints);
JPanel本身:
public class GamePanel extends JPanel {
private final int SQUARE_SIZE = 50;
private Grid grid;
private final GameView gameView;
public GamePanel(Grid grid, GameView gameView) {
this.gameView = gameView;
this.setPreferredSize(new Dimension(200, 200));
}
public void setGrid(Grid grid) {
this.grid = grid;
this.setPreferredSize(new Dimension(grid.getSizeX() * SQUARE_SIZE, grid.getSizeY() * SQUARE_SIZE));
}
@Override
public void paintComponents(Graphics g) {
System.out.println("test");
if (this.grid != null) {
Graphics2D g2 = (Graphics2D) g;
double thickness = 3;
g2.setStroke(new BasicStroke((float) thickness));
g2.setColor(Color.BLACK);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int x = SQUARE_SIZE * i;
int y = SQUARE_SIZE * j;
g2.drawRect(x, y, SQUARE_SIZE, SQUARE_SIZE);
if(this.grid.getSquareState(x, y) != 0) {
char[] tmp = ("" + this.grid.getSquareState(x, y)).toCharArray();
g2.drawChars(tmp, 0, 1, x, y);
}
}
}
}
}
}
编辑:(整个JFrame)
public class GameView extends JFrame {
private CustomSocket socket;
private JPanel panel;
private GamePanel gamePanel;
private JLabel listPlayers;
private JLabel playerPlaying;
private Grid grid;
public GameView(CustomSocket socket) {
this.socket = socket;
this.setTitle("TicTacToe - Client");
this.setSize(600, 480);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.init();
this.pack();
this.setVisible(true);
this.play();
}
private void init() {
this.panel = new JPanel();
this.panel.setLayout(new GridBagLayout());
GridBagConstraints constraints =new GridBagConstraints();
constraints.fill = GridBagConstraints.CENTER;
constraints.gridx = 0;
constraints.gridy = 0;
constraints.gridwidth = 1;
// Grid
this.gamePanel = new GamePanel(this.grid, this);
this.panel.add(this.gamePanel, constraints);
// Labels
constraints.gridy += 1;
this.listPlayers = new JLabel();
this.panel.add(this.listPlayers, constraints);
constraints.gridy += 1;
this.playerPlaying = new JLabel();
this.panel.add(this.playerPlaying, constraints);
this.setContentPane(this.panel);
}
private void play() {
String[] tmp = this.socket.getData().split(";");
this.grid = new Grid(Integer.parseInt(tmp[0]), Integer.parseInt(tmp[1]));
String players = "";
for(int i = 2; i < tmp.length; i++) {
players += tmp[i] + " ";
}
this.listPlayers.setText(players);
boolean notFinished = true;
while(notFinished) {
String[] gridData = this.socket.getData().split(";");
for(int i = 1; i < gridData.length; i++) {
String[] gridRow = gridData[i].replace("(", "").replace(")", "").split(",");
for(int j = 0; j < gridRow.length; j++) {
this.grid.setSquareState(i - 1, j, Integer.parseInt(gridRow[j]));
}
}
this.gamePanel.repaint();
String playerPlaying = this.socket.getData().split(";")[0];
if(playerPlaying != this.socket.getUsername()) {
}
notFinished = true;
}
}
}
提前谢谢。
答案 0 :(得分:2)
this.panel.add(this.gamePanel, constraints);
您将组件添加到面板,但面板没有首选大小。由于其大小为(0,0),因此无需绘制任何内容,因此永远不会调用该方法。
所有Swing组件都负责确定自己的首选大小。覆盖自定义组件的getPreferredSize()
方法。然后布局管理器可以设置组件的正确大小/位置。
并且paintComponent(...)
是覆盖的正确方法,并且不要忘记super.paintComponent(...)
作为确保背景被清除的第一个语句。