2014-01-09 425 views
0

我正在研究一個需要在主要的JFrameJPanel之間進行通信的小遊戲gamepan改進JFrame和JPanel之間的通信

遊戲要求用戶通過點擊包含字母表的按鈕找到隱藏的單詞。

JFrame包含gamepanscorepanmenus和其他的東西......

gamepan包含我buttonsArrayListener,隱藏文字和其他東西......

的問題是,當用戶發現隱藏的話我要告訴我的JFrame,他這樣做稍後可以重新繪製gamepan,使一個新詞....

我所做的是:我爲m增加了boolean Ÿgamepan如果我的話被發現或不和MouseListenergamepan,所以每次我移動鼠標JFrame測試如果單詞或發現不 然後在我gamepan,我從JFrame使用初始化的東西補充制定者告訴再次如果找到隱藏的詞。

我覺得這不是檸有效添加MouseListener,因爲我必須mouve鼠標來進行的變化,每次鼠標移動沒用treatements由...

我想知道是否有是比添加MouseListener更好的溶劑?而且我想知道如果我還是很好地爲gamepan添加setter以設置新詞的變量。

這裏是我的代碼

gamepan代碼

public class GamePanel extends JPanel{ 
private JPanel leftPan = new JPanel(); 
private JPanel rightPan = new JPanel(); 
private String[] letters =  {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",}; 
private JButton Button[] = new JButton[26]; 

private JLabel label1; 
private JLabel label2; 
private JLabel label3; 
private ActionListener buttonListener; 
private JOptionPane jop = new JOptionPane(); 

private Word randWord = new Word(); // mot aléatoire 
private TreatedWord tWord = new TreatedWord(randWord.getRandWord());// mot aléatoire traité (etoiles et tout ça) 
private char clickedButton;// lettre tappée 
private boolean motTrouvé = false; // pour informer la classe Fenetre si le mot a été retrouvé ou pas on utilise ce boolean avec son getter et setter (a savoir que cette classe est informée si le mot est trouvé ou pas via l'objet tWord) 


private final List<CustomListener> customListener = new LinkedList<>(); //On crée une liste de CustomListener pour en ajouter autant qu'on veut(Via addCustomListener) 

public GamePanel(){ 
    this.setBackground(Color.white); 
    initGamePan(); 
    initListeners(); 
    this.setLayout(new BorderLayout()); 
    this.add(leftPan,BorderLayout.WEST); 
    this.add(rightPan,BorderLayout.EAST); 
} 

public void initGamePan(){ 
    rightPan.add(new JLabel(new ImageIcon("131869.jpg"))); 
    label1 = new JLabel("Nombre de mots trouvés : 0"); 
    label1.setHorizontalAlignment(JLabel.CENTER); 
    label1.setFont(new Font("arial",Font.BOLD,20)); 
    label1.setPreferredSize(new Dimension(300,50)); 

    label2 = new JLabel("Score Actuel : 0 point"); 
    label2.setHorizontalAlignment(JLabel.CENTER); 
    label2.setFont(new Font("arial",Font.BOLD,20)); 
    label2.setPreferredSize(new Dimension(300,50)); 

    label3 = new JLabel(tWord.getStars()); 
    label3.setHorizontalAlignment(JLabel.CENTER); 
    label3.setFont(new Font("arial",Font.BOLD,30)); 
    label3.setForeground(Color.blue); 
    label3.setPreferredSize(new Dimension(450,50)); 

    leftPan.add(label1); 
    leftPan.add(label2); 
    leftPan.add(label3); 
    for(int i=0;i<letters.length;i++){ 
     Button[i]= new JButton(letters[i]); 
     leftPan.add(Button[i]); 
    } 

    leftPan.setPreferredSize(new Dimension(460,650)); 
    leftPan.setBackground(Color.WHITE); 
    rightPan.setPreferredSize(new Dimension(420,650)); 
    rightPan.setBackground(Color.WHITE); 
} 

public void initListeners(){ 
    buttonListener= new ActionListener(){ 

     public void actionPerformed(ActionEvent arg0) { 
      clickedButton = ((JButton)(arg0.getSource())).getText().charAt(0); // on prend le bouton cliqué, on le convertis en string puis en char 
      label3.setText(tWord.treatedWord(clickedButton));// on donne a la methode tretedWord de l'objet tWord le char clickedbutton pour faire le traitement sur le mot mystère 
      ((JButton)(arg0.getSource())).setEnabled(false); 

      if(tWord.isFound()==true){ 
       jop.showMessageDialog(null, "Bravo t'a trouvé le mot !", "U don't Say B|", JOptionPane.INFORMATION_MESSAGE); 
       motTrouvé = true; 

      } 
     } 

    }; 
    for(int i=0;i<letters.length;i++){ 
     Button[i].addActionListener(buttonListener); 
    } 

} 


public void setNewWord(){ 
    this.randWord = new Word(); 
    this.tWord = new TreatedWord(randWord.getRandWord()); 
    this.label3.setText(tWord.getStars()); 
} 
public void resetButtons(){ 
    for(JButton B : this.Button){ 
     B.setEnabled(true); 
    } 
} 


public void addCustomListener(final CustomListener listener) { 
     this.customListener.add(listener); 
    } 

public void notifyWordFound(/* any data you could use */) { 
     for(final CustomListener listener : this.customListener) { 
      listener.wordFound(/* any data you could use */); 
     } 
    } 

}

MyJFrame代碼:

公共類FENETRE擴展的JFrame {

private JMenuBar menu = new JMenuBar(); 
    private JMenu file = new JMenu("Fichier"); 
    private JMenuItem neew = new JMenuItem("Nouveau"); 
    private JMenuItem score = new JMenuItem("Score"); 
    private JMenuItem quit = new JMenuItem("Quitter"); 
    private JMenu about = new JMenu("About"); 
    private JMenuItem how = new JMenuItem("Règles"); 
    private JMenuItem who = new JMenuItem("Credit"); 
    private int i=1; 
    private ScorePanel scorepan = new ScorePanel(900,650); 
    private ReglesJeuPanel rgpan = new ReglesJeuPanel(900,650); 
    private GamePanel gamepan = new GamePanel(); 
    private JPanel pan = new JPanel(); 
    private JPanel container = new JPanel(); 
    private JLabel label = new JLabel("------------------------SAMAIKOM------------------------"); 
    private JTextArea texte = new JTextArea( "Vous avez sept coups pour trouver le mot caché. Si vous réussissez, on recommence !\n" + 
      "Plus vous trouvez de mots, plus votre score augmente. Alors, à vous de jouer !\n" + 
      "Proverbe :\t« Pas vu, pas pris !\n" + 
       "\tPris ! PENDU ! »"); 
public Fenetre(){ 
    this.setTitle("Le Pendu ..."); 
    this.setSize(900, 650); 
    this.setDefaultCloseOperation(EXIT_ON_CLOSE); 
    this.setLocationRelativeTo(null); 
    this.setVisible(true); 
    initMenu(); 
    initAcceuilPan(); 
    initListeners(); 
    this.setContentPane(container); 
} 

private void initMenu(){ 
    file.add(neew); 
    file.add(score); 
    file.addSeparator(); 
    file.add(quit); 
    file.setMnemonic('F'); 
    neew.setMnemonic('N'); 
    neew.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,KeyEvent.CTRL_DOWN_MASK)); 
    score.setMnemonic('S'); 
    score.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,KeyEvent.CTRL_DOWN_MASK)); 
    quit.setMnemonic('Q'); 
    quit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q,KeyEvent.CTRL_DOWN_MASK)); 

    about.add(how); 
    about.addSeparator(); 
    about.add(who); 
    about.setMnemonic('A'); 
    how.setMnemonic('R'); 
    how.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R,KeyEvent.CTRL_DOWN_MASK)); 
    who.setMnemonic('C'); 
    who.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,KeyEvent.CTRL_DOWN_MASK)); 

    menu.add(file); 
    menu.add(about); 
    this.setJMenuBar(menu); 
} 

