The constructor for a panel is:
public Panel()
Its constructor is:
public Canvas()
Both Panel and Canvas have method:
public void setSize(int width, int height)
Canvases must be resized or they will be set to have size (0,0). You can try to resize panels, but the layout manager may stretch them to a somewhat different size.
public Josephus extends Frame implements ActionListener, ItemListener { ... // omitted constant & instance variable defs // fields for number of people protected Label numLabel = new Label(" Number of people (<= 26)"); protected TextField number = new TextField("26"); // fields for # soldiers to skip btn elimination protected Label countLabel = new Label(" Number to skip"); protected TextField countOff = new TextField("7"); protected int numSkip; // Button to start finding messenger protected Button start = new Button("Start"); // Choice button to set speed protected Choice speed = new Choice(); // Panels and canvases for Applet // holds data entry fields Panel input = new Panel(); // for displaying animation of selection process Canvas diagram = new Canvas(); // holds start button and speed selector Panel startPanel = new Panel(); // constructor public Josephus() { // sets gap of 5 pixels between components setLayout(new BorderLayout(5,5)); // Set up input fields in two rows and two cols // using GridLayout (and leave gap of 5 pixels) input.setLayout(new GridLayout(2,2,5,5)); // Add label and number field to input input.add(numLabel); number.setBackground(Color.white); input.add(number); // Add label and field for number to skip input.add(countLabel); countOff.setBackground(Color.white); input.add(countOff); // Add input to top of frame add("North",input); // Set up canvas and add to center of frame diagram.setSize(200,400); add("Center",diagram); // Set up panel with start button and speed control // Since no explicit layout manager uses FlowLayout start.setBackground(Color.cyan); startPanel.add(start); // Let this class listen to the buttons! start.addActionListener(this); // Set up speed choice button speed.addItem("Slow"); speed.addItem("Medium"); speed.addItem("Fast"); speed.addItemListener(this); startPanel.add(speed); // Add startPanel at bottom of frame add("South",startPanel); }See the calculator program for another relatively complex example of laying out buttons and a label.
Event driven programming is based on an explicit or implicit loop and event queue. The idea is that the queue holds all events that have occurred and each time through the loop one event is removed from the queue and processed. Concurrently various devices generate events which are added to the queue. If the queue is ever empty the processing loop suspends until an event is added to the queue.
The event handling is built into Java and the programmer need not provide either the loop or queue. Instead events are delivered to objects which handle them.
If you really want to see the event queue, it is accessible by invoking Toolkit classes getSystemEventQueue(). One can also postEvent's and getNextEvent from an EventQueue.
All events inherit from Event from package java.awt. One subclass is AWTEvent. It and its subclasses can be found in the package java.awt.event.
For example there is a class PaintEvent. Objects of this class are generated any time an awt component needs to be repainted and causes the paint(Graphics g) method to be automatically called with parameter the current Graphics context (don't worry about Graphics objects for now - they are used for drawing).
Thus every Java component has a paint method which is automatically called everytime that component needs to be repainted (e.g., another object obscured part of it, but has now moved out of the way). Interestingly Java programmer guidelines forbid the programmer from explicitly calling this method. However you can override it in subclasses to make sure that repainting does what you want it to do.
The only way one is allowed to explicitly trigger repainting the screen is to execute the method:
public void repaint()which itself first schedules a call to the objects update method which erases the background and then calls paint with the appropriate Graphics parameter. Many of the sample programs (like Josephus) include code that overrides the paint method and that invokes the paint method indirectly through calls to repaint().
For example, ActionEvents are sent to Action listeners, which are registered by executing an addActionListener(...) method.
Here are examples of AWT Events, their listeners, the components generating these events and the methods of the listener class for handling the events. More are available.
Event Type Listener Interface Item generating Method ActionEvent ActionListener Button, MenuItem, actionPerformed List, TextField ItemEvent ItemListener Choice, CheckBox, itemStateChanged CheckboxMenuItem WindowEvent WindowListener Dialog, Frame windowClosing, ... MouseEvent MouseMotionListener Canvas, Frame, mouseDragged, Panel, Dialog mouseMoved MouseEvent MouseListener Canvas, Frame, mousePressed, Panel, Dialog mouseReleased, mouseClicked, ... KeyEvent KeyListener Component keyPressed, keyReleased, keyTyped
An important feature of the new Java 1.1. event model is that the container responsible for displaying a component (e.g., the frame containing a button) need not be responsible for handling events generated by that object. By assigning a listener to an object we can explicitly delegate responsibility for handling the events generated by the object.
All that is necessary is to ensure that the class provides an implementation for all methods contained in the interface. Because Josephus implements ActionListener and ItemListener, we see from the table above that it needs to provide methods actionPerformed and itemStateChanged. Here is the skeleton of these methods from the Josephus class:
/** Post: if start button pushed run simulation & select messenger, otherwise don't do anything. */ public void actionPerformed(ActionEvent evt) { if (evt.getSource() == start) { ... // code omitted // Ensure input fields legal or don't run. numPeople = Integer.parseInt(number.getText()); if (numPeople <= 0 || numPeople > 26) System.out.println("No more than 26 people"); else { numSkip = Integer.parseInt(countOff.getText()); if (numSkip < 1) System.out.println("Error ..."); else { ... // do appropriate stuff } } } } public void itemStateChanged(ItemEvent evt){ if (evt.getSource() == speed){ String selection = (String)evt.getItem(); if (selection.equals("Slow")) sleepTime = slowDelay; else if (selection.equals("Medium")) sleepTime = mediumDelay; else if (selection.equals("Fast")) sleepTime = fastDelay; } }
Java also supports the creation of "anonymous classes" which may be used as listeners, but we won't discuss that in this class. (They can save keystrokes in typing, but I find them hard to read.)
In practice there are minor variations that can sometimes screw up the look of components on windows (e.g., the fact that buttons lose their colors in Internet Explorer 4.x). Partially as a result, Sun is also introducing a new set of libraries (the Swing libraries) which will provide exactly the same look on all platforms.
I hope this brief discussion of the Java GUI and event system has provided you with some insight into how to program with it. There is no way that I can provide detailed instruction into the use of these libraries in this course, but I hope this brief introduction will provide you with enough information that you can read in more depth to see how to accomplish more complex tasks.