Universidad Carlos III de Madrid

Ingeniería de Telecomunicación

Enero-Mayo 2010 / January-May 2010

Graphical User Interfaces

Lab Section1.  Laboratory: Graphical User Interfaces

Time90 min

Exercise Section1.1.  Events management

Time40 min

The following code is a simple graphic interface which contains a javax.swing.JButton button that can be clicked. The rest of the elements of the interface should be well known by you.

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.BorderLayout;

class Simple00GUIEn {

	private static final String FRAME_TITLE = "Simple00GUI";
	private static final String BUTTON_TEXT = "Click me!";

	private void createGUI() {
		JFrame.setDefaultLookAndFeelDecorated(true);
		JFrame frame = new JFrame(FRAME_TITLE);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JPanel contentPane = (JPanel) frame.getContentPane();
		JButton button = new JButton(BUTTON_TEXT);
		contentPane.add(button, BorderLayout.CENTER);
		frame.pack();
		frame.setVisible(true);
	}

	public static void main(String args[]) {
		Simple00GUIEn p = new Simple00GUIEn();
		p.createGUI();
	}
}

          

Download this code

  1. Compile and execute this program. What happens when the button is pressed?

  2. Open the Java API and localize the JButton class (this is a good habit that you should always do when programming).

  3. Implement a program, Simple01GUIEn, based on Simple00GUIEn, in which a text message is printed to console when the button is pressed. You will find useful the javax.swing.AbstractButton.addActionListener(ActionListener l) method and the following code shell:

    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    
    class ButtonActionListenerEn implements ActionListener {
    
        public void actionPerformed(ActionEvent e) {
    
        }
    }
    
              

    Download this code

  4. Implement a program Simple02GUIEn, based on Simple00GUIEn, in which the program modify its text when the user clicks the button.

  5. Implement a program Simple03GUIEn, based on Simple00GUIEn, which also contains a JLabel which text appears after the first button press.

  6. Write a TwoButtons program that contains two buttons, A and B. When the program starts, only the A button must be active. When the A button is clicked, it must be disable and B must turn into active. The behaviour of B button must be simmetric to A. Here you can find an example:TwoButtons.class. (Note: This example is composed of a single class, but you are not forced to follow the same pattern. Choose the more suitable way for you).

  7. Regarding the previous section, if you made the program with a single class, repeat the exercise using several classes. If you implemented several classes, make the necessary changes in order to have a single class (that is, only a .class file).

Exercise Section1.2.  Event Management in GUIs I - (Tic Tac Toe)

Time90 min

During this exercise, we are going to practice with the implementation of a complete example of a Graphic User Interface (GUI) that integrates the corresponding Event Management associated to the graphic elements that are composed of.

To do so, we will be based on the Tic Tac Toe's famous game. According to the Wikipedia, the Tic-tac-toe, also spelled tick tack toe, and alternatively called noughts and crosses, Xs and Os, and many other names, is a pencil-and-paper game for two players, O and X, who take turns marking the spaces in a 3×3 grid, usually X going first. The player who succeeds in placing three respective marks in a horizontal, vertical or diagonal row wins the game.

To simulate the game's board, we will use the following graphic elements that belong to the javax.Swing package that are mentinoned next:

  • Board's spaces are simulated with the use of graphic buttons (javax.swing.JButton) with an associated image (javax.swing.ImageIcon).

    • If the space is free, without having being marked, the button will not have any associated image to it.

    • The space's mark is simulated by associating an image to the button. The image is binded to each player's turn respectively: O and X

      Images are shown next so you can download them:

      Note

      At the time of the initialization of an ImageIcon object with the path to the button's image, make sure that such path is correct so that it could be shown to the user.

  • The board will be modelled as a javax.swing.Jpanel container element, whose associated layout will be java.awt.GridLayout, a 3x3 bidimensional's array.

    • The 3x3 bidimensional's array will be filled in with the previous buttons.

The following image shows the main game's window that is constituted by the following panels (JPanel): an upper panel (panel_info) that contains information about the actual turn's player; a central panel (panel_board) that initially contains the button's array without any associated image, that is, the initial game's board that is ready to start playing:

As player's turns succeed, each player “marks the space" by clicking the corresponding button. To simulate the space's mark, the button's image will be changed according to the symbol of each player as shown at the next figure:

