Graphics

Document Sample
Graphics Powered By Docstoc
					Simple user interfaces

Liang, Chapter 10 (some parts)
Liang Chapter 11 (some parts)
           Jframes : user interfaces
Next we‟re going to learn how to get java to create more
complicated JFrames for input and output. These can contain
larger text areas, multiple buttons, choice buttons, graphics, etc.
These are a type of GUI (Graphical User Interface).


In describing Jframes I‟m going to use sections of Liang chapter
10 and chapter 11. I‟ll skip bits of these chapters, though.
            Parts of a JFrame
 This is a Jframe. It is a            Every JFrame contains a
 window with various user             contentPane, which is a
 interface components.                Container holding all of the
                                      contents of the JFrame
                                   _ _
 Test frame
                                              The contentPane can
 This is a text area
                                              hold JComponents
 with multiple lines                          such as JMenu,
                                              JTextArea,
 in it
                                              JCheckBox,
                                              JRadioButton,
                                              JButton etc..
   submit   clear        male      female      The contentPane
                                               may contain JPanels,
A Jpanel containing two JButtons               with each panel
and two JCheckBoxs                             containing a subgroup of
                                               JComponents.
    Example Jframe (see Liang 10.3.1)
import javax.swing.*; // JFrame is a swing class

public class MyFrame{
 public static void main(String[] args){
   JFrame frame = new JFrame("my first JFrame");
   frame.setSize(400,300); // size of frame in pixels
   frame.setVisible(true);   // make the frame appear
                             // on the screen
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 }
}

There‟s no System.exit() here. Instead, this line tells the MyFrame
program to exit when the frame window is closed by the user. You just have to
include this to get the program to end properly.
This program does nothing but display an empty Jframe.
Screen coordinates go from upper
          left corner.
                 X

       (0,0)              (600,0)



  Y




       (0,400)           (600,400)
      Placing a JFrame at a location
import javax.swing.*;                          // JFrame is a swing class

public class MyFrame{
 public static void main(String[] args){
   JFrame frame = new JFrame("my first JFrame");
   frame.setSize(400,300);                      // size of frame in pixels
   frame.setLocation(300,300); // location of upper-left corner
                                                // of frame on screen (in pixels)
   frame.setVisible(true);                      // make the frame appear
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 }
}
  Liang 10.3.1 gives code for getting the size of the screen and using
  setLocation to place the frame in the center of the screen.

   (Click here to download this program)
   JFrame with a component (10.3.3)
To add an interface component to a frame (like a JRadioButton, a JButton, a
 JTextArea,etc), we have to get the ContentPane of the frame and add the
 component to that ContentPane.

A ContentPane is a Container. We can add a component using the
Container class, like this:
    Jbutton myButton = new JButton("hello!");
    Container content = frame.getContentPane();
    content.add(myButton);
Or, more compressed:
    Container content = frame.getContentPane();
    content.add(new JButton("hello!"));
Or even more compressed:
    frame.getContentPane().add(new JButton.("hello!"));

 Container is a class from the package java.awt.*. We have to import
 java.awt.* to use Container .
    JFrame with a component (10.3.3)
import javax.swing.*; // JFrame is a swing class
import java.awt.*;    // awt to use the Container class
                      // it‟s „java‟ not „javax‟!

public class MyFrame{
 public static void main(String[] args){
   JFrame frame = new JFrame("my first JFrame");
   frame.setSize(400,300);
     Container content = frame.getContentPane();
     content.add(new JButton("hello!"));
     frame.setVisible(true);
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     }
}

    This creates a frame with a single big button in it, saying “hello!”
 A JCheckBox component (download here)
import javax.swing.*; // JFrame is a swing class
import java.awt.*;    // to use the Container class
                      // it‟s „java‟ not „javax‟!

public class MyJCheckBoxFrame{
 public static void main(String[] args){
   JFrame frame = new JFrame("my JCheckBox JFrame");
   frame.setSize(400,300);
     Container content = frame.getContentPane();
     content.add(new JCheckBox("check this", true));
     frame.setVisible(true);
     frame.setDefaultCloseOperation(JFrame.                EXIT_ON_CLOSE);
 }
}
  “new JCheckBox(“check this”, true));” creates a JCheckBox with
  the box already checked (that‟s what the „true‟ means)
A JTextArea component (liang 11.6)
import javax.swing.*; // JFrame is a swing class
import java.awt.*;    // to use the Container class
                      // it‟s „java‟ not „javax‟!

