001import javax.swing.*;
002import java.awt.*;
003import java.awt.event.*;
004import java.net.URL;
005import java.awt.image.*;
006import java.awt.Color;
007import java.awt.Font;
008
009import javax.swing.JButton;
010
011import java.io.*;
012
013import java.applet.Applet;
014import java.net.URL;
015import java.applet.AudioClip;
016
017/**
018 * This class implements a simple graphical user interface with a text entry
019 * area, a text output area and an optional image.
020 * 
021 * @author Michael Kolling - Alban FERRACANI
022 * @version 1.0 (Jan 2003), DB edited (2019), AF edited (2021)
023 */
024public class UserInterface implements ActionListener
025{
026    private GameEngine aEngine;
027    private JFrame     aMyFrame;
028    private JTextField aEntryField;
029    private JTextArea  aLog;
030    private JLabel     aImage;
031
032    private JButton abtnAide;
033    private JButton abtnQuit;
034    private JButton abtnAttraper; //bouton = btn
035    private JButton abtnNord;
036    private JButton abtnSud;
037    private JButton abtnOuest;
038    private JButton abtnEst;
039    
040    private JButton abtnHaut;
041    private JButton abtnBas;
042    private JButton abtnBack;
043    
044    private JButton[] aButtons; 
045    
046    private JPanel vPanel1 = new JPanel();
047    private JPanel vPanel2 = new JPanel(); 
048    //private JPanel vPanel3 = new JPanel();  //panel end 
049    //private boolean aPanel3Visible = false;
050    //private boolean aPanel2Visible;
051    
052   
053    
054    /**
055     * Construct a UserInterface. As a parameter, a Game Engine
056     * (an object processing and executing the game commands) is
057     * needed.
058     * 
059     * 
060     */
061    public UserInterface( final GameEngine pGameEngine )
062    {
063        this.aEngine = pGameEngine;
064        this.createGUI();
065        //this.aPanel2Visible = true;
066
067    } // UserInterface(.)
068
069    /**
070     * Print out some text into the text area.
071     */
072    public void print( final String pText)
073    {
074        this.aLog.append( pText );
075        this.aLog.setCaretPosition( this.aLog.getDocument().getLength() );
076        
077        
078        // URL url = getClass().getClassLoader().getResource("dong.wav");
079        // AudioClip clip = Applet.newAudioClip(url);
080        
081        // new Thread() {
082            // public void run() {
083                // clip.play();
084            // }
085        // }.start();
086        
087        
088    } // print(.)
089    
090    
091    /**
092     * Print out some text into the text area.
093     * Permet d'afficher ce texte avec une police, couleur spécifique.
094     * @param pText (String) pour le texte à afficher.
095     * @param pColor (Color) pour la couleur du texte à afficher.
096     */
097    public void printBold( final String pText, final Color pColor)
098    {
099        Font vFont1 = new Font(" TimesRoman ",Font.BOLD,30);        //On  crée une nouvelle police vFont1
100        Font vFont2 = new Font(" Courrier ",Font.BOLD, 12);         //On  crée une nouvelle police vFont2
101        this.aLog.append( pText + "\n" );
102        this.aLog.setForeground(pColor);                            //On met le texte dans la couleur choisie
103        this.aLog.setFont(vFont2);                                  //On lui applique la police désirée (taille + police + style : gras, italique)
104        this.aLog.setDisabledTextColor(Color.GRAY);                     
105        this.aLog.setCaretPosition( this.aLog.getDocument().getLength() );
106
107    } // printBold(.)
108    
109    /**
110     * Print out some text into the text area, followed by a line break.
111     */
112    public void println( final String pText )
113    {
114        this.print( pText + "\n" );
115    } // println(.)
116
117    /**
118     * Affiche une image sur l'user interface.
119     */
120    public void showImage( final String pImageName )
121    {
122        String vImagePath = "" + pImageName; // to change the directory
123        URL vImageURL = this.getClass().getClassLoader().getResource( vImagePath );
124        if ( vImageURL == null )
125            System.out.println( "Image non trouvée : " + vImagePath );
126        else {
127            ImageIcon vIcon = new ImageIcon( vImageURL );
128            this.aImage.setIcon( vIcon );
129            this.aMyFrame.pack();
130            
131            
132        }
133    } // showImage(.)
134
135    /**
136     * Enable or disable input in the input field.
137     * Permet également d'afficher l'image de fin dans le cas où le jeu a été gagné,
138     * perdu ou quitté.
139     * @param pOnOff (booleen) pour rendre enable ou disable l'interface utilisateur.
140     */
141    public void enable( final boolean pOnOff )
142    {
143        this.aEntryField.setEditable( pOnOff ); // enable/disable
144        this.aEntryField.setVisible(false);
145        this.vPanel1.setVisible(false);
146        this.aMyFrame.setTitle("Au revoir !");
147        this.showImage("images/end5.gif");
148        //this.aPanel3Visible(true);
149        //vPanel3.add( this.aImage, BorderLayout.NORTH );
150        //this.showImage("images/end2.gif");
151        
152        // URL url = getClass().getClassLoader().getResource("son/cheval.wav");
153        // AudioClip clip = Applet.newAudioClip(url);
154        
155        // URL urlfin = getClass().getClassLoader().getResource("son/sound2.wav");
156        // AudioClip clipfin = Applet.newAudioClip(urlfin);
157        
158        // URL urlfin1 = getClass().getClassLoader().getResource("son/end.wav");
159        // AudioClip clipfin1 = Applet.newAudioClip(urlfin1);
160        
161        // URL urlpause = getClass().getClassLoader().getResource("son/pause.wav");
162        // AudioClip clippause = Applet.newAudioClip(urlpause);
163
164       
165        
166        if ( ! pOnOff ) { // disable
167            this.aEntryField.getCaret().setBlinkRate( 0 ); // cursor won't blink
168            this.aEntryField.removeActionListener( this ); // won't react to entry
169        }
170        
171        // new Thread() {
172            // public void run() {
173                // clipfin1.play();
174                // clip.play();
175                // clipfin.play();
176                // //clippause.play();
177            // }
178        // }.start();
179        
180        
181    } // enable(.)
182    
183    /**
184     * Efface le texte de l'interface graphique
185     * Méthode appelée pour effacer l'historique des affichages à la fin du jeu pour 
186     * afficher le message final. 
187     */
188    public void clearText(){
189        this.aLog.setText("");
190    }
191    
192    /**
193     * Set up graphical user interface.
194     */
195    private void createGUI()
196    {
197        this.aMyFrame = new JFrame( "Bienvenue dans le château Périgourdain !" ); // change the title
198        this.aEntryField = new JTextField( 34 );
199        this.aEntryField.setForeground(Color.DARK_GRAY);
200        this.aEntryField.setText("Saisissez ici votre commande puis pour valider tapez entrer");
201        
202        this.aLog = new JTextArea();
203        this.aLog.setEditable( false );
204        JScrollPane vListScroller = new JScrollPane( this.aLog );
205        vListScroller.setPreferredSize( new Dimension(200, 300) );
206        vListScroller.setMinimumSize( new Dimension(100,100) );
207        
208
209        
210        this.abtnAide = new JButton("Aide");
211        this.abtnAide.setActionCommand("help");
212        this.abtnQuit = new JButton("Quitter");
213        this.abtnQuit.setActionCommand("quit");
214        this.abtnAttraper = new JButton("Attraper");
215        this.abtnAttraper.setActionCommand("take");
216        this.abtnNord = new JButton("Nord", new ImageIcon("icons/nord.png"));
217        this.abtnNord.setActionCommand("go nord");
218        this.abtnSud = new JButton("Sud", new ImageIcon("icons/sud.png"));
219        this.abtnSud.setActionCommand("go sud");
220        this.abtnOuest = new JButton("Ouest", new ImageIcon("icons/ouest.png"));
221        this.abtnOuest.setActionCommand("go ouest");
222        this.abtnEst = new JButton("Est", new ImageIcon("icons/est.png"));
223        this.abtnEst.setActionCommand("go est");
224        this.abtnHaut = new JButton("Haut", new ImageIcon("icons/haut.png"));
225        this.abtnHaut.setActionCommand("go haut");
226        this.abtnBas = new JButton("Bas", new ImageIcon("icons/bas.png"));
227        this.abtnBas.setActionCommand("go bas");
228        this.abtnBack = new JButton("Back", new ImageIcon("icons/back.png"));
229        this.abtnBack.setActionCommand("back");
230        
231        JButton[] vButtons = {abtnAide, abtnAttraper, abtnNord, abtnSud, abtnEst, abtnOuest, abtnHaut, abtnBas, abtnBack, abtnQuit};
232        this.aButtons = vButtons; 
233        
234        JPanel vPanel = new JPanel();
235        this.aImage = new JLabel();
236        
237
238        vPanel.setLayout( new BorderLayout() ); // ==> only five places
239        vPanel.add( this.aImage, BorderLayout.NORTH );
240        vPanel.add( vListScroller, BorderLayout.CENTER );
241        vPanel.add( this.aEntryField, BorderLayout.SOUTH );
242        
243        //Ajout panel 1 (panel boutons situé à EAST)
244        //JPanel vPanel1 = new JPanel(); 
245        
246        vPanel1.setLayout( new BorderLayout() ); // ==> only five places
247        vPanel.add(vPanel1, BorderLayout.EAST );
248        // vPanel1.add( this.abtnAide, BorderLayout.CENTER);
249        //vPanel1.add( this.abtnAttraper, BorderLayout.SOUTH);
250        vPanel1.add( this.abtnNord, BorderLayout.NORTH);
251        vPanel1.add( this.abtnSud, BorderLayout.SOUTH);
252        vPanel1.add( this.abtnOuest, BorderLayout.WEST);
253        vPanel1.add( this.abtnEst, BorderLayout.EAST);
254        
255        //Ajout panel 2 (panel boutons situé  CENTER)
256        //JPanel vPanel2 = new JPanel(); 
257        vPanel2.setLayout( new BorderLayout() ); // ==> only five places
258        vPanel1.add(vPanel2, BorderLayout.CENTER );
259
260        
261        vPanel2.add( this.abtnBack, BorderLayout.CENTER);
262        vPanel2.add( this.abtnHaut, BorderLayout.NORTH);
263        vPanel2.add( this.abtnBas, BorderLayout.SOUTH);
264        
265        
266        // JPanel vPanel3 = new JPanel(); 
267        // vPanel3.setLayout( new BorderLayout() ); // ==> only five places
268        // vPanel.add(vPanel3, BorderLayout.SOUTH );
269        // vPanel3.add( this.aEntryField, BorderLayout.SOUTH );
270        // vPanel3.add( this.abtnAide, BorderLayout.NORTH );
271        // vPanel3.add( this.abtnQuit, BorderLayout.EAST );
272        
273        
274        this.aMyFrame.getContentPane().add( vPanel, BorderLayout.CENTER );
275
276        
277        //vPanel3.setLayout( new BorderLayout() ); // ==> only five places
278        //vPanel3.add( this.aImage, BorderLayout.NORTH );
279        //vPanel.add(vPanel3, BorderLayout.EAST );
280        //vPanel3.setVisible(aPanel3Visible);
281        
282        
283        // add some event listeners to some components
284        this.aEntryField.addActionListener( this );
285
286        // to end program when window is closed
287        this.aMyFrame.addWindowListener( new WindowAdapter() {
288                public void windowClosing(WindowEvent e) { System.exit(0); }
289            } );
290
291        this.aMyFrame.pack();
292        this.aMyFrame.setVisible( true );
293        this.aEntryField.requestFocus();
294
295        //Ajout du bouton à notre content pane
296        this.abtnAide.addActionListener(this);
297        //vPanel.add(this.abtnAide, BorderLayout.WEST);
298
299        this.abtnAttraper.addActionListener(this);
300        //vPanel.add(this.abtnAttraper, BorderLayout.EAST);
301        this.abtnNord.addActionListener(this);
302        this.abtnSud.addActionListener(this);
303        this.abtnOuest.addActionListener(this);
304        this.abtnEst.addActionListener(this);
305        this.abtnBack.addActionListener(this);
306        this.abtnHaut.addActionListener(this);
307        this.abtnBas.addActionListener(this);
308    } // createGUI()
309    
310    /**
311     * Actionlistener interface for entry textfield.
312     */
313    public void actionPerformed( final ActionEvent pE ) 
314    {
315        // now we must check the type of action
316        // because there are many possible actions...
317
318        Object  source=pE.getSource();
319
320        // if  (source==this.abtnAide){
321            // this.println("test bouton " + this.abtnAide.getLabel());
322            // //this.aEntryField.setText("help");
323            // this.aEntryField.setText(this.abtnAide.getActionCommand());
324        // }
325        // else if (source==this.abtnAttraper){
326            // this.println("test bouton " + this.abtnAttraper.getLabel());
327            // //this.println("test bouton 0 - Attraper l'objet ");
328            // //this.aEntryField.setText("take");
329            // this.aEntryField.setText(this.abtnAttraper.getActionCommand());
330        // }
331
332        for(JButton vB: this.aButtons ){
333            if (source==vB){
334                //this.println("test " + vB.getLabel());
335                this.aEntryField.setText(vB.getActionCommand());
336            }
337
338        }
339        this.processCommand(); // never suppress this line
340
341    } // actionPerformed(.)
342
343    /**
344     * A command has been entered. Read the command and do whatever is 
345     * necessary to process it.
346     */
347    private void processCommand()
348    {
349        String vInput = this.aEntryField.getText();
350        this.aEntryField.setText( "" );
351        this.aEngine.interpretCommand( vInput );
352    } // processCommand()
353
354} // UserInterface