2014-02-25 136 views
0

我正在使用TicTacToe遊戲的圖形進行測試,但在點擊按鈕後更新Canvas時出現問題。當我致電showUpdatedBoard()時,它會創建一個新的畫布,但它不會輸入paintComponent方法,因此不更新畫布。單擊按鈕後更新畫布?

任何幫助,將不勝感激。 謝謝!

(忽略計數和我,他們只是用於測試)

井字遊戲類:

public class TicTacToe extends JPanel{ 

private JFrame mainFrame; 
private JPanel mainPanel; 
private JPanel canvasPanel; 
private JPanel optionsPanel; 
private JTextField coord; 
private JButton enterCoord; 

private int i = 0; 

public static void main(String[] args){ 

    TicTacToe tictac = new TicTacToe(); 
    tictac.mainFrame = new JFrame(); 
    tictac.mainFrame.setSize(1600, 900); 
    tictac.mainFrame.setLocationRelativeTo(null); 
    tictac.mainFrame.setDefaultCloseOperation(tictac.mainFrame.EXIT_ON_CLOSE); 
    tictac.mainFrame.setVisible(true); 
    tictac.makeGUI(); 

} 

public void showUpdatedBoard(){ 
    canvasPanel = new Canvas(); 
    canvasPanel.repaint(); 
} 

private void makeGUI(){ 

    canvasPanel = new Canvas(); 

    mainPanel = new JPanel(new FlowLayout()); 
    mainPanel.add(canvasPanel); 

    mainFrame.add(mainPanel); 

    optionsPanel = new JPanel(); 
    coord = new JTextField(4); 

    enterCoord = new JButton("Enter Co-ordinate"); 
    enterCoord.addActionListener(new enterCoordPress()); 

    optionsPanel.add(coord); 
    optionsPanel.add(enterCoord); 

    mainPanel.add(optionsPanel); 
} 

public class enterCoordPress implements ActionListener{ 

    public void actionPerformed(ActionEvent ev) { 
     TicTacToe tictac = new TicTacToe(); 
     tictac.showUpdatedBoard(); 
     i++; 
     coord.setText(String.valueOf(i)); 
    } 
} 
} 

Canvas類:

public class Canvas extends JPanel { 

private String[][] Board = new String[3][3]; 
private int count = 0; 

public Canvas(){ 
    this.setPreferredSize(new Dimension(1300, 900)); 
    this.setBackground(Color.WHITE); 

} 

@Override 
public void paintComponent(Graphics g){ 
    super.paintComponent(g); 
    System.out.println(count); 
    if(count <= 5){ 
     g.fillRect(0, 0, 1000, 900); 
    } else { 
     g.fillRect(0, 0, 120, 546); 
    } 
    count++; 
} 

} 
+0

請參閱[*混合重量級和輕量級組件*](http://www.oracle.com/technetwork/articles/java/mixing-components- 433992.html)。 – trashgod

回答

0

嘗試使用

canvasPanel.update(canvasPanel.getGraphics()); 

而不是

canvasPanel.repaint(); 
+0

除非打印或生成組件的快照,否則不應該直接調用update(或任何)paint方法,特別是不要使用可以返回null的'getGraphics',特別是當該方法可以返回null時組件尚未實現 – MadProgrammer

+0

我得到一個NullPointerException? – Latrinum

+0

@Latrinum getGraphics在組件未連接到本地對等體時返回null,因此您不應該依賴它。 – MadProgrammer

0

基本上,當您使用new要創建的組件的全新例如,一個具有您之前曾創建過沒有關係什麼,一個不顯示在屏幕上,做...

canvasPanel = new Canvas(); 
canvasPanel.repaint(); 

是什麼也不做,因爲Swing是足夠聰明,知道你的組件還沒有實現(連接到本地同行,把在屏幕上),所以它永遠不會安排它的任何繪畫,它會浪費是時候這樣做了。

相反,你需要以某種方式更新canvasPanel狀態,以反映要出現的變化,只需撥打repaint

這同樣適用於你的actionPerformed方法,不要創造TicTacToe一個新實例因爲它不是組件實例在屏幕上的實例...

+0

我可以在paintComponent()之外編輯Canvas的位置? – Latrinum

+0

你已經在'TicTacToe'中引用'canvasPanel'。你是'ActionListener','enterCoordPress',應該能夠直接引用它。所有你需要的是爲ActionListener改變'canvasPanel'的狀態,或者通過一個通用的模型(這將是首選的),或者直接通過某種設置器 – MadProgrammer

+0

我通過調用repaint() Canvas類中的新方法,然後在TicTacToe中調用repaint()。謝謝您的幫助! – Latrinum