The new AWT
| Bruce Eckel's Thinking in Java | Contents | Prev | Next |
The new event model
//: Button2New.java // Capturing button presses import java.awt.*; import java.awt.event.*; // Must add this import java.applet.*; public class Button2New extends Applet { Button b1 = new Button("Button 1"), b2 = new Button("Button 2"); public void init() { b1.addActionListener(new B1()); b2.addActionListener(new B2()); add(b1); add(b2); } class B1 implements ActionListener { public void actionPerformed(ActionEvent e) { getAppletContext().showStatus("Button 1"); } } class B2 implements ActionListener { public void actionPerformed(ActionEvent e) { getAppletContext().showStatus("Button 2"); } } /* The old way: public boolean action(Event evt, Object arg) { if(evt.target.equals(b1)) getAppletContext().showStatus("Button 1"); else if(evt.target.equals(b2)) getAppletContext().showStatus("Button 2"); // Let the base class handle it: else return super.action(evt, arg); return true; // We've handled it here } */ } ///:~
b1.addActionListener(new B1()); b2.addActionListener(new B2());
Event and listener types
|
ActionEvent
ActionListener addActionListener( ) removeActionListener( ) |
Button,
List,
TextField, MenuItem,
and its derivatives including
CheckboxMenuItem,
Menu,
and
PopupMenu
|
|
AdjustmentEvent
AdjustmentListener addAdjustmentListener( ) removeAdjustmentListener( ) |
Scrollbar
Anything you create that implements the Adjustable interface |
|
ComponentEvent
ComponentListener addComponentListener( ) removeComponentListener( ) |
Component
and its derivatives, including
Button,
Canvas,
Checkbox,
Choice,
Container
,
Panel,
Applet,
ScrollPane,
Window,
Dialog,
FileDialog,
Frame
,
Label,
List,
Scrollbar,
TextArea,
and
TextField
|
|
ContainerEvent
ContainerListener addContainerListener( ) removeContainerListener( ) |
Container
and its derivatives, including
Panel,
Applet,
ScrollPane,
Window,
Dialog,
FileDialog,
and
Frame
|
|
FocusEvent
FocusListener addFocusListener( ) removeFocusListener( ) |
Component
and its derivatives, including
Button,
Canvas,
Checkbox,
Choice,
Container
,
Panel,
Applet,
ScrollPane,
Window,
Dialog,
FileDialog,
Frame
Label,
List,
Scrollbar,
TextArea,
and
TextField
|
|
KeyEvent
KeyListener addKeyListener( ) removeKeyListener( ) |
Component
and its derivatives, including
Button,
Canvas,
Checkbox,
Choice,
Container
,
Panel,
Applet,
ScrollPane,
Window,
Dialog,
FileDialog,
Frame
,
Label,
List,
Scrollbar,
TextArea,
and
TextField
|
|
MouseEvent
(for both clicks and motion)
MouseListener addMouseListener( ) removeMouseListener( ) |
Component
and its derivatives, including
Button,
Canvas,
Checkbox,
Choice,
Container
,
Panel,
Applet,
ScrollPane,
Window,
Dialog,
FileDialog,
Frame
,
Label,
List,
Scrollbar,
TextArea,
and
TextField
|
|
MouseEvent[58]
(for
both clicks and motion)
MouseMotionListener addMouseMotionListener( ) removeMouseMotionListener( ) |
Component
and its derivatives, including
Button,
Canvas,
Checkbox,
Choice,
Container
,
Panel,
Applet,
ScrollPane,
Window,
Dialog,
FileDialog,
Frame
,
Label,
List,
Scrollbar,
TextArea,
and
TextField
|
|
WindowEvent
WindowListener addWindowListener( ) removeWindowListener( ) |
Window
and its derivatives, including
Dialog,
FileDialog,
and
Frame
|
|
ItemEvent
ItemListener addItemListener( ) removeItemListener( ) |
Checkbox,
CheckboxMenuItem,
Choice,
List,
and anything that implements the
ItemSelectable
interface
|
|
TextEvent
TextListener addTextListener( ) removeTextListener( ) |
Anything
derived from
TextComponent,
including
TextArea
and
TextField
|
|
Adjustable
|
AdjustmentEvent
|
|
Applet
|
ContainerEvent,
FocusEvent, KeyEvent, MouseEvent, ComponentEvent
|
|
Button
|
ActionEvent,
FocusEvent, KeyEvent, MouseEvent, ComponentEvent
|
|
Canvas
|
FocusEvent,
KeyEvent, MouseEvent, ComponentEvent
|
|
Checkbox
|
ItemEvent,
FocusEvent, KeyEvent, MouseEvent, ComponentEvent
|
|
CheckboxMenuItem
|
ActionEvent,
ItemEvent
|
|
Choice
|
ItemEvent,
FocusEvent, KeyEvent, MouseEvent, ComponentEvent
|
|
Component
|
FocusEvent,
KeyEvent, MouseEvent, ComponentEvent
|
|
Container
|
ContainerEvent,
FocusEvent, KeyEvent, MouseEvent, ComponentEvent
|
|
Dialog
|
ContainerEvent,
WindowEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent
|
|
FileDialog
|
ContainerEvent,
WindowEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent
|
|
Frame
|
ContainerEvent,
WindowEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent
|
|
Label
|
FocusEvent,
KeyEvent, MouseEvent, ComponentEvent
|
|
List
|
ActionEvent,
FocusEvent, KeyEvent, MouseEvent, ItemEvent, ComponentEvent
|
|
Menu
|
ActionEvent
|
|
MenuItem
|
ActionEvent
|
|
Panel
|
ContainerEvent,
FocusEvent, KeyEvent, MouseEvent, ComponentEvent
|
|
PopupMenu
|
ActionEvent
|
|
Scrollbar
|
AdjustmentEvent,
FocusEvent, KeyEvent, MouseEvent, ComponentEvent
|
|
ScrollPane
|
ContainerEvent,
FocusEvent, KeyEvent, MouseEvent, ComponentEvent
|
|
TextArea
|
TextEvent,
FocusEvent, KeyEvent, MouseEvent, ComponentEvent
|
|
TextComponent
|
TextEvent,
FocusEvent, KeyEvent, MouseEvent, ComponentEvent
|
|
TextField
|
ActionEvent,
TextEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent
|
|
Window
|
ContainerEvent,
WindowEvent, FocusEvent, KeyEvent, MouseEvent, ComponentEvent
|
- Take the name of the event class and remove the word “ Event.” Add the word “ Listener” to what remains. This is the listener interface you need to implement in your inner class.
- Implement the interface above and write out the methods for the events you want to capture. For example, you might be looking for mouse movements, so you write code for the mouseMoved( ) method of the MouseMotionListener interface. (You must implement the other methods, of course, but there’s a shortcut for that which you’ll see soon.)
- Create an object of the listener class in step 2. Register it with your component with the method produced by prefixing “ add” to your listener name. For example, addMouseMotionListener( ).
|
ActionListener
|
actionPerformed(ActionEvent)
|
|
AdjustmentListener
|
adjustmentValueChanged(
AdjustmentEvent) |
|
componentHidden(ComponentEvent)
componentShown(ComponentEvent) componentMoved(ComponentEvent) componentResized(ComponentEvent) |
|
|
componentAdded(ContainerEvent)
componentRemoved(ContainerEvent) |
|
|
focusGained(FocusEvent)
focusLost(FocusEvent) |
|
|
keyPressed(KeyEvent)
keyReleased(KeyEvent) keyTyped(KeyEvent) |
|
|
mouseClicked(MouseEvent)
mouseEntered(MouseEvent) mouseExited(MouseEvent) mousePressed(MouseEvent) mouseReleased(MouseEvent) |
|
|
mouseDragged(MouseEvent)
mouseMoved(MouseEvent) |
|
|
windowOpened(WindowEvent)
windowClosing(WindowEvent) windowClosed(WindowEvent) windowActivated(WindowEvent) windowDeactivated(WindowEvent) windowIconified(WindowEvent) windowDeiconified(WindowEvent) |
|
|
ItemListener
|
itemStateChanged(ItemEvent)
|
|
TextListener
|
textValueChanged(TextEvent)
|
class MyWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } }
class MyWindowListener extends WindowAdapter { public void WindowClosing(WindowEvent e) { System.exit(0); } }
Making windows and applets
with the Java 1.1 AWT
//: Button2NewB.java // An application and an applet import java.awt.*; import java.awt.event.*; // Must add this import java.applet.*; public class Button2NewB extends Applet { Button b1 = new Button("Button 1"), b2 = new Button("Button 2"); TextField t = new TextField(20); public void init() { b1.addActionListener(new B1()); b2.addActionListener(new B2()); add(b1); add(b2); add(t); } class B1 implements ActionListener { public void actionPerformed(ActionEvent e) { t.setText("Button 1"); } } class B2 implements ActionListener { public void actionPerformed(ActionEvent e) { t.setText("Button 2"); } } // To close the application: static class WL extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } // A main() for the application: public static void main(String[] args) { Button2NewB applet = new Button2NewB(); Frame aFrame = new Frame("Button2NewB"); aFrame.addWindowListener(new WL()); aFrame.add(applet, BorderLayout.CENTER); aFrame.setSize(300,200); applet.init(); applet.start(); aFrame.setVisible(true); } } ///:~
- Make the handle applet a static member of the class (instead of a local variable of main( )), and then:
- Call applet.stop( ) and applet.destroy( ) inside WindowAdapter.windowClosing( ) before you call System.exit( ).
an anonymous class
aFrame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } });
<head><title>Button2NewB Example Applet </title></head> <body> <applet code="Button2NewB.class" archive="Button2NewB.jar" width=200 height=150> </applet> </body>
Revisiting the earlier examples
//: TextNew.java // Text fields with Java 1.1 events import java.awt.*; import java.awt.event.*; import java.applet.*; public class TextNew extends Applet { Button b1 = new Button("Get Text"), b2 = new Button("Set Text"); TextField t1 = new TextField(30), t2 = new TextField(30), t3 = new TextField(30); String s = new String(); public void init() { b1.addActionListener(new B1()); b2.addActionListener(new B2()); t1.addTextListener(new T1()); t1.addActionListener(new T1A()); t1.addKeyListener(new T1K()); add(b1); add(b2); add(t1); add(t2); add(t3); } class T1 implements TextListener { public void textValueChanged(TextEvent e) { t2.setText(t1.getText()); } } class T1A implements ActionListener { private int count = 0; public void actionPerformed(ActionEvent e) { t3.setText("t1 Action Event " + count++); } } class T1K extends KeyAdapter { public void keyTyped(KeyEvent e) { String ts = t1.getText(); if(e.getKeyChar() == KeyEvent.VK_BACK_SPACE) { // Ensure it's not empty: if( ts.length() > 0) { ts = ts.substring(0, ts.length() - 1); t1.setText(ts); } } else t1.setText( t1.getText() + Character.toUpperCase( e.getKeyChar())); t1.setCaretPosition( t1.getText().length()); // Stop regular character from appearing: e.consume(); } } class B1 implements ActionListener { public void actionPerformed(ActionEvent e) { s = t1.getSelectedText(); if(s.length() == 0) s = t1.getText(); t1.setEditable(true); } } class B2 implements ActionListener { public void actionPerformed(ActionEvent e) { t1.setText("Inserted by Button 2: " + s); t1.setEditable(false); } } public static void main(String[] args) { TextNew applet = new TextNew(); Frame aFrame = new Frame("TextNew"); aFrame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); aFrame.add(applet, BorderLayout.CENTER); aFrame.setSize(300,200); applet.init(); applet.start(); aFrame.setVisible(true); } } ///:~
class T1 implements TextListener { public void textValueChanged(TextEvent e) { t2.setText(t1.getText()); } }
//: TextAreaNew.java // Controlling scrollbars with the TextArea // component in Java 1.1 import java.awt.*; import java.awt.event.*; import java.applet.*; public class TextAreaNew extends Applet { Button b1 = new Button("Text Area 1"); Button b2 = new Button("Text Area 2"); Button b3 = new Button("Replace Text"); Button b4 = new Button("Insert Text"); TextArea t1 = new TextArea("t1", 1, 30); TextArea t2 = new TextArea("t2", 4, 30); TextArea t3 = new TextArea("t3", 1, 30, TextArea.SCROLLBARS_NONE); TextArea t4 = new TextArea("t4", 10, 10, TextArea.SCROLLBARS_VERTICAL_ONLY); TextArea t5 = new TextArea("t5", 4, 30, TextArea.SCROLLBARS_HORIZONTAL_ONLY); TextArea t6 = new TextArea("t6", 10, 10, TextArea.SCROLLBARS_BOTH); public void init() { b1.addActionListener(new B1L()); add(b1); add(t1); b2.addActionListener(new B2L()); add(b2); add(t2); b3.addActionListener(new B3L()); add(b3); b4.addActionListener(new B4L()); add(b4); add(t3); add(t4); add(t5); add(t6); } class B1L implements ActionListener { public void actionPerformed(ActionEvent e) { t5.append(t1.getText() + "\n"); } } class B2L implements ActionListener { public void actionPerformed(ActionEvent e) { t2.setText("Inserted by Button 2"); t2.append(": " + t1.getText()); t5.append(t2.getText() + "\n"); } } class B3L implements ActionListener { public void actionPerformed(ActionEvent e) { String s = " Replacement "; t2.replaceRange(s, 3, 3 + s.length()); } } class B4L implements ActionListener { public void actionPerformed(ActionEvent e) { t2.insert(" Inserted ", 10); } } public static void main(String[] args) { TextAreaNew applet = new TextAreaNew(); Frame aFrame = new Frame("TextAreaNew"); aFrame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); aFrame.add(applet, BorderLayout.CENTER); aFrame.setSize(300,725); applet.init(); applet.start(); aFrame.setVisible(true); } } ///:~
//: RadioCheckNew.java // Radio buttons and Check Boxes in Java 1.1 import java.awt.*; import java.awt.event.*; import java.applet.*; public class RadioCheckNew extends Applet { TextField t = new TextField(30); Checkbox[] cb = { new Checkbox("Check Box 1"), new Checkbox("Check Box 2"), new Checkbox("Check Box 3") }; CheckboxGroup g = new CheckboxGroup(); Checkbox cb4 = new Checkbox("four", g, false), cb5 = new Checkbox("five", g, true), cb6 = new Checkbox("six", g, false); public void init() { t.setEditable(false); add(t); ILCheck il = new ILCheck(); for(int i = 0; i < cb.length; i++) { cb[i].addItemListener(il); add(cb[i]); } cb4.addItemListener(new IL4()); cb5.addItemListener(new IL5()); cb6.addItemListener(new IL6()); add(cb4); add(cb5); add(cb6); } // Checking the source: class ILCheck implements ItemListener { public void itemStateChanged(ItemEvent e) { for(int i = 0; i < cb.length; i++) { if(e.getSource().equals(cb[i])) { t.setText("Check box " + (i + 1)); return; } } } } // vs. an individual class for each item: class IL4 implements ItemListener { public void itemStateChanged(ItemEvent e) { t.setText("Radio button four"); } } class IL5 implements ItemListener { public void itemStateChanged(ItemEvent e) { t.setText("Radio button five"); } } class IL6 implements ItemListener { public void itemStateChanged(ItemEvent e) { t.setText("Radio button six"); } } public static void main(String[] args) { RadioCheckNew applet = new RadioCheckNew(); Frame aFrame = new Frame("RadioCheckNew"); aFrame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); aFrame.add(applet, BorderLayout.CENTER); aFrame.setSize(300,200); applet.init(); applet.start(); aFrame.setVisible(true); } } ///:~
//: ChoiceNew.java // Drop-down lists with Java 1.1 import java.awt.*; import java.awt.event.*; import java.applet.*; public class ChoiceNew extends Applet { String[] description = { "Ebullient", "Obtuse", "Recalcitrant", "Brilliant", "Somnescent", "Timorous", "Florid", "Putrescent" }; TextField t = new TextField(100); Choice c = new Choice(); Button b = new Button("Add items"); int count = 0; public void init() { t.setEditable(false); for(int i = 0; i < 4; i++) c.addItem(description[count++]); add(t); add(c); add(b); c.addItemListener(new CL()); b.addActionListener(new BL()); } class CL implements ItemListener { public void itemStateChanged(ItemEvent e) { t.setText("index: " + c.getSelectedIndex() + " " + e.toString()); } } class BL implements ActionListener { public void actionPerformed(ActionEvent e) { if(count < description.length) c.addItem(description[count++]); } } public static void main(String[] args) { ChoiceNew applet = new ChoiceNew(); Frame aFrame = new Frame("ChoiceNew"); aFrame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); aFrame.add(applet, BorderLayout.CENTER); aFrame.setSize(750,100); applet.init(); applet.start(); aFrame.setVisible(true); } } ///:~
//: ListNew.java // Java 1.1 Lists are easier to use import java.awt.*; import java.awt.event.*; import java.applet.*; public class ListNew extends Applet { String[] flavors = { "Chocolate", "Strawberry", "Vanilla Fudge Swirl", "Mint Chip", "Mocha Almond Fudge", "Rum Raisin", "Praline Cream", "Mud Pie" }; // Show 6 items, allow multiple selection: List lst = new List(6, true); TextArea t = new TextArea(flavors.length, 30); Button b = new Button("test"); int count = 0; public void init() { t.setEditable(false); for(int i = 0; i < 4; i++) lst.addItem(flavors[count++]); add(t); add(lst); add(b); lst.addItemListener(new LL()); b.addActionListener(new BL()); } class LL implements ItemListener { public void itemStateChanged(ItemEvent e) { t.setText(""); String[] items = lst.getSelectedItems(); for(int i = 0; i < items.length; i++) t.append(items[i] + "\n"); } } class BL implements ActionListener { public void actionPerformed(ActionEvent e) { if(count < flavors.length) lst.addItem(flavors[count++], 0); } } public static void main(String[] args) { ListNew applet = new ListNew(); Frame aFrame = new Frame("ListNew"); aFrame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); aFrame.add(applet, BorderLayout.CENTER); aFrame.setSize(300,200); applet.init(); applet.start(); aFrame.setVisible(true); } } ///:~
//: MenuNew.java // Menus in Java 1.1 import java.awt.*; import java.awt.event.*; public class MenuNew extends Frame { String[] flavors = { "Chocolate", "Strawberry", "Vanilla Fudge Swirl", "Mint Chip", "Mocha Almond Fudge", "Rum Raisin", "Praline Cream", "Mud Pie" }; TextField t = new TextField("No flavor", 30); MenuBar mb1 = new MenuBar(); Menu f = new Menu("File"); Menu m = new Menu("Flavors"); Menu s = new Menu("Safety"); // Alternative approach: CheckboxMenuItem[] safety = { new CheckboxMenuItem("Guard"), new CheckboxMenuItem("Hide") }; MenuItem[] file = { // No menu shortcut: new MenuItem("Open"), // Adding a menu shortcut is very simple: new MenuItem("Exit", new MenuShortcut(KeyEvent.VK_E)) }; // A second menu bar to swap to: MenuBar mb2 = new MenuBar(); Menu fooBar = new Menu("fooBar"); MenuItem[] other = { new MenuItem("Foo"), new MenuItem("Bar"), new MenuItem("Baz"), }; // Initialization code: { ML ml = new ML(); CMIL cmil = new CMIL(); safety[0].setActionCommand("Guard"); safety[0].addItemListener(cmil); safety[1].setActionCommand("Hide"); safety[1].addItemListener(cmil); file[0].setActionCommand("Open"); file[0].addActionListener(ml); file[1].setActionCommand("Exit"); file[1].addActionListener(ml); other[0].addActionListener(new FooL()); other[1].addActionListener(new BarL()); other[2].addActionListener(new BazL()); } Button b = new Button("Swap Menus"); public MenuNew() { FL fl = new FL(); for(int i = 0; i < flavors.length; i++) { MenuItem mi = new MenuItem(flavors[i]); mi.addActionListener(fl); m.add(mi); // Add separators at intervals: if((i+1) % 3 == 0) m.addSeparator(); } for(int i = 0; i < safety.length; i++) s.add(safety[i]); f.add(s); for(int i = 0; i < file.length; i++) f.add(file[i]); mb1.add(f); mb1.add(m); setMenuBar(mb1); t.setEditable(false); add(t, BorderLayout.CENTER); // Set up the system for swapping menus: b.addActionListener(new BL()); add(b, BorderLayout.NORTH); for(int i = 0; i < other.length; i++) fooBar.add(other[i]); mb2.add(fooBar); } class BL implements ActionListener { public void actionPerformed(ActionEvent e) { MenuBar m = getMenuBar(); if(m == mb1) setMenuBar(mb2); else if (m == mb2) setMenuBar(mb1); } } class ML implements ActionListener { public void actionPerformed(ActionEvent e) { MenuItem target = (MenuItem)e.getSource(); String actionCommand = target.getActionCommand(); if(actionCommand.equals("Open")) { String s = t.getText(); boolean chosen = false; for(int i = 0; i < flavors.length; i++) if(s.equals(flavors[i])) chosen = true; if(!chosen) t.setText("Choose a flavor first!"); else t.setText("Opening "+ s +". Mmm, mm!"); } else if(actionCommand.equals("Exit")) { dispatchEvent( new WindowEvent(MenuNew.this, WindowEvent.WINDOW_CLOSING)); } } } class FL implements ActionListener { public void actionPerformed(ActionEvent e) { MenuItem target = (MenuItem)e.getSource(); t.setText(target.getLabel()); } } // Alternatively, you can create a different // class for each different MenuItem. Then you // Don't have to figure out which one it is: class FooL implements ActionListener { public void actionPerformed(ActionEvent e) { t.setText("Foo selected"); } } class BarL implements ActionListener { public void actionPerformed(ActionEvent e) { t.setText("Bar selected"); } } class BazL implements ActionListener { public void actionPerformed(ActionEvent e) { t.setText("Baz selected"); } } class CMIL implements ItemListener { public void itemStateChanged(ItemEvent e) { CheckboxMenuItem target = (CheckboxMenuItem)e.getSource(); String actionCommand = target.getActionCommand(); if(actionCommand.equals("Guard")) t.setText("Guard the Ice Cream! " + "Guarding is " + target.getState()); else if(actionCommand.equals("Hide")) t.setText("Hide the Ice Cream! " + "Is it cold? " + target.getState()); } } public static void main(String[] args) { MenuNew f = new MenuNew(); f.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); f.setSize(300,200); f.setVisible(true); } } ///:~
//: ToeTestNew.java // Demonstration of dialog boxes // and creating your own components import java.awt.*; import java.awt.event.*; public class ToeTestNew extends Frame { TextField rows = new TextField("3"); TextField cols = new TextField("3"); public ToeTestNew() { setTitle("Toe Test"); Panel p = new Panel(); p.setLayout(new GridLayout(2,2)); p.add(new Label("Rows", Label.CENTER)); p.add(rows); p.add(new Label("Columns", Label.CENTER)); p.add(cols); add(p, BorderLayout.NORTH); Button b = new Button("go"); b.addActionListener(new BL()); add(b, BorderLayout.SOUTH); } static final int BLANK = 0; static final int XX = 1; static final int OO = 2; class ToeDialog extends Dialog { // w = number of cells wide // h = number of cells high int turn = XX; // Start with x's turn public ToeDialog(int w, int h) { super(ToeTestNew.this, "The game itself", false); setLayout(new GridLayout(w, h)); for(int i = 0; i < w * h; i++) add(new ToeButton()); setSize(w * 50, h * 50); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e){ dispose(); } }); } class ToeButton extends Canvas { int state = BLANK; ToeButton() { addMouseListener(new ML()); } public void paint(Graphics g) { int x1 = 0; int y1 = 0; int x2 = getSize().width - 1; int y2 = getSize().height - 1; g.drawRect(x1, y1, x2, y2); x1 = x2/4; y1 = y2/4; int wide = x2/2; int high = y2/2; if(state == XX) { g.drawLine(x1, y1, x1 + wide, y1 + high); g.drawLine(x1, y1 + high, x1 + wide, y1); } if(state == OO) { g.drawOval(x1, y1, x1 + wide/2, y1 + high/2); } } class ML extends MouseAdapter { public void mousePressed(MouseEvent e) { if(state == BLANK) { state = turn; turn = (turn == XX ? OO : XX); } else state = (state == XX ? OO : XX); repaint(); } } } } class BL implements ActionListener { public void actionPerformed(ActionEvent e) { Dialog d = new ToeDialog( Integer.parseInt(rows.getText()), Integer.parseInt(cols.getText())); d.show(); } } public static void main(String[] args) { Frame f = new ToeTestNew(); f.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); f.setSize(200,100); f.setVisible(true); } } ///:~
//: FileDialogNew.java // Demonstration of File dialog boxes import java.awt.*; import java.awt.event.*; public class FileDialogNew extends Frame { TextField filename = new TextField(); TextField directory = new TextField(); Button open = new Button("Open"); Button save = new Button("Save"); public FileDialogNew() { setTitle("File Dialog Test"); Panel p = new Panel(); p.setLayout(new FlowLayout()); open.addActionListener(new OpenL()); p.add(open); save.addActionListener(new SaveL()); p.add(save); add(p, BorderLayout.SOUTH); directory.setEditable(false); filename.setEditable(false); p = new Panel(); p.setLayout(new GridLayout(2,1)); p.add(filename); p.add(directory); add(p, BorderLayout.NORTH); } class OpenL implements ActionListener { public void actionPerformed(ActionEvent e) { // Two arguments, defaults to open file: FileDialog d = new FileDialog( FileDialogNew.this, "What file do you want to open?"); d.setFile("*.java"); d.setDirectory("."); // Current directory d.show(); String yourFile = "*.*"; if((yourFile = d.getFile()) != null) { filename.setText(yourFile); directory.setText(d.getDirectory()); } else { filename.setText("You pressed cancel"); directory.setText(""); } } } class SaveL implements ActionListener { public void actionPerformed(ActionEvent e) { FileDialog d = new FileDialog( FileDialogNew.this, "What file do you want to save?", FileDialog.SAVE); d.setFile("*.java"); d.setDirectory("."); d.show(); String saveFile; if((saveFile = d.getFile()) != null) { filename.setText(saveFile); directory.setText(d.getDirectory()); } else { filename.setText("You pressed cancel"); directory.setText(""); } } } public static void main(String[] args) { Frame f = new FileDialogNew(); f.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); f.setSize(250,110); f.setVisible(true); } } ///:~
Binding events dynamically
//: DynamicEvents.java // The new Java 1.1 event model allows you to // change event behavior dynamically. Also // demonstrates multiple actions for an event. import java.awt.*; import java.awt.event.*; import java.util.*; public class DynamicEvents extends Frame { Vector v = new Vector(); int i = 0; Button b1 = new Button("Button 1"), b2 = new Button("Button 2"); public DynamicEvents() { setLayout(new FlowLayout()); b1.addActionListener(new B()); b1.addActionListener(new B1()); b2.addActionListener(new B()); b2.addActionListener(new B2()); add(b1); add(b2); } class B implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("A button was pressed"); } } class CountListener implements ActionListener { int index; public CountListener(int i) { index = i; } public void actionPerformed(ActionEvent e) { System.out.println( "Counted Listener " + index); } } class B1 implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("Button 1 pressed"); ActionListener a = new CountListener(i++); v.addElement(a); b2.addActionListener(a); } } class B2 implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("Button 2 pressed"); int end = v.size() -1; if(end >= 0) { b2.removeActionListener( (ActionListener)v.elementAt(end)); v.removeElementAt(end); } } } public static void main(String[] args) { Frame f = new DynamicEvents(); f.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e){ System.exit(0); } }); f.setSize(300,200); f.show(); } } ///:~
- There is more than one listener attached to each Button. Usually, components handle events as multicast, meaning that you can register many listeners for a single event. In the special components in which an event is handled as unicast, you’ll get a TooManyListenersException.
- During the execution of the program, listeners are dynamically added and removed from the Button b2 . Adding is accomplished in the way you’ve seen before, but each component also has a removeXXXListener( ) method to remove each type of listener.
Separating business logic
from UI logic
//: Separation.java // Separating GUI logic and business objects import java.awt.*; import java.awt.event.*; import java.applet.*; class BusinessLogic { private int modifier; BusinessLogic(int mod) { modifier = mod; } public void setModifier(int mod) { modifier = mod; } public int getModifier() { return modifier; } // Some business operations: public int calculation1(int arg) { return arg * modifier; } public int calculation2(int arg) { return arg + modifier; } } public class Separation extends Applet { TextField t = new TextField(20), mod = new TextField(20); BusinessLogic bl = new BusinessLogic(2); Button calc1 = new Button("Calculation 1"), calc2 = new Button("Calculation 2"); public void init() { add(t); calc1.addActionListener(new Calc1L()); calc2.addActionListener(new Calc2L()); add(calc1); add(calc2); mod.addTextListener(new ModL()); add(new Label("Modifier:")); add(mod); } static int getValue(TextField tf) { try { return Integer.parseInt(tf.getText()); } catch(NumberFormatException e) { return 0; } } class Calc1L implements ActionListener { public void actionPerformed(ActionEvent e) { t.setText(Integer.toString( bl.calculation1(getValue(t)))); } } class Calc2L implements ActionListener { public void actionPerformed(ActionEvent e) { t.setText(Integer.toString( bl.calculation2(getValue(t)))); } } class ModL implements TextListener { public void textValueChanged(TextEvent e) { bl.setModifier(getValue(mod)); } } public static void main(String[] args) { Separation applet = new Separation(); Frame aFrame = new Frame("Separation"); aFrame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); aFrame.add(applet, BorderLayout.CENTER); aFrame.setSize(200,200); applet.init(); applet.start(); aFrame.setVisible(true); } } ///:~
Recommended coding approaches
//: GoodIdea.java // The best way to design classes using the new // Java 1.1 event model: use an inner class for // each different event. This maximizes // flexibility and modularity. import java.awt.*; import java.awt.event.*; import java.util.*; public class GoodIdea extends Frame { Button b1 = new Button("Button 1"), b2 = new Button("Button 2"); public GoodIdea() { setLayout(new FlowLayout()); b1.addActionListener(new B1L()); b2.addActionListener(new B2L()); add(b1); add(b2); } public class B1L implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("Button 1 pressed"); } } public class B2L implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("Button 2 pressed"); } } public static void main(String[] args) { Frame f = new GoodIdea(); f.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e){ System.out.println("Window Closing"); System.exit(0); } }); f.setSize(300,200); f.setVisible(true); } } ///:~
//: BadIdea1.java // Some literature recommends this approach, // but it's missing the point of the new event // model in Java 1.1 import java.awt.*; import java.awt.event.*; import java.util.*; public class BadIdea1 extends Frame implements ActionListener, WindowListener { Button b1 = new Button("Button 1"), b2 = new Button("Button 2"); public BadIdea1() { setLayout(new FlowLayout()); addWindowListener(this); b1.addActionListener(this); b2.addActionListener(this); add(b1); add(b2); } public void actionPerformed(ActionEvent e) { Object source = e.getSource(); if(source == b1) System.out.println("Button 1 pressed"); else if(source == b2) System.out.println("Button 2 pressed"); else System.out.println("Something else"); } public void windowClosing(WindowEvent e) { System.out.println("Window Closing"); System.exit(0); } public void windowClosed(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowActivated(WindowEvent e) {} public void windowDeactivated(WindowEvent e) {} public void windowOpened(WindowEvent e) {} public static void main(String[] args) { Frame f = new BadIdea1(); f.setSize(300,200); f.setVisible(true); } } ///:~
addWindowListener(this); b1.addActionListener(this); b2.addActionListener(this);
- Java 1.1 supports JAR files so all your files can be placed in a single compressed JAR archive that requires only one server hit. You no longer need to reduce class count for Internet efficiency.
- The code above is much less modular so it’s harder to grab and paste. Note that you must not only implement the various interfaces for your main class, but in actionPerformed( ) you’ve got to detect which action was performed using a cascaded if statement. Not only is this going backwards, away from the listener model, but you can’t easily reuse the actionPerformed( ) method since it’s specific to this particular application. Contrast this with GoodIdea.java, in which you can just grab one listener class and paste it in anywhere else with minimal fuss. Plus you can register multiple listener classes with a single event, allowing even more modularity in what each listener class does.
//: BadIdea2.java // An improvement over BadIdea1.java, since it // uses the WindowAdapter as an inner class // instead of implementing all the methods of // WindowListener, but still misses the // valuable modularity of inner classes import java.awt.*; import java.awt.event.*; import java.util.*; public class BadIdea2 extends Frame implements ActionListener { Button b1 = new Button("Button 1"), b2 = new Button("Button 2"); public BadIdea2() { setLayout(new FlowLayout()); addWindowListener(new WL()); b1.addActionListener(this); b2.addActionListener(this); add(b1); add(b2); } public void actionPerformed(ActionEvent e) { Object source = e.getSource(); if(source == b1) System.out.println("Button 1 pressed"); else if(source == b2) System.out.println("Button 2 pressed"); else System.out.println("Something else"); } class WL extends WindowAdapter { public void windowClosing(WindowEvent e) { System.out.println("Window Closing"); System.exit(0); } } public static void main(String[] args) { Frame f = new BadIdea2(); f.setSize(300,200); f.setVisible(true); } } ///:~
//: GoodTechnique.java // Your first choice when overriding components // should be to install listeners. The code is // much safer, more modular and maintainable. import java.awt.*; import java.awt.event.*; class Display { public static final int EVENT = 0, COMPONENT = 1, MOUSE = 2, MOUSE_MOVE = 3, FOCUS = 4, KEY = 5, ACTION = 6, LAST = 7; public String[] evnt; Display() { evnt = new String[LAST]; for(int i = 0; i < LAST; i++) evnt[i] = new String(); } public void show(Graphics g) { for(int i = 0; i < LAST; i++) g.drawString(evnt[i], 0, 10 * i + 10); } } class EnabledPanel extends Panel { Color c; int id; Display display = new Display(); public EnabledPanel(int i, Color mc) { id = i; c = mc; setLayout(new BorderLayout()); add(new MyButton(), BorderLayout.SOUTH); addComponentListener(new CL()); addFocusListener(new FL()); addKeyListener(new KL()); addMouseListener(new ML()); addMouseMotionListener(new MML()); } // To eliminate flicker: public void update(Graphics g) { paint(g); } public void paint(Graphics g) { g.setColor(c); Dimension s = getSize(); g.fillRect(0, 0, s.width, s.height); g.setColor(Color.black); display.show(g); } // Don't need to enable anything for this: public void processEvent(AWTEvent e) { display.evnt[Display.EVENT]= e.toString(); repaint(); super.processEvent(e); } class CL implements ComponentListener { public void componentMoved(ComponentEvent e){ display.evnt[Display.COMPONENT] = "Component moved"; repaint(); } public void componentResized(ComponentEvent e) { display.evnt[Display.COMPONENT] = "Component resized"; repaint(); } public void componentHidden(ComponentEvent e) { display.evnt[Display.COMPONENT] = "Component hidden"; repaint(); } public void componentShown(ComponentEvent e){ display.evnt[Display.COMPONENT] = "Component shown"; repaint(); } } class FL implements FocusListener { public void focusGained(FocusEvent e) { display.evnt[Display.FOCUS] = "FOCUS gained"; repaint(); } public void focusLost(FocusEvent e) { display.evnt[Display.FOCUS] = "FOCUS lost"; repaint(); } } class KL implements KeyListener { public void keyPressed(KeyEvent e) { display.evnt[Display.KEY] = "KEY pressed: "; showCode(e); } public void keyReleased(KeyEvent e) { display.evnt[Display.KEY] = "KEY released: "; showCode(e); } public void keyTyped(KeyEvent e) { display.evnt[Display.KEY] = "KEY typed: "; showCode(e); } void showCode(KeyEvent e) { int code = e.getKeyCode(); display.evnt[Display.KEY] += KeyEvent.getKeyText(code); repaint(); } } class ML implements MouseListener { public void mouseClicked(MouseEvent e) { requestFocus(); // Get FOCUS on click display.evnt[Display.MOUSE] = "MOUSE clicked"; showMouse(e); } public void mousePressed(MouseEvent e) { display.evnt[Display.MOUSE] = "MOUSE pressed"; showMouse(e); } public void mouseReleased(MouseEvent e) { display.evnt[Display.MOUSE] = "MOUSE released"; showMouse(e); } public void mouseEntered(MouseEvent e) { display.evnt[Display.MOUSE] = "MOUSE entered"; showMouse(e); } public void mouseExited(MouseEvent e) { display.evnt[Display.MOUSE] = "MOUSE exited"; showMouse(e); } void showMouse(MouseEvent e) { display.evnt[Display.MOUSE] += ", x = " + e.getX() + ", y = " + e.getY(); repaint(); } } class MML implements MouseMotionListener { public void mouseDragged(MouseEvent e) { display.evnt[Display.MOUSE_MOVE] = "MOUSE dragged"; showMouse(e); } public void mouseMoved(MouseEvent e) { display.evnt[Display.MOUSE_MOVE] = "MOUSE moved"; showMouse(e); } void showMouse(MouseEvent e) { display.evnt[Display.MOUSE_MOVE] += ", x = " + e.getX() + ", y = " + e.getY(); repaint(); } } } class MyButton extends Button { int clickCounter; String label = ""; public MyButton() { addActionListener(new AL()); } public void paint(Graphics g) { g.setColor(Color.green); Dimension s = getSize(); g.fillRect(0, 0, s.width, s.height); g.setColor(Color.black); g.drawRect(0, 0, s.width - 1, s.height - 1); drawLabel(g); } private void drawLabel(Graphics g) { FontMetrics fm = g.getFontMetrics(); int width = fm.stringWidth(label); int height = fm.getHeight(); int ascent = fm.getAscent(); int leading = fm.getLeading(); int horizMargin = (getSize().width - width)/2; int verMargin = (getSize().height - height)/2; g.setColor(Color.red); g.drawString(label, horizMargin, verMargin + ascent + leading); } class AL implements ActionListener { public void actionPerformed(ActionEvent e) { clickCounter++; label = "click #" + clickCounter + " " + e.toString(); repaint(); } } } public class GoodTechnique extends Frame { GoodTechnique() { setLayout(new GridLayout(2,2)); add(new EnabledPanel(1, Color.cyan)); add(new EnabledPanel(2, Color.lightGray)); add(new EnabledPanel(3, Color.yellow)); } public static void main(String[] args) { Frame f = new GoodTechnique(); f.setTitle("Good Technique"); f.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e){ System.out.println(e); System.out.println("Window Closing"); System.exit(0); } }); f.setSize(700,700); f.setVisible(true); } } ///:~
public void update(Graphics g) { paint(g); }
//: BadTechnique.java // It's possible to override components this way, // but the listener approach is much better, so // why would you? import java.awt.*; import java.awt.event.*; class Display { public static final int EVENT = 0, COMPONENT = 1, MOUSE = 2, MOUSE_MOVE = 3, FOCUS = 4, KEY = 5, ACTION = 6, LAST = 7; public String[] evnt; Display() { evnt = new String[LAST]; for(int i = 0; i < LAST; i++) evnt[i] = new String(); } public void show(Graphics g) { for(int i = 0; i < LAST; i++) g.drawString(evnt[i], 0, 10 * i + 10); } } class EnabledPanel extends Panel { Color c; int id; Display display = new Display(); public EnabledPanel(int i, Color mc) { id = i; c = mc; setLayout(new BorderLayout()); add(new MyButton(), BorderLayout.SOUTH); // Type checking is lost. You can enable and // process events that the component doesn't // capture: enableEvents( // Panel doesn't handle these: AWTEvent.ACTION_EVENT_MASK | AWTEvent.ADJUSTMENT_EVENT_MASK | AWTEvent.ITEM_EVENT_MASK | AWTEvent.TEXT_EVENT_MASK | AWTEvent.WINDOW_EVENT_MASK | // Panel can handle these: AWTEvent.COMPONENT_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK | AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.CONTAINER_EVENT_MASK); // You can enable an event without // overriding its process method. } // To eliminate flicker: public void update(Graphics g) { paint(g); } public void paint(Graphics g) { g.setColor(c); Dimension s = getSize(); g.fillRect(0, 0, s.width, s.height); g.setColor(Color.black); display.show(g); } public void processEvent(AWTEvent e) { display.evnt[Display.EVENT]= e.toString(); repaint(); super.processEvent(e); } public void processComponentEvent(ComponentEvent e) { switch(e.getID()) { case ComponentEvent.COMPONENT_MOVED: display.evnt[Display.COMPONENT] = "Component moved"; break; case ComponentEvent.COMPONENT_RESIZED: display.evnt[Display.COMPONENT] = "Component resized"; break; case ComponentEvent.COMPONENT_HIDDEN: display.evnt[Display.COMPONENT] = "Component hidden"; break; case ComponentEvent.COMPONENT_SHOWN: display.evnt[Display.COMPONENT] = "Component shown"; break; default: } repaint(); // Must always remember to call the "super" // version of whatever you override: super.processComponentEvent(e); } public void processFocusEvent(FocusEvent e) { switch(e.getID()) { case FocusEvent.FOCUS_GAINED: display.evnt[Display.FOCUS] = "FOCUS gained"; break; case FocusEvent.FOCUS_LOST: display.evnt[Display.FOCUS] = "FOCUS lost"; break; default: } repaint(); super.processFocusEvent(e); } public void processKeyEvent(KeyEvent e) { switch(e.getID()) { case KeyEvent.KEY_PRESSED: display.evnt[Display.KEY] = "KEY pressed: "; break; case KeyEvent.KEY_RELEASED: display.evnt[Display.KEY] = "KEY released: "; break; case KeyEvent.KEY_TYPED: display.evnt[Display.KEY] = "KEY typed: "; break; default: } int code = e.getKeyCode(); display.evnt[Display.KEY] += KeyEvent.getKeyText(code); repaint(); super.processKeyEvent(e); } public void processMouseEvent(MouseEvent e) { switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: requestFocus(); // Get FOCUS on click display.evnt[Display.MOUSE] = "MOUSE clicked"; break; case MouseEvent.MOUSE_PRESSED: display.evnt[Display.MOUSE] = "MOUSE pressed"; break; case MouseEvent.MOUSE_RELEASED: display.evnt[Display.MOUSE] = "MOUSE released"; break; case MouseEvent.MOUSE_ENTERED: display.evnt[Display.MOUSE] = "MOUSE entered"; break; case MouseEvent.MOUSE_EXITED: display.evnt[Display.MOUSE] = "MOUSE exited"; break; default: } display.evnt[Display.MOUSE] += ", x = " + e.getX() + ", y = " + e.getY(); repaint(); super.processMouseEvent(e); } public void processMouseMotionEvent(MouseEvent e) { switch(e.getID()) { case MouseEvent.MOUSE_DRAGGED: display.evnt[Display.MOUSE_MOVE] = "MOUSE dragged"; break; case MouseEvent.MOUSE_MOVED: display.evnt[Display.MOUSE_MOVE] = "MOUSE moved"; break; default: } display.evnt[Display.MOUSE_MOVE] += ", x = " + e.getX() + ", y = " + e.getY(); repaint(); super.processMouseMotionEvent(e); } } class MyButton extends Button { int clickCounter; String label = ""; public MyButton() { enableEvents(AWTEvent.ACTION_EVENT_MASK); } public void paint(Graphics g) { g.setColor(Color.green); Dimension s = getSize(); g.fillRect(0, 0, s.width, s.height); g.setColor(Color.black); g.drawRect(0, 0, s.width - 1, s.height - 1); drawLabel(g); } private void drawLabel(Graphics g) { FontMetrics fm = g.getFontMetrics(); int width = fm.stringWidth(label); int height = fm.getHeight(); int ascent = fm.getAscent(); int leading = fm.getLeading(); int horizMargin = (getSize().width - width)/2; int verMargin = (getSize().height - height)/2; g.setColor(Color.red); g.drawString(label, horizMargin, verMargin + ascent + leading); } public void processActionEvent(ActionEvent e) { clickCounter++; label = "click #" + clickCounter + " " + e.toString(); repaint(); super.processActionEvent(e); } } public class BadTechnique extends Frame { BadTechnique() { setLayout(new GridLayout(2,2)); add(new EnabledPanel(1, Color.cyan)); add(new EnabledPanel(2, Color.lightGray)); add(new EnabledPanel(3, Color.yellow)); // You can also do it for Windows: enableEvents(AWTEvent.WINDOW_EVENT_MASK); } public void processWindowEvent(WindowEvent e) { System.out.println(e); if(e.getID() == WindowEvent.WINDOW_CLOSING) { System.out.println("Window Closing"); System.exit(0); } } public static void main(String[] args) { Frame f = new BadTechnique(); f.setTitle("Bad Technique"); f.setSize(700,700); f.setVisible(true); } } ///:~

Comments
There are no comments yet. Be the first to comment!