private void initListeners(){ 
    score.addActionListener(new ActionListener(){ 
     public void actionPerformed(ActionEvent arg0) { 
      container.removeAll(); 
      container.add(scorepan); 
     } 
    }); 
    quit.addActionListener(new ActionListener(){ 
     public void actionPerformed(ActionEvent arg0) { 
      System.exit(0); 
     } 
    }); 
    how.addActionListener(new ActionListener(){ 
     public void actionPerformed(ActionEvent arg0) { 
      container.removeAll(); 
      container.add(rgpan); 
     } 
    }); 
    neew.addActionListener(new ActionListener(){ 
     public void actionPerformed(ActionEvent arg0) { 
      gamepan.setNewWord(); 
      gamepan.resetButtons(); 
      container.removeAll(); 
      container.add(gamepan); 
     } 
    }); 

    gamepan.addCustomListener(new CustomListener(){ 

     public void wordFound() { 
     } 

    }); 

    gamepan.notifyWordFound();  // where to put this ????? 


} 

private void initAcceuilPan(){ 
    pan.setBackground(Color.white); 
    pan.add(new JLabel(new ImageIcon("131868.jpg"))); 
    texte.setEditable(false); 
    Font F1 = new Font("arial",Font.BOLD,20); 
    Font F2 = new Font("arial",Font.BOLD,15); 
    label.setFont(F1); 
    texte.setFont(F2); 
    container.setBackground(Color.white); 
    container.add(label); 
    container.add(pan); 
    container.add(texte); 
    //container.add(gamepan); 

} 


