001import javax.swing.JFrame;
002import javax.swing.JTextField;
003import javax.swing.JTextArea;
004import javax.swing.JLabel;
005import javax.swing.ImageIcon;
006import javax.swing.JScrollPane;
007import javax.swing.JPanel;
008import javax.swing.JButton;
009
010import java.awt.Dimension;
011import java.awt.BorderLayout;
012
013import java.awt.event.ActionListener;
014import java.awt.event.ActionEvent;
015import java.awt.event.WindowEvent;
016import java.awt.event.WindowAdapter;
017
018import java.net.URL;
019
020
021/**
022 * Cette classe permet d'avoir une interface graphique relativement simple, avec de de l'affichage d'image dans le jeu
023 * en plus, de l'action entrée qui est paramétrée pour regarder les commandes tapées.
024 * 
025 * 
026 * @author Gabriel Leroux
027 * @version 23/03/20
028 */
029public class UserInterface implements ActionListener
030{
031    private GameEngine aEngine;
032    private JFrame     aMyFrame;
033    private JTextField aEntryField;
034    private JTextArea  aLog;
035    private JLabel     aImage;
036    private JButton aBouton;
037    /**
038     * Construit une interface pour l'utilisateur prenant en paramètre un objet GameEngine.
039     * 
040     * @param pGameEngine The GameEngine object implementing the game logic.
041     */
042    public UserInterface( final GameEngine pGameEngine )
043    {
044        this.aEngine = pGameEngine;
045        this.createGUI();
046    } // UserInterface(.)
047
048    /**
049     * Affiche du texte dans une zone de texte prédéfini.
050     * @param pText String souhaitant être affichée
051     */
052    public void print( final String pText )
053    {
054        this.aLog.append( pText );
055        this.aLog.setCaretPosition( this.aLog.getDocument().getLength() );
056    } // print(.)
057
058    /**
059     * Affiche du texte dans une zone de texte prédéféni en sautant une ligne entre.
060     * @param pText String que l'on doit afficher avec un saut de ligne
061     */
062    public void println( final String pText )
063    {
064        this.print( pText + "\n" );
065    } // println(.)
066
067    /**
068     * Montre un fichier image dans la fenêtre.
069     * @param pImageName nom de l'image que l'on souhaite afficher.
070     */
071    public void showImage( final String pImageName )
072    {
073        String vImagePath = "" + pImageName; // to change the directory
074        URL vImageURL = this.getClass().getClassLoader().getResource( vImagePath );
075        if ( vImageURL == null )
076            System.out.println( "Image not found : " + vImagePath );
077        else {
078            ImageIcon vIcon = new ImageIcon( vImageURL );
079            this.aImage.setIcon( vIcon );
080            this.aMyFrame.pack();
081        }
082    } // showImage(.)
083
084    /**
085     * Active ou désactive la zone de saisie du texte et des commandes.
086     * @param pOnOff vrai ou faux selon de si la zone d'entrée de commande est désactivée ou non
087     */
088    public void enable( final boolean pOnOff )
089    {
090        this.aEntryField.setEditable( pOnOff ); // enable/disable
091        if ( ! pOnOff ) { // disable
092            this.aEntryField.getCaret().setBlinkRate( 0 ); // cursor won't blink
093            this.aEntryField.removeActionListener( this ); // won't react to entry
094        }
095    } // enable(.)
096
097    /**
098     * Initialise une interface graphique pour l'utilisateur basique.
099     */
100    private void createGUI()
101    {
102        this.aMyFrame = new JFrame( "Gaby's Game" ); // change the title
103        this.aEntryField = new JTextField( 34 );
104
105        this.aLog = new JTextArea();
106        this.aLog.setEditable( false );
107        JScrollPane vListScroller = new JScrollPane( this.aLog );
108        vListScroller.setPreferredSize( new Dimension(200, 200) );
109        vListScroller.setMinimumSize( new Dimension(100,100) );
110
111        JPanel vPanel = new JPanel();
112        this.aImage = new JLabel();
113
114        vPanel.setLayout( new BorderLayout() ); // ==> only five places
115        vPanel.add( this.aImage, BorderLayout.NORTH );
116        vPanel.add( vListScroller, BorderLayout.CENTER );
117        vPanel.add( this.aEntryField, BorderLayout.SOUTH );
118
119        this.aMyFrame.getContentPane().add( vPanel, BorderLayout.CENTER );
120
121        // add some event listeners to some components
122        this.aEntryField.addActionListener( this );
123
124        // to end program when window is closed
125        this.aMyFrame.addWindowListener( new WindowAdapter() {
126            public void windowClosing(WindowEvent e) { System.exit(0); }
127        } );
128
129        this.aMyFrame.pack();
130        this.aMyFrame.setVisible( true );
131        this.aEntryField.requestFocus();
132        
133        //création d'un bouton
134        this.aBouton=new JButton("quit");
135        vPanel.add(aBouton,BorderLayout.EAST);
136        aBouton.addActionListener(this);
137        
138    } // createGUI()
139
140    /**
141     * Interface Actionlistener pour l'action entrée mais aussi pour les actions liées aux différents boutons.
142     * @param pE est une action associé a un un évnèmenent appuyer sur un bouton par exemple
143     */
144    public void actionPerformed( final ActionEvent pE ) 
145    {
146        // no need to check the type of action at the moment
147        // because there is only one possible action (text input) :
148        if(pE.getSource()==this.aBouton){
149        this.aEngine.interpretCommand(aBouton.getActionCommand());return;}
150        
151        this.processCommand(); // never suppress this line
152    } // actionPerformed(.)
153
154    /**
155     * Lorsqu'une commande est entrée, cette méthode la lit et éxécute ce qui doit être éxécuté par la commande.
156     */
157    private void processCommand()
158    {
159        String vInput = this.aEntryField.getText();
160        this.aEntryField.setText( "" );
161
162        this.aEngine.interpretCommand( vInput );
163    } // processCommand()
164  
165} // UserInterface