In case of some space could not be marked (for example, if there are no symbols left for the player or if the player's turn is not correct), an error message should be displayed to the player.

Finally, if the player wins the game, a congratulation's message will be displayed as shown in the next figure:

The TicTacToeButton class.

Time30 min

Let's implement the TicTacToeButton class that represents the espace or square each player can mark. To simulate the mark, the button will update its associated image according whether it is free (it has no image) or marked (with the associated image of the turn's player). To achieve that, the class has the following attributes:

  • An integer attribute (turnPlayer) to store the player's turn and it represents the state of the space (square).

  • Three integer constants (FREE, PLAYER_1,PLAYER_2) that indicate the possible states associated to the buttons.

  • An image array (javax.swing.ImageIcon[]) that stores the respective players' symbols: O y X

Download the class skeleton from the following link TicTacToeButton.java and implement the following methods:

  • The class constructor public TicTacToeButton() that initializes the button and let it in free state (FREE), that is, with no player's turn and, therefore, without any associated image to it.

  • The public void setPlayer(int newPlayer) method that updates the button's state with the turn of the new player and its corresponding image.

Test the operation by executing the main class method and passing it, as an argument, any of the three possible button's states (FREE(-1), PLAYER_1(0), PLAYER_2(1)) to see whether the result is correct or not.

The TicTacToe class.

Time20 min

In this chapter, we are not going to program anything, just we pretend to observ how the Tic Tac Toe's main board Graphic Interface has been built. Download the TicTacToe class skeleton from the following link TicTacToe.java and look at the following methods that permit to build the Graphic Interface.

Note

