Java Swing JPanel paintComponents从未调用过

时间:2017-04-05 19:51:23

标签: java swing jpanel

我遇到了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;
        }
    }
}

提前谢谢。

1 个答案:

答案 0 :(得分:2)

this.panel.add(this.gamePanel, constraints);

您将组件添加到面板,但面板没有首选大小。由于其大小为(0,0),因此无需绘制任何内容,因此永远不会调用该方法。

所有Swing组件都负责确定自己的首选大小。覆盖自定义组件的getPreferredSize()方法。然后布局管理器可以设置组件的正确大小/位置。

并且paintComponent(...)是覆盖的正确方法,并且不要忘记super.paintComponent(...)作为确保背景被清除的第一个语句。