2015-11-03 105 views
0

我在嘗試瞭解MouseActionListener/Adapter類以及圖形,並且我認爲我會通過創建井字遊戲來做到這一點。我不想使用JButtons,因爲我只是改變按鈕上的措辭而不是繪製圖形圖像。 我無法讓我的面板繪製圖像。我爲JPanels創建了兩個內部類,一個用於MouseAdapter類。我的paint方法位於Board類中,但是當我單擊JPanel時,它不繪製圖形(到目前爲止,我只是設置繪製一個X)。 我知道它認識到通過使用調試器點擊面板,但我不明白爲什麼調用時不調用paint方法。無法在JPanel上繪圖

這裏是我的代碼:

package xno; 
import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.awt.Graphics.*; 
/** 
* 
* @author jordynsmith 
*/ 
public class XnOFrame extends JFrame { 
    private int win=0; 
    private int loss=0; 
    private int turn=1; //keeps track of the turn so that color can change with each turn 
    public XnOFrame(){ 
     super("X n' O"); 

    //instantiate 
    board = new Board[3][3]; 
    for(int i=0 ;i< 3; i++){ 
     for(int j=0; j<3; j++){ 
      board[i][j] = new Board(); 
      board[i][j].setStatus("Empty"); 
      board[i][j].setBackground(Color.black); 
      //creates tic tac toe border 
      //1st column 
      if(j==0){//top 
        board[i][j].setBorder(BorderFactory.createMatteBorder(0, 0, 2, 2, Color.blue)); 
       if(i==1){//center 
        board[i][j].setBorder(BorderFactory.createMatteBorder(2, 0, 2, 0, Color.blue));  
       } 
       if(i==2){//bottom 
        board[i][j].setBorder(BorderFactory.createMatteBorder(2, 0, 0, 0, Color.blue)); 
       } 
      } 
      //2nd column 
      else if(j==1){//top 
      board[i][j].setBorder(BorderFactory.createMatteBorder(0, 2, 2, 2, Color.blue)); 
       if(i==1){//center 
       board[i][j].setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.blue));  
       } 
       if(i==2){//bottom 
       board[i][j].setBorder(BorderFactory.createMatteBorder(2, 2, 0, 2, Color.blue)); 
       } 
      } 
      //3rd column 
      else if(j==2){//top 
      board[i][j].setBorder(BorderFactory.createMatteBorder(0, 2, 2, 0, Color.blue)); 
       if(i==1){//center 
       board[i][j].setBorder(BorderFactory.createMatteBorder(2, 2, 2, 0, Color.blue));  
       } 
       if(i==2){//bottom 
       board[i][j].setBorder(BorderFactory.createMatteBorder(2, 2, 0, 0, Color.blue)); 
       } 
      } 
     } 
    } 
    goBtn = new JButton("Start Game"); 
    quitBtn = new JButton("End Game"); 
    newBtn = new JButton("New Game"); 
    score = new JLabel("Score"); 
    wins = new JLabel("Wins"); 
    losses = new JLabel("Losses"); 
    wPoints = new JLabel(win + ""); 
    lPoints = new JLabel(loss + ""); 
    line = new JLabel("||"); 
    menuPanel = new JPanel(); 
    scorePanel = new JPanel(); 
    gridPanel = new JPanel(); 
    scoreLabelPanel = new JPanel(); 
    pointsPanel = new JPanel(); 

    //set layout 
    this.setLayout(new BorderLayout()); 
    menuPanel.setLayout(new FlowLayout()); 
    scorePanel.setLayout(new BorderLayout()); 
    gridPanel.setLayout(new GridLayout(3,3)); 
    scoreLabelPanel.setLayout(new FlowLayout()); 
    pointsPanel.setLayout(new FlowLayout()); 

    //add components 
    this.add(gridPanel, BorderLayout.CENTER); 
    this.add(menuPanel, BorderLayout.SOUTH); 
    this.add(scorePanel, BorderLayout.WEST); 
    menuPanel.add(goBtn); 
    menuPanel.add(quitBtn); 
    menuPanel.add(newBtn); 
    scorePanel.add(scoreLabelPanel, BorderLayout.NORTH); 
    scorePanel.add(pointsPanel, BorderLayout.CENTER); 
    scoreLabelPanel.add(score); 
    pointsPanel.add(wins); 
    pointsPanel.add(wPoints); 
    pointsPanel.add(line); 
    pointsPanel.add(losses); 
    pointsPanel.add(lPoints); 
    for(int i=0; i<board.length; i++){ 
     for(int j=0; j<board[i].length; j++){ 
      gridPanel.add(board[i][j]); 
     } 
    } 

    //adding action 
    for(int i=0; i<board.length; i++){ 
     for(int j=0; j<board[i].length; j++){ 
      board[i][j].addMouseListener(new BoardAction()); 
     } 
    } 
} 

