Sunday, 7 September 2014

Basic GUI Programming

Basic GUI Programming

1. From the beginning

To this point, you have seen only how to write programs that take input from the keyboard, fuss with it, and then display the results on a console screen. However most modern programs don’t work this way. This topic starts you on the road to writing Java programs that use a graphical user interface (GUI).
 
You will learn how to write programs that size and locate windows on the screen, display text with multiple fonts in a window, display images, and so on. 
All the jobs we are going to do will be supported by either AWT (Abstract Windows Toolkit) or Swing. Please refer to Section 12.2 for the difference between AWT and Swing.

1.1 What are the components?

Almost everything on windows GUI is called a Component in Java. For example, the text book lists several kind of common components you will meet, like JButton (buttons), JTextField (text areas) etc., even a window is a Component instance. To build a user interface, you need to create all kinds of components and put them together. This topic will teach you how to organize components. Later on we will learn how to create components. 

1.2  Creating a frame 

A window is usually called a frame in Java GUI programming. O course it is a component in Java terminology. A frame is used to hold everything that you want to display on the window. Before you present any components like a text, an image to users, you need to create a frame for holding those components. Frames can be created by using the JFrame class of the Swing. Read the following code first. 
import javax.swing.*;
 
public class TestFrame {
      public static void main( String[] argv ) {
          
           JFrame myframe = new JFrame("My First Frame");
            
           myframe.setSize(400, 300);
           myframe.setLocation(0,0);
           myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
           myframe.setVisible(true);
    }
 
I suggest you should play with this simple program if you don’t have any experience in Java GUI programming.
 
First, you may note the statement of a calling to the setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
method. This statement is very important. It means that when a user click on the close label on the frame(or window), the program should terminate.  
 
Second, change the size (400, 300) to different amount and see how the window changes.
 
Third, change the location (0, 0) to other values and see how the window changes.
 
Forth, change the visible value true to false and see what will happen.
After this I bid you will have understood the meaning of all the statements.   

1.3 Positioning a frame 

There are two ways to locate a JFrame on the screen. The first way is to use the setLocation(int x, int y) as you have seen in the TestFrame.java where (x,y) is the coordinates of the upper-left-corner location of the frame with respect the screen. Since JDK 1.4, you can use the setLocationRelativeTo(Component C) method to locate your JFrame relative to the specified component C. If C is null (i.e., no specified component) then the JFrame will be centered at the screen. Try the TestFrame.java again by replacing
                 myframe.setLocation(0,0);
with
                myframe.setLocationRelativeTo(null);

1.4 Adding a compnent to a frame

JFrame behaves like any windows you are familiar with. It holds all kinds of components like menu bars, labels and buttons. In Java you will use a consistent way to add all kind of components onto a JFrame. After you create an object of Component, you simply use theadd method to add the component onto your frame. Read the following program
import javax.swing.*;
 
public class TestFrameWithComponent {
      public static void main( String[] argv ) {
          
           JFrame myframe = new MyFrame();
          
           JButton firstBtn = new JButton("First Button");
           //Create a new button - a component
          
           myframe.add(firstBtn);
                     
           myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
           myframe.setVisible(true);
    }
}
 
class MyFrame extends JFrame
{
      public MyFrame(){
            setTitle("Frame with Components");
            setSize(400, 300);
            setLocationRelativeTo(null);
      }
}
 
There are several new features in the above program. First we extended the JFrame to a new class MyFrame and then in main we create an instance of this class, i.e., a new frame. This is a style we should follow. Always extend the JFrame and then initialize specification like title, size etc in the constructor. In the main method, you create a MyFrame instance with the constructor. Second, the statement
 
JButton firstBtn = new JButton("First Button");
 
is used to create a JButton and then it is added onto the newly created frame.

2. Layout managers

If you have tried the program TestFrameWithComponent.java, you would have seen that the button added occupies the entireJFrame’s pane area. What should we do if we want the button placed on the upper-left corner of the pane area? Java uses layout managers to provide a level of abstraction that automatically arranges your user interface.
There are three basic layout managers: FlowLayoutGridLayout and BorderLayout. They are defined in AWT. A default layout manager is the BorderLayout.
 
A layout manager is created using a layout manager class, then it is set in a container. A Container is a component which can hold other components. For example, a JFrame is a container, so you can set a layout manager for a JFrame. More details about container, please consult to the inheritance structure shown in Figure 12.1 of the text book.

2.1 FlowLayout

FlowLayout is the simplest layout manager. The components are arranged in the container from left to right in the order in which they are added. When one row is filled, a new row is started.
Please test the program in Listing 12.3 in the following way:
  1. Compile and run the program as it is. When the frame appears on the screen, resize the frame to different sizes with your mouse and see how six components move on the frame. Or you can set different size value in the setSize method in the program.
       