public static void main(String[] args) { 
    Fenetre F1 = new Fenetre(); 
} 

}

回答

4

你可以用一個字被發現,可能會出現一些自定義的事件:

public interface MyEventListener { 
    public abstract void wordFound(/* any data you could use */); 
} 

然後讓你的GamePan能夠發出這樣的事件:

public class GamePan extends JPanel { 
    private final List<MyEventListener> myEventListeners = new LinkedList<>(); 

    // Here, keep everything you already have 

    public void addMyEventListener(final MyEventListener listener) { 
     this.myEventListeners.add(listener); 
    } 

    private void notifyWordFound(/* any data you could use */) { 
     for(final MyEventListener listener : this.myEventListeners) { 
      listener.wordFound(/* any data you could use */) 
     } 
    } 
} 

當這個詞被發現,只需撥打GamePan#notifyWordFound即可。 然後,註冊當這樣的事件發生在你的JFrame叫一些更新方法:

public class MyJFrame extends JFrame { 
    // Here, keep everything you already have 

    public JFrame() { 
     // Here, keep everything you already have 

     // Let's assume your ScorePanel instance is here: 
     final ScorePanel scorePanel = new ScorePanel(); 

     this.gamePan.addMyEventListener(new MyEventListener() { 
      @Override 
      public void wordFound(/* any data you could use */) { 
       // Update your application using any data you can use :) 
       scorePanel.wordFound(/* any data you could use */); 
      } 
     }); 
    } 
} 

在這裏,我們簡單地調用ScorePanel#wordFound方法使ScorePanel可以更新。

不要忘記,您可以通過所有這些方法傳輸您感興趣的任何數據。例如,如果您想要傳送用戶只需找到了一句話,MyEventListener#wordFound方法可以聲明如下:

public interface MyEventListener { 
    public abstract void wordFound(final String word); 
} 

編輯:添加了ScorePanel比如有的相互作用來回答你的問題,另外在評論:)

+0

感謝名單,我理解,但我在哪裏打電話gamepan .notifyWordFound ???我的意思是我把它放在我的JFrame中?我編輯我的文章添加我的代碼,使其簡單 – FrankelStein

+0

你需要通知,找到一個單詞(即使用'notifyWordFound'),當......找到一個單詞:) 基本上,我認爲你想使用它在哪裏測試'if(tWord.isFound()== true)'(在你的文件_GamePanel.java_的第90行左右,我相信,就像這樣調用它:'GamePanel.this.notifyWordFound();'。 By 'GamePan#notifyWordFound'應該是'private' :) – ccjmne

+0

而且,if(tWord.isFound()== true)中不需要'== true',除非它在你看來更清楚,if 'tWord.isFound'是'true',以及它是'true',並且進入'if'的條件被驗證,沒有必要明確地將其與'true'進行比較。:) – ccjmne

0

通常,ClassName.this語法用於不是static的嵌套類中。它用於訪問其外部類的實例。我給大家舉一個例子:現在

class OuterClass { 
    private final String text = "I'm the outer class!"; 

    class NestedClass { 
     private final String text = "I'm the nested class!"; 

     public final String getText() { 
      return this.text; // "I'm the outer class!" 
     } 

     public final String getOuterClassText() { 
      return OuterClass.this.text; // "I'm the nested class!" 
     } 
    } 
} 

,你的情況,你有嵌套類實際上是您實例化MyEventListener接口,用下面的代碼創建了一個匿名類:

gamePanel.addMyEventListener(new MyEventListener() { 
    @Override 
    public void wordFound(/* any data you could use */) { 
     // Here, access your GamePanel's instance attributes and methods using GamePanel.this 
    } 
}); 

讓我向你解釋一下上面的代碼完全沒有:

new MyEventListener() { 
} 

此符號將創建一個匿名類implements MyEventListener。您可以通過在括號{}之間添加任何你想要的內容來修改該類的定義。既然你實現一些接口,你必須overrideabstract method在接口中聲明,就像這樣:

new MyEventListener() { 
    @Override 
    public void wordFound(/* any data you could use */) { 
    } 
} 

我希望這是明確的,它幫助你:)

+0

此答案不直接回答所問的問題,它實際上是打算根據我上面的回答的評論中的要求提供其他信息。 – ccjmne