2013-02-16 95 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

相关问题