public class MyJTextAreaFrame{
 public static void main(String[] args){
   JFrame frame = new JFrame("my JTextArea JFrame");
   frame.setSize(400,300);
     Container content = frame.getContentPane();
     content.add(new JTextArea(4,25));
     frame.setVisible(true);
     frame.setDefaultCloseOperation(JFrame.                      EXIT_ON_CLOSE);
 }
}
  “new JTextArea(4,25));” creates a JTextArea object that is 4
  characters (or lines) high and 25 characters across (for the user to type in).
More than one component in a JFrame.
• The programs we‟ve seen so far just put one component into a
  JFrame. We usually want more than one component.
• If we have more than one component in a JFrame, we have to
  organise their layout.
• We set a layout manager object for the contentPane.
• There are different predefined layout managers:
   – flowLayout()        places components left to right in the order they were added
   – gridLayout(int rows, int columns) defines a grid of rows*columns locations
   – borderLayout() has five locations, north south east west center. This is the
     default layout manager in contentPane objects.


• When we add multiple components to the contentPane, they are
  placed in position by the layout manager we have placed in the
  contentPane. If we put different layout manager objects in, we
  will get different layouts.
Creating and setting a LayoutManager
import javax.swing.*;
import java.awt.*;

public class MyFlowFrame{
 public static void main(String[] args){
   JFrame frame = new JFrame("my flowLayout JFrame");
   frame.setSize(400,300);
   Container content = frame.getContentPane();
   content.setLayout(new FlowLayout());
   for(int i=0; i<20; i++){
      content.add(new JCheckBox("check " + i));
    }
   frame.setVisible(true);
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 }
} We could use new flowLayout(5,5) , which would put 5 pixel spaces between
   components, new flowLayout(FlowLayout.LEFT) which would align
   components to the left, or new flowLayout(FlowLayout.LEFT,5,5) to do both
Setting a gridLayout manager (download here)
  import javax.swing.*;
  import java.awt.*;
  public class MyGridFrame{
   public static void main(String[] args){
      JFrame frame = new JFrame("my gridLayout JFrame");
      frame.setSize(400,300);
      Container content = frame.getContentPane();
      content.setLayout(new GridLayout(10,2));
      for(int i=0; i<20; i++){
         content.add(new JCheckBox("check " + i));
       }
      frame.setVisible(true);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   }
  } new GridLayout(10,2)creates a layout manager object that puts components in a
   grid 10 rows down, 2 columns across. We could use new GridLayout(10,2,5,5),
   which would create a 10 by 2 grid with 5 pixel spaces between components
     Playing with LayoutManagers
Notice that things are placed in the layout according to the
order in which they were added to the contentPane.
In these examples, I added things using a loop. This is just for
demonstration purposes!
I also added the same thing each time. Again, this is just for
demonstration: you can add any type of JComponent.

 •   Experiment with these 3 Layout Managers
 •   For each, observe effects of resizing the window
 •   For each, explore arguments to the constructor
 •   To avoid surprises, always explicitly set a LayoutManager
 •   Expect surprises and trial and error
1 JTextArea and 4 JButtons (download here)
import javax.swing.*;
import java.awt.*;

public class MyFourButtonFrame{
  public static void main(String[] args){
    JFrame frame = new JFrame("my first JFrame");
    frame.setSize(400,300);
    Container content = frame.getContentPane();
    content.setLayout(new BorderLayout());
    content.add(new JTextArea(4,25),BorderLayout.CENTER);
    content.add(new JButton("North"), BorderLayout.NORTH);
    content.add(new JButton("South"), BorderLayout.SOUTH);
    content.add(new JButton("West"), BorderLayout.WEST);
    content.add(new JButton("East"), BorderLayout.EAST);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame. EXIT_ON_CLOSE);
  }       A BorderLayout Jframe has 5 specified locations:
}         BorderLayout.CENTER,NORTH,SOUTH EAST WEST
MyGridFrame extends Jframe                            (download here)
import javax.swing.*;
import java.awt.*;
class MyGridFrame extends JFrame{
  MyGridFrame(){                             // constructor
    super("my gridLayout JFrame");           // superclass constructor
    Container content = this.getContentPane();
    content.setLayout(new GridLayout(10,2));
    for(int i=0; i<20; i++)
        { content.add(new JCheckBox("check " + i));         }
   this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }
}
class testGridFrame{
   public static void main(String[] args) {
     MyGridFrame frame = new MyGridFrame(); // make a MyGridFrame
     frame.setSize(400,300);                     // set the size
     frame.setVisible(true);                     // make it visible
   }
} Notice that the MyGridFrame object has methods setSize and
  setVisible: it inherits them from JFrame
