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 as this document is not considered advanced material because it does not discuss Peers, ImageConsumers/Producers, Toolkits and other a dvanced AWT ilk. It is recommend you look at the source code to see how the AWT really works.
The cornerstone of most OO programing languages are classes. So I'd expect you to understand them before using the AWT.
Java has four 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 creating an instance of System because out is a static PrintStream.
interface Document { public void read(); public void write(); } public class MultipleInterfaces extends Object implements Runnable, Document { // Runnable requires this public void run() {} // Document require these public void read() {} public void write() {} }
When you inherit from a class
You inherit the public members, have access to protected members of the parent, but not to private member of the parent. The new 'derived'(child by others) is 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. See above.
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 us from using threads, audio, I/O, networking classes 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 within a HTML document.
Interfaces
The method of handling events in the Container(i.e Frame) is preferred over the latter, since we want to centralize event handling. If you don't want to handle events in one common area of code, then you must sub-class every Component you create an instance of and override its action() or handleEvent() method.
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(); } public boolean handleEvent(Event evt) { if("Hit This".equals(evt.arg)) { 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. First we must sub-class Button.
public class MyButton extends Button { ... ... public boolean action(Event evt, Object arg) { if(evt.target == this) { System.out.println("He hit me"); return true; } } }
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(); resize(300, 300); show(); } }All Containers have common functionality, due to the fact they are derived from Container which includes many pre-defined event handling methods(called callbacks). These events are useful for handling user input in a specialized(i.e sub-class or derived) Container class where you'd override the default behavior such as the appearance(i.e font, color, etc.) by overriding the methods.
A quick-and-dirty summary of common methods:
add(Component)
add(String, Component)
remove(Component)
getComponents()
setLayout(LayoutManager)
getLayout()
Every Container Is-A Component since it is derived from Component, thus it can also behave and be used like an Component. All of the methods in Component can be used in a Container.
Components are Buttons, TextAreas, Scrollbars, etc. in other words the visible UI controls that the user interacts with, all of which have been added to a Container. Anything that is derived from the class Component can be one. p
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 each layouts is different. For BorderLayout you specify the type of layout(North, South, etc.) by passing a string(i.e "North", "South", etc to the method add() in a Container.
i.e
add("Center", myComponent);adds myComponent to the Container and centers it. With other layouts, the first String parameter is different.
add(new Button("Hello")); Button b = new Button("World"); add(b);
You can handle events given the label of the Component, thus new Button("Hello") makes perfect sense to a Java programmer.
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 ones, 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
The following examples shows you how and why...
public boolean handleEvent(Event evt) { switch(evt.id) { case Event.ACTION_EVENT: { if((Hey I've been hit " + n + "times).equals(evt.arg)) { return true; } // 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 } default: // Let parent handle the message return super.handleEvent(evt); } }The same thing came be accomplished with action(evt, arg), because when an ACTION_EVENT occurs action() is called.
public boolean action(Event evt, Object arg) { if(("Hey I've been hit " + n + "times").equals(arg)) { return true; } return false; }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: return true; // ... default: return super.handleEvent(evt); } }Also you can override a sub-class's method handler such as keyDown(), mouseDown() to provide your own event 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 can decide to hilight the text if needed.
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 and 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
To use menus you need to create a MenuBar and Menus with MenuItems, then attach the MenuBar to your application via setMenuBar. You can even embed, Menus in MenuItems..
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);To use Menus in applet you'll need to create a new Frame and attach a menubar to that. You can not just change the browser's menubar. You are not dealing with OLE 2 here.
g.drawLine(x1, y1, x2, y2);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); }
End of Introduction.