2017-04-05 70 views
-1

我遇到了一個JPanel問題,我不知道發生了什麼。所以我有一個帶有init函數的JFrame,它創建了一個名爲GamePanel的自定義JPanel,奇怪的是它始終不會在paintComponents函數中執行,即使我在對象上使用了重繪。Java Swing JPanel paintComponents never called

這裏是我的代碼時,我初始化的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; 
     } 
    } 
} 

預先感謝您。

+2

使用paintComponent而不是paintComponents – ControlAltDel

+0

我嘗試過這兩個函數,不幸的是它不起作用 –

+0

爲什麼它是你的[7問題](http://stackoverflow.com/users/6743005/florian-merle),只有**一個**有一個可接受的答案?所以沒有爲你工作? –

回答

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

您將組件添加到面板,但面板沒有首選大小。由於它的大小是(0,0),因此沒有任何內容可以繪製,因此該方法從不會被調用。

所有Swing組件負責確定自己喜歡的大小。覆蓋您的自定義組件的getPreferredSize()方法。然後佈局管理器可以設置組件的正確大小/位置。

paintComponent(...)是重寫的正確方法,不要忘記super.paintComponent(...)作爲確保背景被清除的第一條語句。

+0

好吧,添加getPreferredSize()方法並沒有解決問題,但如果我更改了維度,它會使窗口變大。 –

+0

編輯:我在原來的文章中添加了JFrame的全部代碼 –

+0

@FlorianMerle你錯過了我的最後一點,現在已經做了兩次。另外,誰知道你的Socket是否會導致問題。也許代碼阻塞等待輸入。做更多的調試來確定邏輯流程是否正確。 – camickr