2014-02-25 107 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