這是我的問題確實是。我不確定如何組織和何時調用某些方法,以及應該調用哪些方法才能使其工作。

private class BoardAction extends MouseAdapter{ 
    private Board panel = new Board(); 

    @Override 
    public void mouseClicked(MouseEvent me){ 
     //determines which panel was clicked 
     panel = (Board) me.getSource(); 
     panel.repaint();//calls paint method 
    } 
} 



private class Board extends JPanel{ 
    public String status; 

    public Board(){ 
     status="Empty"; 
    } 

    public String getStatus(){ 
     return status; 
    } 
    public void setStatus(String s){ 
     status = s; 
    } 

    public void piant(Graphics g){ 
    super.paint(g); 
    draw(g); 
    } 

    private void draw(Graphics g){ 
     if(status.equals("Empty")){//paints x if empty 
      if(turn%2 != 0){//if turn is odd the color is green 
      g.setColor(Color.green); 
      } 
      else//if even the color is yellow 
       g.setColor(Color.yellow); 

      g.drawLine(0, 0, getWidth(), getHeight()); 
      g.drawLine(getHeight(), 0, getWidth(), 0); 
      setStatus("X"); 
     } 
    } 
} 

//components 
Board [][] board; 
JPanel menuPanel, scorePanel, gridPanel, scoreLabelPanel, pointsPanel; 
JButton goBtn, quitBtn, newBtn; 
JLabel score, wins, losses, wPoints, lPoints, line; 

}

因此改變我的paint方法來一個的paintComponent後的StackOverflowError當super.paint()方法被調用時拋出我的Jbutton將採取永遠出現。爲了看看會發生什麼,我評論說,排隊並運行程序。在這樣做,我得到這個: 黑色面板是我點擊的人。面板應該是黑色的,點擊時綠色的線條應該顯示出來。另外,只有一條綠線出現(應該有兩條,因爲它是一個x)。我正在盡我所能按照教程,但任何額外的幫助,非常感謝!

+0

1.不要在'BorderActon'中創建'Board'的新實例,不需要它; 2.用'paint'替代'paintComponent'; 3。據推測,你BoardAction'實際上應該以一種有意義的方式改變'Board'的狀態 – MadProgrammer

回答

3

不要改變裏面paint

private void draw(Graphics g){ 
    if(status.equals("Empty")){//paints x if empty 
     if(turn%2 != 0){//if turn is odd the color is green 
     g.setColor(Color.green); 
     } 
     else//if even the color is yellow 
      g.setColor(Color.yellow); 

     g.drawLine(0, 0, getWidth(), getHeight()); 
     g.drawLine(getHeight(), 0, getWidth(), 0); 
     // This is bad idea... 
     setStatus("X"); 
    } 
} 

一種塗料方法的組件的狀態應該做的而已油漆組件的當前狀態,它不應該修改它。

優選使用paintComponent超過paint。見Painting in AWT and SwingPerforming Custom Painting更多細節

@Override 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    draw(g); 
} 

private void draw(Graphics g) { 
    if (status.equals("Empty")) {//paints x if empty 
     if (turn % 2 != 0) {//if turn is odd the color is green 
      g.setColor(Color.green); 
     } else//if even the color is yellow 
     { 
      g.setColor(Color.yellow); 
     } 

     g.drawLine(0, 0, getWidth(), getHeight()); 
     g.drawLine(getHeight(), 0, getWidth(), 0); 
    } 
} 

BoardAction實際上應該改變一些有意義的方式Board的狀態...

private class BoardAction extends MouseAdapter { 

    @Override 
    public void mouseClicked(MouseEvent me) { 
     //determines which panel was clicked 
     Board panel = (Board) me.getSource(); 
     panel.setStatus("X"); 
     panel.repaint();//calls paint method 
    } 
} 

也可考慮,你Board類也應該覆蓋getPreferredSize和回報其他尺寸的其他尺寸0x0

3
public void piant(Graphics g){ 

piant!= paint。

  1. 您應該重寫paintComponent
  2. 始終前言我們覆蓋與@Override註釋所以編譯器會告訴你,當你做錯了。
  3. 閱讀Swing繪畫教程。
+0

@JonnyHenly因爲它實際上並沒有回答這個問題,但是提供了一些好的建議,這將有助於OP進一步減少問題的數量有代碼可以幫助隔離實際問題。如果我們說過一次,我們已經說過一千遍了:P – MadProgrammer