Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
MIT AITI 2004 Swing Event Model Lecture 17 The Java Event Model • In the last lecture, we learned how to construct a GUI to present information to the user. • But how do GUIs interact with users? How do applications recognize when the user has done something? package swinglab; ClickReporter import java.awt.*; import javax.swing.*; public class ClickReporter extends JFrame { public ClickReporter() { JButton myButton = new JButton("Click here"); Container cp = getContentPane(); cp.add(myButton); setTitle("Click Printer"); setDefaultCloseOperation(EXIT_ON_CLOSE); pack(); show(); } public static void main(String[] args) { ClickReporter cr = new ClickReporter(); } } ClickPrinter Listener package swinglab; import java.awt.event.*; class ClickPrinter implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("Button was pressed"); } } Adding a Listener public ClickReporter() { JButton myButton = new JButton("Click here"); ClickPrinter printer = new ClickPrinter(); click.addActionListener(printer); Container cp = getContentPane(); cp.add(myButton); setTitle("Click Printer"); setDefaultCloseOperation(EXIT_ON_CLOSE); pack(); show(); } ClickReporter • Each time you click the button a message is displayed in a console window. Click here Button was pressed Event Handling Diagram e.g. button, menu, text fields Event Handling • To be able to handle events in Java we need 3 things: – event sources – event objects – event listeners Event Sources • Event sources are components that can recognize user action: menus, buttons, text fields etc. • Event sources have methods to add event listeners to them like addActionListener • Event source reports on events and notifies all its listeners Event Source • In our ClickReporter class we create an event source, a JButton called myButton: JButton myButton = new JButton("Click here"); Click here Event Objects • Objects that represent a user action (e.g. mouse click) – contain detailed information about the event. • When an event happens an event source sends an event object to its event listeners • EventObject is the superclass – ActionEvent, MouseEvent, etc. are the subclasses that we use Event Objects • In our example, the event source – JButton myButton generates an event object representing a mouse click. • We are not going into details of EventObjects – we will need them only as arguments to the method actionPerformed in event listeners. Event Listeners • Event listeners are objects that respond when an event occurs • Any object , whose class implements the ActionListener interface, can be an event listener. • If the event listener has been added to an event source, the listener will be called when an event occurs on that source. ActionListener interface • Look it up at the API in the package java.awt.event: public interface ActionListener extends EventListener { public void actionPerformed(ActionEvent e); } Event Listener In ClickReporter class we have an event listener – ClickPrinter object called printer: ClickPrinter printer = new ClickPrinter(); and add this listener to our JButton click: click.addActionListener(printer); • create an event source: JButton myButton = new JButton("Click here"); • create an event listener: ClickPrinter printer = new ClickPrinter(); • add listener to the source: click.addActionListener(printer); • Add the following data fields to your ClickReporter class: private JLabel counterLabel; private int counter = 0; • Add the following three lines to the ClickReporter constructor: cp.setLayout(new FlowLayout()); ClickCounter cc = new ClickCounter(this); click.addActionListener(cc); • Add these lines to your constructor: counterLabel = new JLabel( "The number of clicks is 0"); cp.add(counterLabel); • Add this method to ClickReporter: void incrementCounter(){ counterLabel.setText( "The number of clicks is " + (++counter)); pack(); } In your swinglab package create ClickCounter: package swinglab; import java.awt.event.*; class ClickCounter implements ActionListener { private ClickReporter clickReporter; ClickCounter(ClickReporter c) { clickReporter = c; } public void actionPerformed(ActionEvent e){ clickReporter.incrementCounter(); } } ClickCounter Diagram • Button is pressed and notifies ClickCounter JButton actionPerformed ClickCounter • ClickCounter tells ClickReporter to increment its counter incrementCounter ClickReporter A Calculator Listener package swinglab; import java.awt.event.*; class CalcListener implements ActionListener { private Calc calculator; CalcListener(Calc c) { calculator = c; } public void actionPerformed(ActionEvent e) { calculator.calculatePressed(); } } • Add this method to Calc class: void calculatePressed() { double n1 = Double.parseDouble(num1.getText()); double n2 = Double.parseDouble(num2.getText()); String op = (String)operation.getSelectedItem(); double ans; if (op.equals(Calc.ADD_OP)) ans else if (op.equals(Calc.SUB_OP)) ans else if (op.equals(Calc.MUL_OP)) ans else ans = = = = answerLabel.setText("Answer: " + ans); pack(); } n1 n1 n1 n1 + * / n2; n2; n2; n2; Add the Calc Listener • In the Calc constructor, add an instance of CalcListener as a listener to the calculate button CalcListener cl = new CalcListener(this); calculate.addActionListener(cl); Quiz Question 1 • Q: It's annoying to make a separate class for each listener. If any class can implement an interface, can't Calc implement ActionListener and listen for the events itself? • A: Yes Quiz Question 2 • Q: Is it a good idea to have Calc be a listener for itself? • A: No. Calc is public, and if Calc implements ActionListener, then any outside class can use Calc to listen for unrelated events. Calc is only designed to handle Calc 's own events. Uh oh . . . • What happens when you type letters into the textfields and click the calculate button? • Exceptions are thrown! Exception Handling • Catch those exceptions and display an error message window describing the error to the user. • To show the error message window use the method JOptionPane.showMessageDialog • Hint: the parentComponent should be the Calc object itself Solution void calculatePressed() { double n1 = 0, n2 = 0; try { n1 = Double.parseDouble(num1.getText()); n2 = Double.parseDouble(num2.getText()); } catch(NumberFormatException e) { JOptionPane.showMessageDialog(this, "Must type two numbers, dummy!", "Not Numbers!", JOptionPane.ERROR_MESSAGE); } String op = (String)operation.getSelectedItem(); double ans; if (op.equals(Calc.ADD_OP)) ans else if (op.equals(Calc.SUB_OP)) ans else if (op.equals(Calc.MUL_OP)) ans else ans = = = = answerLabel.setText("Answer: " + ans); } n1 n1 n1 n1 + * / n2; n2; n2; n2;