The Abstract Window Toolkit provides many classes for programmers to use. It is your connection between your application and the native GUI. The AWT hides you from the underlying details of the GUI your application will be running on and thus is at very high level of abstraction. It takes the lowest common denominator approach to retain portability. No floating toolbars or Balloon help here...
It is a Java package and can be used in any Java program by importing java.awt.* via the import keyword. The documentation for the package is available at the Java hompage. The package will be covered briefly and this document is not considered advanced material as it does not discuss Peers, ImageConsumers/Producers, Toolkits and other advanced AWT ilk.
Java has three types of access levels and one unamed default one:
public class MyClass extends Object { int x; int y; int z; ... public void myMethod(int x, int y, int size) { this.x = x; this.y = y z = size; // Error: Ambiguous x = x; y = y } } public class YourClass extends MyClass { int x; int y; int size; ... public void yourMethod(int x, int y) { // This sets MyClass' x, y,z variables super.x = x; super.y = y; super.z = x + y; this.x = x; this.y = y; size = x * y * super.x * super.y; } }
public class AnotherClass { static int x; int y; public void myMethod() { y = AnotherClass.x; } }If you have a C++ background this is rather straightforward. An instance method/variable can be access using the "this" pointer or not. In the above code y and this.y are exactly the same.
With class methods and variables you do not need to create an instance of the class in order to use the method/variables. For example System.out.println() is accessible without create an instance of System because out is a static PrintStream.
When you inherit from a class
You inherit the public members, have access to protected members, but not to private. And you are considered a sub-class or sub-type of the class you derived from.
When you implement an interface
You must implement the methods specified by the interface otherwise the class becomes abstract.
public class ThisClass { public myMethod(Object x, Object y) { if(x instanceof Button && y instanceof Button) System.out.println("This method was called with Buttons"); else if(x instanceof Thread && y instanceof Thread) System.out.println("This method was callled with Threads"); else if(x instanceof Label && y instanceof String) { Label l = (Label)x; l.setLabel((String)y); } } }Comfortable with what has been discussed? If yes, you should read this and the tutorial. If not you could read this for a brief overview of AWT programming.
Nothing prevents use from using threading, audio, I/O, networking alongside the AWT. The AWT by itself is rather bare and empty. Imagine a text editor that couldn't save! As a side note, the AWT can be used in a stand-alone Java application or in an applet that is embedded into a HTML document.
Interfaces
public class TextEditor extends Frame { Button myButton; public TextEditor() { ... setTitle("Text Editor") setLayout(new BorderLayout()); setBackground(Color.orange); myButton = new Button("Hit This"); add("Center", myButton); pack(); show(); } boolean handleEvent(Event evt) { if("Hit This".equals(evt.arg)) { System.out.println("He hit me"); return true; } } }
public class MyButton extends Button { ... ... boolean action(Event evt, Object arg) { if(evt.target == this) { System.out.println("He hit me"); return true; } } }This is another method of event handling. The event is handled in the Component rather than the Container.
public class AnotherTextEditor extends Frame { MyButton anotherButton; public AnotherTextEditor() { setTitle("Another Text Editor") setLayout(new BorderLayout()); setBackground(Color.white); anotherButton = new MyButton("Hit This"); add("Center", anotherButton); pack(); show(); } }Note: Instead of extending Frame for an applet which is in itself a sub-class of a Panel, we can merely add() it to the applet.
All Containers have common functionality, due to the fact they are derived from Container which includes many event handling methods. These events are useful for handling user input and/or in a specialized class where you would override the default behavior such as the appearance(i.e font, color, etc.)
A quick-and-dirty summary of common methods:
add(Component)
add(String, Component)
remove(Component)
getComponents()
setLayout(LayoutManager)
getLayout()
Container Is-A Component since it is derived from Component, thus it can also behave and used like an Component. All of the methods in Component can be used in a Container
A quick-and-dirty summary of common methods:
getBackground()
setBackground(Color)
getFont()
setFont(Font)
mouseDown(Event, int, int)
show()
resize(int, int)
paint(Graphics)
update(Graphics)
move(int, int)
There are man different layout schemes, but the ones pre-defined for us are
Using the layouts is different from one from another. Withing BorderLayout we specify the type of layout(North, South, etc.) by passing a string with either "North", "South", etc to the method add().
i.e
add("Center", myComponent);adds myComponent to the Container and centers it. With other layouts, the first string parameter is different.
Button b = new Button("Hello"); add(new Button("World")); add(b);
Event-handling? Geez don't I just poll and grab user-input?
No this is Java and how the GUIs it runs under operate. GUIs and Windowing systems use the event-driven model rather than the old procedural-grab-the-input-yourself model. The OS is the one polling for events. When it finds it, it tells you what has happened. If you say, "bah, I don't care about that event". Fine, the OS handles it with its own default handler, otherwise you better do something with it or you get the default, which maybe nothing at all.
Here are the some of the events you will need to handle. This list of all events your application will probably need to handle is in the Event's class documentation.
ACTION_EVENT occurs when you press a button, select a menu, etc.
To handle ACTION_EVENT you have two choices
public boolean handleEvent(Event evt) { switch(evt.id) { case Event.ACTION_EVENT: { if((Hey I've been hit " + n + "times).equals(evt.arg)) { } // Here evt.target contains the target // i.e java.awt.MenuItem[label=Quit] // evt.arg contains the label of the button pressed // or menu item hit } } }The same thing came be accomplished with action(evt, arg), because this is the method which is called whenever a event has occurred for that Component.
public boolean action(Event evt, Object arg) { if(("Hey I've been hit " + n + "times").equals(arg)) { } }As you can see, even if the labels change you can still receive the event. The above is a button that changes everytime you hit it. But this isn't the only way to handle events. In fact you can compare objects instead of labels such as if(evt.target == myButton).
public boolean handleEvent(Event evt) { switch(evt.id) { // Examples of what can be handled case Event.KEY_PRESS: case Event.HOME: case Event.WINDOW_MOVED: // ... }Also you can override a sub-classes method handler such as keyDown, mouseDown to provide your own handling code. For example a specialized(sub-class) version of a TextArea that overrides mouseEnter() can determine when the mouse enters the Component and thus may decide to hilight the text.
The source code
import java.*; public class MyHelloWorld { public static void main(String args[]) { System.out.println("Hello World"); } }Have we created a Window? have we specified the font size, color and placement of the string "Hello World"? No. GUIs were never meant for printing "Hello World" onto the screen graphically, but to make applications easier-to-use.
This example displays the string graphically, but shows you the types of errors you can get into if you are not careful.
Notice how the first string is cut-off:
The source code
import java.awt.*; public class GraphicHello extends Frame { // Constants static final int H_SIZE = 300; static final int V_SIZE = 200; // The constructor public GraphicHello() { setFont(new Font("TimesRoman",Font.BOLD,24)); setBackground(Color.white); setTitle("GraphicHello"); resize(H_SIZE,V_SIZE); show(); } public void paint(Graphics g) { // This gets cut-off because the baseline is // too near to the top. // We also want to change the color of the font // when we draw g.setColor(Color.black); g.drawString("Hello World", 10,10); // This is just fine for this window g.setColor(Color.red); g.drawString("Hello", 10,50); } public static void main(String args[]) { new GraphicHello(); } }
The following classes are related to Menus
MenuBar mb = new MenuBar(); Menu top = new Menu("File"); Menu sub = new Menu("New"); sub.add(new MenuItem("Document")); sub.add(new MenuItem("Message")); sub.add(new MenuItem("Image")); top.add(sub); top.add(new MenuItem("Open")); top.add(new MenuItem("Save..)); setMenuBar(mb);
g.drawLine(x1, y1, width, height);Where g is an instance of the Graphics class. graphics.drawLine(...) is also legal as long as 'graphics' is an instance of Graphics.
Note: Graphics is an abstract class, you cannot just 'new' it.
i.e
g = new Graphics() is illegal.Here is some code that demostrates drawLine. The example was converted from C/C++ from a book I can't remember the title of.
import java.awt.*; public class FiftySquares extends Frame { float xA, yA, xB, yB, xC, yC, xD, yD, xA1, yA1, xB1, yB1, xC1, yC1, xD1, yD1,p,q,r; int i; int x_center, y_center; static final int H_SIZE = 300; static final int V_SIZE = 300; public FiftySquares() { q = (float)0.05; p = 1 - q; r = (float)0.95 * H_SIZE; x_center = H_SIZE/2; y_center = V_SIZE/2; resize(H_SIZE, V_SIZE); show(); } public void paint(Graphics g) { xA = xD = x_center - r; xB = xC = x_center + r; yA = yB = y_center - r; yC = yD = y_center + r; for(i=0; i<50; i++) { g.drawLine((int)xA, (int)yA, (int)xB, (int)yB); g.drawLine((int)xB, (int)yB, (int)xC, (int)yC); g.drawLine((int)xC, (int)yC, (int)xD, (int)yD); g.drawLine((int)xD, (int)yD, (int)xA, (int)yA); xA1= p*xA+q*xB;yA1= p*yA+q*yB; xB1= p*xB+q*xC;yB1= p*yB+q*yC; xC1= p*xC+q*xD;yC1= p*yC+q*yD; xD1= p*xD+q*xA;yD1= p*yD+q*yA; xA=xA1;xB=xB1;xC=xC1;xD=xD1; yA=yA1;yB=yB1;yC=yC1;yD=yD1; } } public boolean mouseDown(Event evt, int x, int y) { repaint(); return true; } public static void main(String args[]) { new FiftySquares(); } }
The source code
drawRect(x1, y1, width, height) drawRoundRect(x1, y1, width, height, arcWidth, arcHeight) drawRect3D(x1, y1, width, height, raised)
Image img = getImage(getDocumentBase(), "mypicture.gif"); .. public void paint(Graphics g) { g.drawImage(img, 0, 0, this); }See the "Boss Dartboard" example in Apps or Applets section.