Liangs FlowLayout example (page 386)
import javax.swing.*;
import java.awt.*;
public class ShowFlowLayout extends Jframe{
  public ShowFlowLayout(){
    Container container = getContentFrame();
    container.setLayout(new FlowLayout(FlowLayout.LEFT,10,20);
    for (int i = 1; i <= 10; i++){
        container.add(new Jbutton("Component "+i));
    }
  }

    public static void main(String[] args){
      ShowFlowLayout frame = new ShowFlowLayout();
      frame.setTitle("show flow layout");
      frame.setDefaultCloseOperation(Jframe.EXIT_ON_CLOSE);
      frame.setSize(400,300);
      frame.setVisible(true);
    }
}     In this example, the main method is inside the ShowFlowLayout
      class, rather than there being a separate test class.
                  Class JPanel
• Most interfaces combine several kinds of component:
   –   text boxes
   –   messages
   –   check buttons
   –   clickable buttons
   –   menus
   –   graphics
• Often we want to group some of these together, for
  layout reasons.
• Interface components are grouped within JPanels
• JPanel comes from javax.swing
            Example using JPanel
 This is a Jframe. It is a            Every JFrame contains a
 window with various user             contentPane, which is a
 interface components.                Container holding all of the
                                      contents of the JFrame
                                   _ _
 Test frame
                                              The contentPane
 This is a text area
                                              contains JComponents
 with multiple lines                          such as JMenu,
                                              JTextArea,
 in it
                                              JCheckBox,
                                              JRadioButton,
                                              JButton etc..
   submit   clear        male      female      The contentPane
                                               may contain JPanels,
A Jpanel containing two JButtons               with each panel
and two JCheckBoxs                             containing a subgroup of
                                               JComponents.
import javax.swing.*;          // (download here)
import java.awt.*;
class MyFrame extends JFrame{
 MyFrame(){
   super("JFrame with button and checkbox panel");
   JPanel myPanel = new JPanel();               // create panel
   myPanel.setLayout(new GridLayout(0,4));      // set layout of panel
   myPanel.add(new JButton("submit"));          // add button to panel
   myPanel.add(new JButton("clear"));           // add another button
   myPanel.add(new JCheckBox("male", true));    // add checkbox to panel
   myPanel.add(new JCheckBox("female", false)); // another checkbox
   Container content = this.getContentPane();
   content.setLayout(new BorderLayout());
   content.add(new JTextArea(16,25),BorderLayout.CENTER);
   content.add(myPanel,BorderLayout.SOUTH);    // add panel to frame
   this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
class testMyFrame{                                 In this example, Jframe
  public static void main(String[] args) {         has two components: a
    MyFrame frame= new MyFrame();                  JTextArea, and the
    frame.setSize(300,200);                        JPanel, which itself
    frame.setVisible(true);                        contains JButtons
        }                                          and JCheckBoxes
   Putting messages in JPanels (liang 10.6)
The things we‟ve put in JPanels so far are interface components like
JButtons and JCheckBoxes. How do those things actually get onto the
screen? Jpanel has a method called
public void paintComponent(Graphics g)
which is called whenever a JPanel object is to be “painted” onto the screen. This
is given a Graphics object g by the Java system, which represents the bit of
screen where the JPanel is to be drawn. Every JPanel paints its interface
components onto the screen using this Graphics object g.
We don‟t care what goes on inside the paintComponent method. However, if
we want to put messages, or draw pictures, into our JPanels, we need to override
the paintComponent method (redefine the method so that it draws what we want
onto the screen). We use methods in Graphic object g for this:
g.drawString(“Hello”,x,y); // draws string “hello” at location x, y in the bit of
                           // screen represented by Graphics object g
       Extending JPanel and overriding
paintComponent() to draw a message on a panel
import javax.swing.*;
import java.awt.*;

class MyMessageJPanel extends JPanel{
  String message;                     // message contents for panel
  int xlocation,ylocation;            // message location in panel

    MyMessageJPanel(String msg, int x, int y){ // constructor
      super();                      // call constructor for superclass JPanel first
      message = msg;
      xlocation = x;      This paintComponent method is called whenever
      ylocation = y;      a Jpanel is painted on the screen. We‟ve changed it
    }
                                so it draws our message whenever it‟s called.
    public void paintComponent(Graphics g){ // override paintComponent
      super.paintComponent(g);
                      // first do whatever paintComponent in JPanel always does
      g.drawString(message,xlocation,ylocation);
    }               // next use the drawString method to draw our message in the JPanel
}
               Using our extended JMessagePanel
class MyMessageJFrame extends JFrame{
    MyMessageJFrame(){                  // constructor for MyMessageJFrame
      super("JFrame with MyMessageJPanel");
      MyMessageJPanel messagePanel;
      messagePanel = new MyMessageJPanel("Hello world!",50,50);
                                 // create a MyMessageJPanel object that
                                 // draws "hello world!" at location 50, 50
      Container content = this.getContentPane();
      content.setLayout(new BorderLayout(15,15));
      content.add(messagePanel,BorderLayout.CENTER);
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

class testMyFrame{               // class to test out these classes
  public static void main(String[] args) {
    MyMessageJFrame frame= new MyMessageJFrame();
    frame.setSize(300,300);
    frame.setVisible(true);
        }
}           When the MyMessageJPanel object is painted on the screen, our overridden
            paintComponent method will draw the message we gave to the constructor.
        Noticing events: A Button Click
• A JFrame contains a JButton
• To respond when the JButton is clicked, we create an actionListener
  object to listen for the action of that JButton being clicked.
• That actionListener object must contain a method called
•   public void ActionPerformed(ActionEvent e)
• The actionListener object registers with the Jbutton.
• Thereafter, whenever the JButton is clicked, it calls the
  actionPerformed(ActionEvent e) method in the listener.
• The actionPerformed (ActionEvent e) method does whatever we
  want to happen when the button is clicked.
Listener registers
with JButton                    myActionListener {
                                  actionPerformed(ActionEvent e){
                                   JOptionPane.showMessageDialog(“Button click!”);
                     event e:     }
       count
                     Click      }                            JOptionPane
                                                              Button Clicked!
   Registering a listener object with a source
                   (a Jbutton)
JButton myCountButton = new JButton(“count");
myCountListener listener = new myCountListener();
myCountButton.addListener(listener);


This snippet of code creates a JButton object, then creates a
myCountListener object, the registers that listener with that button (adds
the listener object as a listener to the button).
This registration step creates the link between the button and the listener: after
this step, when the button is clicked, the actionPerformed() method in
the listener object will be executed.
Next: putting it all together.
         Making the JFrame class
       implement ActionListener
• Any class at all can implement ActionListener, if it provides the
  actionPerformed() method.
• Its most useful to make the class that draws our windows (our
  JFrames) also implement ActionListener, so that objects from that
  clss not only draw buttons but can respond to events on those
  buttons.
• To do this we change our myButtonJFrame class so that it proves an
  actionPerformed() method as well as constructing the JFrame object.
• I‟ll call this new class EventButtonJFrame
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;                                         // we need event classes

class EventButtonJFrame extends Jframe implements ActionListener{
 JTextArea myTextArea = new JTextArea(6,30),
 JButton myCountButton = new JButton("Count");         // make button
 JPanel buttonPanel = new JPanel();
 EventButtonJFrame (){                                             // constructor
   super(“myButtonJFrame");
   myCountButton.addActionListener(this);               // register this class as the listener
                                                        // for myCountButton
        buttonPanel.setLayout(new GridLayout(4,0));
        buttonPanel.add(myCountButton);                   // add button to panel
        Container content = this.getContentPane();
        content.setLayout(new BorderLayout());
        content.add(myTextArea,BorderLayout.CENTER);
        content.add(buttonPanel, BorderLayout.EAST);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }


    public void actionPerformed(ActionEvent e) {
          JOptionPane.showMessageDialog(null,”Count button clicked!");
          }

}
              Doing something useful
The actionPerformed method in the previous programs doesn‟t really do
anything useful.
To get that method to do something useful, we could, for example, give it access
to the JTextArea object created in our JFrame window.
To do this, we will
1) Make the JTextArea object a generally accessible variable in the
Jframe object. To do this, we put
JTextArea myTextArea = new JTextArea("this is a text area",6,30);
at the top of the EventButtonJFrame class definition.
2) Refer to the text in that JtextArea object in the actionPerformed
method, so that when our count button is clicked, we can return some useful
information.
We can get the text inside the JTextArea object by saying
myTextArea.getText();
(we can change that text by saying something like:
myTextArea.setText(“this is the new text”);
import javax.swing.*;                                         Download from here
import java.awt.*;
import java.awt.event.*;                                    // we need event classes
class EventButtonJFrame extends JFrame implements ActionListener{
 JTextArea myTextArea = new JTextArea("this is a text area",6,30);
 JButton myCountButton = new JButton("count");   // create button
 JPanel buttonPanel = new JPanel();
 EventButtonJFrame (){
    super("myButtonJFrame");
    myCountButton.addActionListener(this);          // add listener
    buttonPanel.setLayout(new GridLayout(4,0));
    buttonPanel.add(myCountButton);                // add button
    Container content = this.getContentPane();
    content.setLayout(new BorderLayout());
    content.add(myTextArea,BorderLayout.CENTER);    // add text area
    content.add(buttonPanel, BorderLayout.EAST);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }
    public void actionPerformed(ActionEvent e) {
        JOptionPane.showMessageDialog(null, “The number of characters in
JTextArea is "+myTextArea.getText().length() );
  }
}
            Whenever the count button is clicked, we get a message telling us
            how many characters are currently in myTextArea.
// continued…

class testEventButtonJFrame {
  public static void main(String[] args) {
    EventButtonJFrame frame = new EventButtonJFrame();
    frame.setSize(300,200);
    frame.setLocation(300,330);
    frame.setVisible(true);

    }
}
This program will respond to a click on the count button by popping
up a text message telling the user how many characters are currently
entered in the JTextArea of the EventButtonJFrame object.
Note that for this program to compile and run properly, it must be in
a file called testEventButtonJFrame.java. This is because
the class with the main method (the one that will actually run) is the
testEventButtonJFrame class.
  A listener with two buttons (download here)
If we want our actionListener to respond to more than 1 button,
we have to change the actionPerformed method so that it checks
which button was source of the current event. We do this as follows:
Declare the two buttons as class-level variables; at top of the class, put:
 JButton myCountButton = new JButton("count");
 JButton myClearButton = new JButton("clear");

In the constructor for the class, register both buttons with the listener
(and add each button to the JPanel as required):
myCountButton.addActionListener(this);
myClearButton.addActionListener(this);

In the actionPerformed method, check which button was the source of
the current ActionEvent e, and respond accordingly:
 if (e.getSource().equals(myCountButton)) {…do whatever}
 if (e.getSource().equals(myClearButton)) {…do whatever}
  Colors, fonts, and drawing graphics
There are lots of other things we can do with JPanels: change colors, set font
sizes, etc. See Liang 10.7 and 10.5, and example 10.5, for details of these. I‟ll leave
them to you to read over.
We have extended JPanel to MyMessageJPanel and used g.drawString()
to draw a string (a message) in the panel.
We can use a similar approach to draw graphics in a panel, using the predefined
graphics methods g.drawline(), g.drawRect(), g.drawOval() and so on. To
use these we extend JPanel to JRectPanel, for example, and in JRectPanel
override paintComponent() as follows:

public void paintComponent(Graphics g){ // override paintComponent
    super.paintComponent(g);
                     // first do whatever paintComponent in JPanel always does
    g.drawRect(x,y,width,height);
  }            // draw a rectangle at x,y with the given width and height
                          Using the API
There are a lot of details in the javax.swing and java.awt classes I‟ve
discussed here. I haven‟t mentioned most of the abilities of these classes.
You should look these classes up in the API:
http://java.sun.com/j2se/ (click on „API specifications‟ under „reference‟, and
then pick the edition of J2SE you are using: currently probably 1.4.2).
You should look up
javax.swing
and within that look up the classes JFrame, JPanel, JComponent,
JDialog and see the methods that are listed. In JComponent you will see
subclasses such as JTextField, JTextArea, Jbutton,
JRadioButton, JCheckBox and so on. The API explains all of the abilites
of objects in these classes and how they are used.
Within javax.awt you will find the layout managers and various other useful
classes of objects.
                         Conclusion
• GUI construction and control is not complicated, but there are loads
  of details involved.
• You don‟t need to know all these details: my aim has been to give a
  general idea of what goes on in GUI construction and in event-driven
  programming.
• If you‟re interested, you can look up the various classes discussed
  here in the Java API:
•    http://java.sun.com/j2se/ (click on „API specifications‟ under
  „reference‟, and then pick the edition of J2SE you are using:
  currently probably 1.5.0 ).
•   There are very useful tutorials on JFrame use, event-driven
  programming and other aspects of Java programming in the API.

				
DOCUMENT INFO