2013-02-16 52 views
1

首先,我已經看過這裏的所有其他類似帖子,但沒有人能夠提供幫助。我正在編寫一個掃雷遊戲,我正在試圖將一個Jlabel放在我的JFrame的borderLayout的頂部,並讓它顯示一個計數器,表明有多少個地雷被標記。只要點擊我網格上的任何其他Jlabel,就需要重新繪製它。首先,用我的代碼,因爲沒有文本顯示在我的頭JLabel上。我可以讓文本顯示出來的唯一方法是將其放入我的JLabel構造函數中。這導致我認爲我的paintComponent永遠不會被調用。我還在我的遊戲的實際網格中爲我的headerJabel的repaint方法調用了mouseHandler。這樣,如果用戶點擊遊戲中的任何組件,標題JLabel將重新繪製自己以反映用戶的移動。爲什麼我的JLabel永遠不會被繪製?

基本上,爲什麼我的JLabel不顯示任何東西,除非我明確地把它放在構造函數中?

import javax.swing。 ; import java.awt。;

公共類JLabelCounter擴展JLabel {

private MinesweeperModel model; 
public JLabelCounter(MinesweeperModel myModel) 
{ 
    model = myModel;  

} 

public void paintComponent(Graphics g) 
{ 
    super.paintComponent(g); 
    int minesRemaining = model.numberOfMinesRemaining(); 
    setText("Mines remaining" + minesRemaining); 

} 

}

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class MinesweeperPanel extends JPanel { 

private MinesweeperModel model; 
private JLabelCounter labelCounter; 

public MinesweeperPanel(MinesweeperModel myModel, JLabelCounter counter) 
{ 
    model = myModel; 
    labelCounter = counter; 
    setLayout(new GridLayout(10,10)); 
    //addMouseListener(new MouseHandler()); 

    for(int i = 0; i <10; i++) 
    { 
     for(int j = 0; j < 10; j++) 
     { 
      MinesweeperJLabel myJLabel = new MinesweeperJLabel(i,j,myModel); 
      myJLabel.addMouseListener(new MouseHandler()); 
      add(myJLabel); 
     } 

    } 

} 

private class MouseHandler extends MouseAdapter 
{ 
    public void mouseClicked(MouseEvent e) 
    { 

     MinesweeperJLabel labelClicked = (MinesweeperJLabel)e.getSource(); 
     int x = labelClicked.getXCoordinate(); 
     int y = labelClicked.getYCoordinate(); 
     int buttonClicked = e.getButton(); 

     if (buttonClicked == 1) 
     { 
      model.stepOnMine(x,y); 
     } 
     else if(buttonClicked == 3) 
     { 
      model.flagMine(x, y); 
     } 
     repaint(); 
     labelCounter.repaint(); 


    } 
} 

}

import javax.swing.*; 
import java.awt.*; 
import java.awt.geom.*; 

public class MinesweeperFrame extends JFrame{ 

public MinesweeperFrame() 
{ 
    MinesweeperModel myModel = new MinesweeperModel(); 
    setTitle("My Super Awesome Minesweeper Game!"); 
    Toolkit kit = Toolkit.getDefaultToolkit(); 
    Dimension screenSize = kit.getScreenSize(); 
    setSize(screenSize.width/2,screenSize.height/2); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    JLabelCounter counter = new JLabelCounter(myModel); 
    Container contentPane = getContentPane(); 
    MinesweeperPanel panel = new MinesweeperPanel(myModel,counter); 
    contentPane.add(counter,BorderLayout.PAGE_START); 
    contentPane.add(panel); 

    setVisible(true);  


} 

}

隨着代碼,它看起來好像我不我連JLabe都沒有當我跑步時,在我的頭部。

+0

不要從的paintComponent中調用的setText,它會導致組件和其他的無效重新繪製請求,一次又一次...您的主意 – MadProgrammer 2013-02-16 21:25:44

+0

然後,我如何讓JLabel顯示不同的文本更新與遊戲? – art3m1sm00n 2013-02-16 21:27:49

+0

查看答案 - 基本上,我們是一個觀察者模式 – MadProgrammer 2013-02-16 21:30:23

回答

3

不要從的paintComponent中調用的setText,它會導致組件和另一重繪請求無效,一次又一次......你的想法

而不是試圖更新標籤,油漆方法。爲您建立一種監聽器接口模型,您可以使用它來更新標籤。

基本上,當你的模式的轉變,它會觸發一個事件,您的標籤可以反應和更新自我

+0

我曾考慮過這個問題,但用戶永遠不會真正點擊標題。因此,附加到標題的聽衆永遠不會被觸發 – art3m1sm00n 2013-02-16 21:31:57

+1

這取決於它正在監聽的內容。 MP並沒有說它有聽用戶事件,而是傾聽模型事件。你的模型(不過你已經實現了)是代表遊戲邏輯的所有數據和數據結構(與UI分離);它知道哪些方格已被清除,哪些方格正在顯示與之相鄰的地雷數量。當用戶點擊一個正方形時,我希望模型有一個偵聽器被觸發,找出其他正方形狀態已經改變的結果,並且爲每個正方形觸發一個偵聽器。 – arcy 2013-02-16 21:36:42

+0

做到了。謝謝! – art3m1sm00n 2013-02-16 21:52:56

相關問題