  2. Change FlowLayout.LEFT to FlowLayout.CENTER and FlowLayout.RIGHT respectively, compile and run the program again. Observe what has changed.
       
  3. In the new FlayLayout(FlowLayout.LEFT, 10, 20)), change 10, 20 to different values such as 0, 0;  5, 30; etc and observe what has changed.
       
  4. Change “First Name” to a longer string like “First Name (in Capital Letter)” and then observe what will happen.
Now have you understood how the FlowLayout manager works?

2.2 GridLayout

The GridLayout manager arranges all components in rows and columns like a spreadsheet. Cells are always the same size. In the constructor of the GridLayout class, you specify how many rows and columns you need and also you can specify the vertical and horizontal gaps you want.
You add the components, starting with the first cell in the first row, then the second cell in the first row, and so on.
The entire grid will occupy the container’s area.
Test the program in Listing 12.4 in the following way:
  1. Compile and run the program and then resize the frame to see what will happen.
      
  2. Change the number of rows to 2, ie., try to make a 2x2 grid with six components. What had happened?
       
  3. Set the number of rows to 0 or columns to 0 and observe what happens.

2.3  BorderLayout

The BorderLayout divide a container (e.g. a frame) into five areas: East, South, West, North and Center, as shown in the following figure.
The components are added to a container with a BorderLayout by using
add(Component, index)
where the index is one of the constants BorderLayout.EAST, BorderLayout.SOUTH, BorderLayout.WEST, BorderLayout.NORTH and BorderLayout.CENTER.
Generally speaking, on a container with a BorderLayout you can only add up to five components. For example if you add the second component to the East area, then the first East component will be replaced by the new one. If you don’t add a component to an area, then the area is simply set to zero (missing from the container).

Note the BorderLayout is the default layout for a container. In this case add(Component) is equivalent to add(Component, BorderLayout.CENTER).
See Section 12.5.3.

3. Using colors

The Color class from AWT is one of helper classes to the GUI. With the color class you can define a color for your displaying text, drawing or components etc. For example, you can set a particular color to the background/foreground of a component with the methodsetBackground/setForeground.
Two ways to choose a color:
  1. Use one of the thirteen standard color names like Color.BLACK, Color.BLUE,  Color.RED etc.
  2. Use the Color constructor to define a color with RGB values (between 0 and 255).

4. Using fonts

The Font class from AWT provides you a way to choose a font available on the system. The Font constructor is
Font(String FontName, int Style, int Size);
There are several pre-defined style constants like Font.PLAIN, Font.BOLD, Font.ITALIC and Font.BOLD+Font.ITALIC.
Check the following program
import javax.swing.*;
import java.awt.*;
public class TestColorFont {
public static void main( String[] argv ) {

JFrame myframe = new ShowFlowLayout();

myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myframe.setVisible(true);
}
}
class ShowFlowLayout extends JFrame
{
public ShowFlowLayout(){

setLayout(new GridLayout(1, 3, 5, 5));
JButton btn = new JButton("12");
btn.setBackground(Color.WHITE);
btn.setForeground(Color.RED);
btn.setFont(new Font("TimesRoman",Font.BOLD, 20));
add(btn);

JButton btn1 = new JButton("23");
btn1.setBackground(new Color(21, 128, 73));
btn1.setForeground(Color.YELLOW);
btn1.setFont(new Font("TimesRoman",Font.BOLD, 40));
add(btn1);

btn = new JButton("HONGKONG");

btn.setFont(new Font("Monospaced",Font.PLAIN, 20));
add(btn);

setTitle("Colors and Fonts");
setSize(400, 400);
setLocationRelativeTo(null);
}
}

5.  Why panels?

For a container you only have one of three choices from FlowLayout, GridLayout and BorderLayout. However I want you to create the following layout, what can you do with the three layouts?








To use three basic layout managers to arrange components in a fancy and complicated layout, Java comes up with the concept of Panel. A panel is also a container in which you can set a layout manager and put components into it and the panel itself as a component can be added into another container or panel just like a normal component.
For example the above layout can be broken down in this way

