Event Handling
• Java graphic components generate events
– Buttons = when pressed, released, clicked
– TextFields = when characters are types, enter key
– CheckBoxes = checked or unchecked
– Etc…
• Based on these events we might want certain
actions to happen
– Therefore we need to have code to detect these
Button Example Code
private Scene scene; private Button button; @Override
public void start(Stage mainFrame) {
button = new Button("Ok");
scene = new Scene(button, 300, 300); mainFrame.setScene(scene);
Event Handling
• Currently nothing happens when the button is
clicked
• We need to create an event handler
• Then we need to register the button with the
Creating an Event Handler
1. Can create a private inner class2. Can create an anonymous inner class 3. Can create a separate class
4. Can use Lambda Expressions
Private Inner Class
• This is a class inside your current class • Advantages
– Can see all class variables
– Will likely need to use them in the event handling – Quick to code
• Disadvantages
– For several different types of events and many
Anonymous Inner Class
• This is a class created on-the-fly with no name
• Advantages
– Quick to code
– Can be created inside the parameters for setting the
event handler
• Disadvantages
– Only works for one components – Ugly code
Separate Event Handling Class
• Make separate classes for handling events • Advantages
– Separates event handling from UI
– Makes programs more modular
• Disadvantages
– Much more work to code
– Does not have access to the UI components directly,
Lambda Expressions
• New to java 8
• Cleaner way to create an anonymous inner class
• Advantages
– Same as anonymous inner classes – Looks nicer too
• Disadvantages
When to Use a Private Inner Class
• Private Inner Classes
– My preferred method
– Have a lot of experience with this – Never had a problem
– The only method you really need to know
– Only reasons not to use
• If you only have one or two buttons an anonymous inner class would be sufficient
When to Use an Anonymous Inner Class
• Anonymous Inner Class
– Never?
When to Use the Lambda Expression
• Only use if you have a very small number of
components that need handlers
• The components should need separate handlers
When to Use a Separate Class
• Only use if you must separate UI from event
handling
Example – ButtonHandlerExample1.java
Private Inner Class Button Handler
private class ButtonHandler implements EventHandler<ActionEvent> {
@Override
public void handle(ActionEvent e) {
if(e.getTarget() == button1) {
System.out.println("Button clicked"); }
Component Visibility
• Notice how the Button object was declared
with class scope outside of the constructor
Component Visibility
private Scene scene;
private Button button;
@Override
public void start(Stage mainFrame) {
button = new Button("Ok");
scene = new Scene(button, 300, 300); mainFrame.setScene(scene);
Events
• There are many types of Event
• In this case a button click corresponds to an ActionEvent
• Therefore our handler implements
Event Type
private class ButtonHandler implements EventHandler<ActionEvent>
{
@Override
public void handle(ActionEvent e) {
if(e.getTarget() == button) {
System.out.println("Button clicked"); }
Handle Method
• All handlers must override the handle method • Since we implement EventHandler we must
implement the handle method
• The handle method is what gets called when
an event is detected
Handle Method
private class ButtonHandler implements EventHandler<ActionEvent> {
@Override
public void handle(ActionEvent e)
{
if(e.getTarget() == button) {
System.out.println("Button clicked"); }
Implementing handle
• We should always check the source of the
event to know what component generated the event
• Always check the source even if there is only one component registered with the handler
– To ensure odd things don’t happen
Handle Method
private class ButtonHandler implements EventHandler<ActionEvent> {
@Override
public void handle(ActionEvent e) {
if(e.getTarget() == button)
{
System.out.println("Button clicked"); }
getTarget Method
• All events have the getTarget method
• This is basically returning the component that fired the event
• Use this to compare to the button you are
looking for
Overview
• We have created a button
• We have created the event handler class
• We have NOT created an event handler object
EventHandler Object
private ButtonHandler buttonHandler;
@Override
public void start(Stage mainFrame) {
button = new Button("Ok");
scene = new Scene(button, 300, 300);
buttonHandler = new ButtonHandler(); button.setOnAction(buttonHandler);
setOnAction Method
• All buttons have the method setOnAction • This method is in the ButtonBase class
– Therefore all classes that inherit (directly or
indirectly) from this class have this method
Anonymous Inner Class Example
@Overridepublic void start(Stage mainFrame) {
button = new Button("Ok");
scene = new Scene(button, 300, 300);
button.setOnAction(new EventHandler<ActionEvent>(){ @Override
public void handle(ActionEvent e) { System.out.println("Button clicked"); } }); mainFrame.setScene(scene); mainFrame.show(); }
Example – ButtonHandlerExample2.java
Lambda Function Example
@Override
public void start(Stage mainFrame) {
button = new Button("Ok");
scene = new Scene(button, 300, 300);
button.setOnAction((ActionEvent e) -> { System.out.println("Button clicked"); });
mainFrame.setScene(scene); mainFrame.show();
Example – ButtonHandlerExample3.java
Separate Event Handling Class
• Take your private inner class
• Make it into a separate regular class
• Everything else should work similarly
• Note: if your event handler needs things in
your regular class, you need to create the event handler with an instance of your class
– Also need to proved get methods for the required
Quick Summary
• Covered how to set up all event types of event
handlers for a button
• From here on we will just use private inner classes
• We looked at how to handle a button click
Multiple Buttons
• Can register multiple buttons to a single
handler
• Better than making a new handler for every
Example – MultipleButtonsExample.java
Multiple Buttons Code
private class ButtonHandler implements EventHandler<ActionEvent>{
@Override
public void handle(ActionEvent e) {
if(e.getTarget() == button1)
{
System.out.println("Button 1 clicked"); }
else if(e.getTarget() == button2)
{
System.out.println("Button 2 clicked"); }
else if(e.getTarget() == button3)
Multiple Buttons
• Use the getTarget method to determine which
one of the buttons has been clicked
• if(e.getTarget() == button1)
• This allows for simpler code when multiple buttons can be registered to a single handler
Checkbox
• Checkboxes also use the setOnAction method
to register a handler
• The handler is the same ActionEvent handler as regular buttons
• What makes Checkboxes different is the call e.getTarget()
Example – CheckBoxHandlerExample.java
CheckBox Code
@Overridepublic void start(Stage mainFrame) {
checkBox1 = new CheckBox("Check Box 1"); checkBox2 = new CheckBox("Check Box 2"); checkBox3 = new CheckBox("Check Box 3");
checkBoxHandler = new CheckBoxHandler();
checkBox1.setOnAction(checkBoxHandler); checkBox2.setOnAction(checkBoxHandler);
CheckBox Code
private class CheckBoxHandler implements EventHandler<ActionEvent> {@Override
public void handle(ActionEvent e) {
if(e.getTarget() == checkBox1) {
System.out.println("Checkbox 1 clicked"); }
else if(e.getTarget() == checkBox2) {
System.out.println("checkBox 2 clicked"); }
else if(e.getTarget() == checkBox3) {
System.out.println("checkBox 3 clicked"); }
CheckBox Selected or Deselected
• Usually want to do something based on
whether or not the checkbox was just selected or deselected
CheckBox Selected Code
@Override
public void handle(ActionEvent e) {
if(e.getTarget() == checkBox1) {
if(checkBox1.isSelected()) {
System.out.println("Checkbox 1 selected"); }
else {
Radio Buttons
• These work the same way CheckBoxes do
• Probably want to create a ToggleGroup object to add all the radio buttons to
– This has no impact on the handlers
Example – RadioButtonHandlerExample.java
Radio Button Code
radioButton1 = new RadioButton("Radio Button 1"); radioButton2 = new RadioButton("Radio Button 2"); radioButton3 = new RadioButton("Radio Button 3");
radioButtonHandler = new radioButtonHandler();
Radio Button Code
private class RadioButtonHandler implements EventHandler<ActionEvent> {@Override
public void handle(ActionEvent e) {
if(e.getTarget() == radioButton1) {
System.out.println("Radio Button 1 selected"); }
else if(e.getTarget() == radioButton2) {
System.out.println("Radio Button 2 selected"); }
else if(e.getTarget() == radioButton3) {
System.out.println("Radio Button 3 selected"); }
ComboBox
• ComboBoxes also work the same was as all
other buttons
• ComboBoxes also can use a ChangeListener
Example – ComboBoxHandlerExample.java
ComboBox Code
comboBox1 = new ComboBox();
comboBox1.getItems().addAll("Choice 1", "Choice 2", "Choice 3");
comboBox1.setMaxWidth(Double.MAX_VALUE); comboBox1.setVisibleRowCount(10);
ComboBox Code
@Override
public void handle(ActionEvent e) {
if(e.getTarget() == comboBox1) {
System.out.println("ComboBox 1 choice " +
(comboBox1.getSelectionModel().getSelectedIndex() + 1) + " selected");
ComboBox Methods
• comboBox1.getSelectionModel()
– This method returns the selection model
• getSelectedIndex()
– Returns the index of the ComboBox choice selected
• Can also get the selected item
ChangeListener
• ChangeEvents for detecting changes
• Different from ActionEvents
• Need another handler to listen for these
• Need to register the ComboBox to this listener
too
• Used for when we just want to detect the state has changed
ComboBox ChangeListener Code
comboBoxHandler2 = new ComboBoxHandler2();
comboBox1.valueProperty().addListener(comboBoxHan dler2);
This adds a Listener to the comboBox
This is generic for all listeners for the ComboBox
ComboBox ChangeListener Code
private class ComboBoxHandler2 implements ChangeListener<String> {
@Override
public void changed(ObservableValue<? extends String> o, String from, String to) {
System.out.println("Changed from " + from + " to " + to); }
ComboBox Events
• Notice how choosing a choice fired both an action event and a change event
TextField
• TextFields have two main types of events
Example – TextHandlerExample.java
TextField ActionEvent Code
• textHandler2 = new TextHandler2(); • textField1.setOnAction(textHandler2);
• This adds textHandler2 as an ActionEvent listener
TextField ActionEvent Code
private class TextHandler2 implements EventHandler<ActionEvent> {
@Override
public void handle(ActionEvent e) {
if(e.getTarget() == textField1) {
System.out.println(textField1.getText()); }
KeyEvent
• Can listen events for keys
– KeyPressed = when a key is pushed down
• setOnKeyPressed()
– KeyReleased = when a key is let back up
• setOnKeyReleased()
– KeyTyped = when a key is pressed and released
KeyEvent Code
textHandler = new TextHandler();KeyEvent Code
private class TextHandler implements EventHandler<KeyEvent>
{
@Override
public void handle(KeyEvent e) {
if(e.getTarget() == textField1) {
if(e.getEventType() == KeyEvent.KEY_PRESSED) {
System.out.println(e.getText() + " Pressed"); }
else if(e.getEventType() == KeyEvent.KEY_RELEASED) {
System.out.println(e.getText() + " Released"); }
else if(e.getEventType() == KeyEvent.KEY_TYPED) { System.out.println(e.getText() + " Typed");
getEventType()
• In this example the same handler is set to
listen to three events
– KeyEvent.KEY_PRESSED – KeyEvent.KEY_RELEASED – KeyEvent.KEY_TYPED
KeyEvent
• Can also detect certain keys • KeyEvent class methods
– getCode = returns the key code
– getText = returns the text of the key
MouseEvent
• Components can listen for various MouseEvents
• MouseEvent
– MOUSE_CLICKED
• when the mouse is pressed and released
– MOUSE_PRESSED
• when the mouse is pressed
– MOUSE_RELEASED
MouseEvent
• MouseEvent
– MOUSE_MOVED
• when the mouse moves inside a component
– MOUSE_ENTERED
• when the mouse enters a component
– MOUSE_EXITED
• when the mouse exits a component
– MOUSE_DRAGGED
MouseEvent
• Can have any node listen for mouse events
– Labels
– TextFields – Shapes
– Buttons
Functions – Node class
• setOnMouseClicked • setOnMouseDragged
• setOnMouseEntered
• setOnMouseExited
• setOnMouseMoved
• setOnMousePressed
Example – MouseHandlerExample.java
Adding Handlers Code
label1 = new label("Click Here");
mouseHandler = new MouseHandler();
MouseEvent Handler
private class MouseHandler implements EventHandler<MouseEvent>
{
@Override
public void handle(MouseEvent e) {
if(e.getTarget() == label1) {
MouseEvent Functions
• getButton()
– Determine which mouse button was clicked
• getScreenX()
– X position the mouse was clicked at
• getScreenY()
MouseButton
• Class has constants to compare the mouse button to
– PRIMARY = primary mouse button (usually left)
– SECONDARY = secondary mouse button (usually right) – MIDDLE = middle mouse button
MouseHandler Code
if(e.getButton() == MouseButton.PRIMARY){
if(e.getEventType() == MouseEvent.MOUSE_PRESSED) {
System.out.println("Left Mouse Pressed"); }
else if(e.getEventType() == MouseEvent.MOUSE_RELEASED) {
System.out.println("Left Mouse Pressed"); }
Logic Note
• It might be possible to have a released event
without a pressed event
– Click in one node
– Do not released the mouse – Move into another node – Release the mouse
– Try this and see what happens.
Restructure Code For more Events
• Check for the source
– if(e.getTarget() == label1)
• Check for the event type
– if(e.getEventType() == MouseEvent.MOUSE_PRESSED)
• Check for the button type (if applicable)
More Mouse Handling Code
else if(e.getEventType() == MouseEvent.MOUSE_CLICKED) {
if(e.getButton() == MouseButton.PRIMARY) { System.out.println("Left Mouse Clicked"); }
else if(e.getButton() == MouseButton.SECONDARY) {
Event Process
• Target Selection
• Route Construction
• Event Capturing
Target Selection
• Determine which node fired the event
Target Selection Example
• Clicking on the triangle will choose the
Route Construction
• Initial route determined by event dispatch
chain
• Initial route can be modified by
– Event filters
– Event Handlers
Route Construction Example
Event Capturing
• Event flows along the event dispatch chain • If there are any nodes that have filters, those
filters are called
– Filters are the same as handlers
– They capture things on the way down the chain
• Can consume the event and stop the event flow
• Event reaches the bottom of the chain and the
Event Bubbling
• Once the event is processed it returns back up
the chain of events
• The event is processed by any registered
Example
• Register filter for rectangle • Register handler for triangle
Example
• When I click on the triangle the following
happens
• Event filter for rectangle is executed
Example 2
• Register filter for rectangle
– Consume the event in the filter
Example
• When I click on the triangle the following
happens
• Event filter for rectangle is executed • Event is consumed
Event Chain Reference
• http://
When to Consume Events
• Scenario
– You have one component that contains another
• Let component x contain component y
– Both components listen for button clicks – You click on component y
– You do not want the event handler for component
x to execute
– You should consume the event in the event handler