The private void createEventListener() method that implements the Event Management's configuration has been let empty until the next chapter.

  • The private void buildGraphicElements() method initializes all necessary graphic elements to build the Graphic Interface (labels and button's array) and initializes them to free state (FREE), as it has been mentioned previously at the text.

  • The private void addElementsToContainers() method adds respectively the previous graphic elements to their corresponding panels (information and board). Finally, it adds those panels to the Window's main container.

To make the main GUI window visible with the initial state of the game, execute the main methdod of the class. This method just creates, initializes and makes it visible by invoquing those precciding methods.

The TicTacToeButtonListener class.

Time40 min

In this chapter we are going to "revive" the game so that it will be able to interact with the user according to the rule's game. All this is achieved by the implementation of the GUI's “Event Management” that involves, normally, the following tasks:

  1. To decide what kind of graphic components of the Graphic Interface constitute the "Event Source", that is, which components are going to generate events that we will want to treat later. In our case, such graphic components will be the board buttons (JButton) that represent the spaces or squares.

  2. To decide what type of events, from all those components are able to generate, are going to be treated later by the corresponding listener or listeners. In this case, all events that we will treat are from ActionEvent type and that is related to the clicking of the button.

  3. To define the number of Listener classes that are going to react to the previous events. The number of classes is variable, it can be a single class or serveral depending on the strategic design of the Event Management. In this case, we will implement a single listener class, TicTacToeButtonListener, that will be the responsible for the management of every ActionEvent event that is generated when a button is clicked. This is achieved by implemmenting the respective interface (interface) that is associated with that type of event, in our case, the ActionListener interface.

  4. For each graphic element that will acts as an "Event Source" and wants to be treated later by a single or several Listener classes, it is necessary to make a previous registry of it or them at the compoment. In our case, once it has been created an instance object of our Listener class, (TicTacToeButtonListener), this has to be registered on every board's button by the invocation of the public void addActionListener(ActionListener l) method from Component class.

  5. Finally, to implement the Event Listener class, TicTacToeButtonListener, that is, both the constructor and all methods of the interface or interfaces that have to be implemented according to tre previous selected strategy (point 2). The real event management associated to the GUI is realized in these methods.

In relation with the three first points (1. 2. and 3.), all can be summed up in the fact tha the only graphic components that are going to act as event sources will be the board's buttons (JButton). Regarding the distinct types of events that can be treated, only ActionEvent type events will be managed that are generated after the button's clicks. It has been decided to create a single listener class, TicTacToeButtonListener, that will take charge of the management of ActionEvent type events by implemmenting the ActionListener associated interface and, therefore, the following single method of it: public void actionPerformed(ActionEvent event).

In this chapter, we will implement the code of the two last points (4. and 5.).

  • The point 4. is implemented at the private void createEventListener() method of TicTacToe class. It is in charge of the creation and the subsequent registry of the listenter class for each graphic element that generates events, that is, for each button of the board.

    Implement the code of the method in the TicTacToe skeleton class according to what has been specified in the text.

  • The point 5. force us to implement the public void actionPerformed(ActionEvent event) in the TicTacToeButtonListener listener class. In this method is where the true GUI's Event Management is realized. The event is passed as the event parameter to the method.

The flow diagram associated to the public void actionPerformed(ActionEvent event) method is described as follows. It is specific for a "PLAYER_X" player and it represents the program flow that it is realized when such player clicks the button that correspnds to the space he wants to mark. In the flow diagram, basically they are realized three checks before verifying whether the player has won the game:

  • First, it is checked whether the player has enough free symbols to mark the space (remember, the player owns only three symbols to use).

    • In case of affirmative answer, it is checked whether the space is free (FREE) or not and, in that case, a message error should be displayed to the player.

    • In case of negative answer, it is checked whether the actual turn belongs to the "PLAYER_X" player or not and, in that case, a message error should be displayed to the player.

Note

To show a Dialog's Window with an user's error message, you can use the static showMessageDialog method from the javax.swing.JOptionPane class.

Homework Section2.  Homework

Time180 min

Exercise Section2.1.  Event Management in GUIs II - (Time Counter)

Time180 min

To improve our knowledge about the Java Event Management model, we are going to propose the following exercise to do at home. We will be based on the TicTacToe GUI's code that we have programmed at the laboratory's session and we are going to add a new functionality that will permit to control the remaining turn's time for each player of the game. That's why we are going to incorporate a new component that is provided by the Java's graphics library (javax.swing) that acts as a "timer".

The component we are talking about is implemmented at the javax.swing.Timer class and, basically, it generates ActionEvent events periodically at constant intervals that can be configured previously. The way these events are managed by the component is seamlessly integrated on the Java's general "Event Delegated Management Model" that, let's remember, is based on the presence of three kinds of objects:

  • A set of Event Sources that generate events of a certain type as a consequence from user actions when interacting with them.

  • A set of Events that can be organised in a class hiereachy according to the stored information and the distinct origin of them. For example, ActionEvent type for user actions over a component; MouseEvent type for mouse movements; KeyEvent type for key strokes, etc..

  • A set of Listeners that react to of events that are generated by the precciding event sources according to the distinct types of events they are subscribed to. For that, they must implement the associated interface for the type of the event they want to manage: ActionListenter for ActionEvent events; MouseListenter for MouseEvent events; etc....

This model has many advantages: is understandable, flexible, extensible and robust. A good proof of this is how easy will result to add aditional Event Management logic code to our TicTacToe's GUI. To achieve that, let's make the corresponding Event Management analogy associated to the component that we are going to incorporate to the application:

  • The Source of Events will be the Timer component (javax.swing.Timer)

  • The Event type that is going to be generated and treated next is ActionEvent.

  • The Listener class (TimeListener), has to implement the associated interface of the Event's type: ActionListener.

The following image shows the initial window where the label with the player turn's time remaining information is located at the upper information's panel (10 seconds for this game).

The time counter starts discounting seconds until the player turn's time is over, in that case, a Dialog Window is shown with the corresponding error message to the user.

After the user has clicked the Accept button, the player's turn is changed and the time's counter is reset to the initial value, after that, it will start discounting seconds again.

Starting from the previous laboratory TicTacToe exericse's code you have implemented, make the following tasks to be able to incorporate the time counter to it:

  • Add the following attributes to the TicTacToe class that will be necessary to integrate the time counter:

    • A label (JLabel) that contains the text wiht the information of the remaining turn's time.

    • An integer constant (final static int) that represents the maximum turn's time.

    • A Timer reference (javax.swing.Timer) that will be the time counter.

  • Implement the TimeListener class that acts as a Listener class for the time counter's events.

    • Add a class attribute that should be a reference to the main window's game (JFrame) and it will be initialized at the class constructor.

    • Add another integer static attribute that will store the remaining number of seconds of the player's turn.

    • Implement the public void actionPerformed(ActionEvent event) method that will be executed periodically by the Timer's object. Such method will decrement the seconds counter and, in the case this value reaches to cero, it will show the corresponding error message to the uses. Finally, it will change the player's turn.

  • Create a Timer object's instance at the TicTacToe's constructor so that, it is started discounting the remainig turn's time from that moment.

    • As a constructor's argument, pass a TimeListener object's reference to it that has to be initialized with a window game's reference, that is, with this

  • Finally, update the method that serves to change the player's turn, public void changeTurn(), so that it should set the TimeListener second's static counter to cero. The counter will, therefore, start discounting the new player turn's remaining time.