Consider two shadowed area as new components (two panels) P1 and P2. They can be arranged by a 1x2 GridLayout manager or simply by the FlowLayout manager.
Then look at the right panel (considered as a container), denoted by P2, the three components in it can be organized by theBorderLayout without center and south areas.
For the left panel, denoted by P1, I would like to see it as a 1x2 grid with two components P3 and P4 as shown below. Both P3 and P4 are panels.
Obviously the left panel P3 can be considered as a flow layout or a border layout (is a 2x1 grid layout possible?) and P4 3x1 grid layout.
The construction method is
First construct the first Panel P3 managed by a FlowLayout and the second Panel P4 managed by a 3x1 grid layout. As components add them into another Panel P1 which is managed by a 1x2 grid layout. Finally add P1 and P2 into a frame managed by a 1x2 GridLayout manager. Then we have obtained what we want. The code for this layout is in 5.2.

5.1 Creating a panel

Creating a panel is very simple. Use the following template.
JPanel p = new JPanel();
p.setLayout(new GridLayout(2,3));
p.add(new JButton(“Button One”));

5.2 Example

Read the following code
import javax.swing.*;
import java.awt.*;
public class TestPanels {
public static void main( String[] argv ) {

JFrame myframe = new ShowPanels();

myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myframe.setVisible(true);
}
}
class ShowPanels extends JFrame
{
public ShowPanels(){

//Making panel P3
JPanel p3 = new JPanel();
p3.setLayout(new BorderLayout(5,5));
JButton btn1 = new JButton("Button1");
btn1.setPreferredSize(new Dimension(75,50));
p3.add(btn1,BorderLayout.NORTH);
JButton btn2 = new JButton("Button2");
btn2.setPreferredSize(new Dimension(75,100));
p3.add(btn2,BorderLayout.SOUTH);
            //Making panel P4
JPanel p4 = new JPanel();
p4.setLayout(new GridLayout(3,1,5,5));
JButton btn3 = new JButton("Button3");
btn3.setPreferredSize(new Dimension(75,50));
JButton btn4 = new JButton("Button4");
btn4.setPreferredSize(new Dimension(75,50));
JButton btn5 = new JButton("Button5");
btn5.setPreferredSize(new Dimension(75,50));
p4.add(btn3);
p4.add(btn4);
p4.add(btn5);

//making panel p1
JPanel p1 = new JPanel();
p1.setLayout(new GridLayout(1,2, 5, 5));
p1.add(p3);
p1.add(p4);

//making panel p2
JPanel p2 = new JPanel();
p2.setLayout(new BorderLayout(5, 5));
JButton btn6 = new JButton("Button6");
btn6.setPreferredSize(new Dimension(150,100));
JButton btn7 = new JButton("Button7");
btn7.setPreferredSize(new Dimension(75,50));
JButton btn8 = new JButton("Button8");
btn8.setPreferredSize(new Dimension(75,50));
p2.add(btn6, BorderLayout.NORTH);
p2.add(btn7, BorderLayout.WEST);
p2.add(btn8, BorderLayout.EAST);

//Making the frame
setLayout(new GridLayout(1,2, 5,5));
add(p1);
add(p2);
setTitle("Frame with Components");
setSize(320, 190);
setLocationRelativeTo(null);
}
}

6. Common features

All Swing GUI components are subclasses of JComponent. JComponent offers common methods to manipulate its instances. For example, you can decorate your JComponent with a surrounding border by using setBorder method. You have seen that the setForeground method sets the foreground color for a component. Please read the example in Listing 12.7 of the text book.
Even you can create an image button or image lable with an image icon. The steps are (1) create an image icon object with an image file; (2) create a button or label with the image icon as a parameter to the constructor of a button or a label.
Please try the example in Listing 12.8 of the text book.

6. Check Boxes and Radio Buttons

Some other common components you might like are check boxes and (mutually exclusive) radio buttons. Some example code that uses them is shown below:
JCheckBox myCheck = new JCheckBox("Student", true);
JCheckBox myCheck2 = new JCheckBox("Teacher", false);

JRadioButton myRadio = new JRadioButton("Student", true);
JRadioButton myRadio2 = new JRadioButton("Teacher", false);

ButtonGroup myGroup = new ButtonGroup();
myGroup.add(myRadio);
myGroup.add(myRadio2);

Use a ButtonGroup to make the radio buttons no longer independent of each other.

No comments:

Post a Comment