Each frame is often subdivided into a number of rectangular areas, which I will call components. Examples of components are buttons, menus, menubars, text input fields, and areas in which text and graphics are drawn. These components often have particular behavior in response to mouse clicks, etc. However, these components are bound in some deep way to the enclosing frame. For example, all components of a frame move together when the frame is moved.
We can also use the mouse to move a frame around, resize the frame, Iconify the frame, kill the frame, select a frame, bring a frame to the foreground so it is not covered by other frames, etc.
Each program is only responsible for the contents of its own frames. It is in general, not resposible for where they are on the screen, whether they are on top or buried, etc. Each program wants to treat its frames as a collection of rectangular areas, independent of any other program's frames.
The operating system is responsible for managing attached hardware. In particular, the mouse, the keyboard, and the screen. It tracks low level motion, click, and keypress events, and sets pixels on the screen to particular colors.
A digression--Pixels and Screens: The image on your screen is made up of a rectangular array of dots which can be set to some color by the computer's graphics hardware. These dots are called pixels. Depending on the computer, monitor, and graphics card, the screen will consist of different sized arrays; for example 1024x800 pixels, 1600x1200, 480x760.
The Window System is an entity that mediates between the operating system and the programs to manage the global resources of screen, mouse, and keyboard, while giving each program the view that it is connected to a mouse, keyboard and some number of frames. It is the window system that is responsiable for placing frames on the screen, moving them, iconifying them, killing then, selecting them, uncovering them etc. It also decides which frame--and therefore which program--each mouse event and key press belongs to. The main abstraction the Window System supports is called, naturally, a Window. Windows correspond to rectangular areas of the screen managed by the Window Systems. Both the frames and components discussed above are windows. In a typical application, each button, menu, scrollbar, etc. is its own window. (At least in most implementations; sometimes there are attempts to cheat for efficiency).
Frame windows are generally treated specially by the window system in that they are given borders, and a title bar with close and iconify icons, and all the other stuff for moving and resizing. (Of course a program can request this stuff be turned off).
Inside a frame, a program's windows are organized hierarchically. This hierarchy usually follows geometric enclosure. Child windows appear inside parent windows. Note: this hierarchy of windows is NOT the inheritance hierarchy of the various window types.
In general, the program is responsible for drawing the contents of its windows and reacting to mouse and keyboard events appropriately. For windows of common functionality, like buttons, there are libraries that support this functionality so it doesn't have to be duplicated. Some of these implement GUI components, and are often called widgets. There are other window types whose sole function is to organise the layout of their children. These are usually called container or layout windows.
The Java class that will do this for us (using the Swing GUI implementation)
is JFrame. We will subclass JFrame to make a frame
with the behavior we want.
// Need to import these
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
/**
* Basic code to put up a frame.
*/
class MyFrame extends JFrame{
public MyFrame(){
setTitle("MyFrame");
setSize(200,200); // size in pixels, must set: defaults to 0,0
// Magic to get program to quit on Frame window close
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
public class FrameTest{
// OK let's have our main() create a frame.
public static void main(String[] args){
// Create new frame
MyFrame myframe = new MyFrame();
// Show frame
myframe.show();
}
}
When I compile and run this program, it opens a frame whose size is 200x200 pixels with title "MyFrame". Notice I can move it, resize it, iconify it, close it; it appears in the taskbar, I can lower or raise it. All without doing any work. The Window System handles it all for me. Is this cool or what?
Sizing issues go beyond how big to make the frame window. Clearly you can fit more stuff into a 400x400 window than a 200x200 window. The application developer must decide how best to adjust to the smaller area, whether to scale everything, pack things close together, or simply omit things. This issue also appears when the user resizes the window. The program must adjust to the new size to make it look good (or simply not allow re-sizing).
class MyPanel extends JPanel{
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawString("Hello World",50,50);
}
}
public class FrameTest{
// OK let's have our main() create a frame.
public static void main(String[] args){
// Create new frame
MyFrame myframe = new MyFrame();
MyPanel mypanel = new MyPanel();
// Random stuff we just have to do (the book explains, kind of)
Container contentPane = myframe.getContentPane();
// add panel
contentPane.add(mypanel);
// Show frame
myframe.show();
}
}
This happens because the our paintComponent() method is called by the WindowSystem when a window needs to be repainted due to being moved, uncovered, de-iconifyed, etc. We can see that this is happening by adding a System.out.println() to our paintComponent() method. The Java model (and the model of most systems) is that the programmer is responsible for refreshing graphics; the window system does not buffer or remember the current contents. We will learn more about how this happens tomorrow.
ints for
pixel values, and consist of methods like drawLine().
float or double for pixel coordinates and
are implemented as separate classes. In order to use them, you must
instantiate one, set any properties you want on the Graphics object,
then draw (or fill) it, using the draw() or fill() methods on Graphics2D.
Color red = new Color(255,0,0); Color blue = Color.blue;
Graphics2D g2 = (Graphics2D)g; // downcast Graphics object Line2D line = new Line2D.float(100,100,150,150); g2.setColor(red); g2.draw(line);
Rectangle2D r = new Rectangle2D.float(120,100,30,30); g2.setColor(red); g2.draw(); g2.setColor(blue); g2.fill(); // To draw a solid rectangle we call fill() rather than draw()
drawImage method.
// use static method on ToolKit class to get the system-dependent ToolKit
// to really use.
Toolkit kit = Toolkit.getDefaultToolkit();
Image im = kit.getImage("img01.jpg");
g.drawImage(im,50,50,null);
More complex Image handling issues are discussed in the book.
The only way to really learn to use these tools is to try them. Explore nad have fun.