Showing posts with label swing events. Show all posts
Showing posts with label swing events. Show all posts

Wednesday, January 25, 2012

Creating Listeners Containing a Single Method Call


Java SE 1.4 introduces a mechanism that lets you specify simple event listeners without programming inner classes. (I am one of those people who doesn't like to use inner classes much, so I take any opportunity that is available to avoid using them) For example, suppose you have a button labeled “Load” whose event handler contains a single method call:
frame.loadData();

Of course, you can always use an anonymous inner class:

loadButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
frame.loadData();
}
});


But the EventHandler class can create such a listener automatically, with the call
EventHandler.create(ActionListener.class, frame, "loadData")

Of course, you still need to install the handler:
loadButton.addActionListener(EventHandler.create(ActionListener.class, frame, "loadData"));

If the listener calls a method with a single parameter that can be obtained from the event parameter, you can use another form of the create method. For example
EventHandler.create(ActionListener.class, frame, "loadData", "source.text")

is equivalent to


new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
frame.loadData(((JTextField) event.getSource()).getText());
}
}



The property names source and text turn into method calls getSource and getText.

A Working Example:

Let us understand the usage of these single method calls better with a simple example.
As you might have figured out by now, Swing programs use the Metal look and feel by default (We haven’t set any look and feel till now in our Swing programs, or have we?) There are two ways to change to a different look and feel. The first way is to supply a file swing.properties in the jre/lib subdirectory of your Java installation. In that file, set the property swing.defaultlaf to the class name of the look and feel that you want. For example:
swing.defaultlaf=com.sun.java.swing.plaf.motif.MotifLookAndFeel

Note that the Metal look and feel is located in the javax.swing package. The other look-and-feel packages are located in the com.sun.java package and need not be present in every Java implementation. Currently, for copyright reasons, the Windows and Macintosh look-and-feel packages are only shipped with the Windows and Macintosh versions of the Java runtime environment.
The second way is to change the look and feel dynamically. Call the static UIManager.setLookAndFeel method and give it the name of the look-and-feel class that you want. Then call the static method SwingUtilities.updateComponentTreeUI to refresh the entire set of components. You need to supply one component to that method; it will find all others. The UIManager.setLookAndFeel method may throw a number of exceptions when it can’t find the look and feel that you request, or when there is an error loading it. Worrying about those exceptions is currently out of our scope and we will deal with them later.

Here is an example showing how you can switch to the Motif look and feel in your program:


String plaf = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
try
{
UIManager.setLookAndFeel(plaf);
SwingUtilities.updateComponentTreeUI(panel);
}
catch(Exception e) { e.printStackTrace(); }



To list down all installed look and feel implementations, call

UIManager.LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels();

Then you can get the name and class name for each look and feel as below:
String name = infos[i].getName();
String className = infos[i].getClassName();

Lets now look at the code for a class that will dynamically change the look and feel of our screen. Our code will identify the available look and feel based on the code snippet above and create buttons dynamically mentioning them. When we click on each of the buttons, the look and feel of the frame and the components inside it will change dynamically.

Code:


import java.awt.EventQueue;
import java.awt.event.*;
import javax.swing.*;

/**
* @version 1.1 02-June-2011
* @author Anand Vijayakumar
*/
public class TestLookNFeel
{
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
LookNFeelFrame frame = new LookNFeelFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}

/**
* A frame with a button panel for changing look and feel
*/
class LookNFeelFrame extends JFrame
{
public LookNFeelFrame()
{
setTitle("Look N Feel Test");
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);

buttonPanel = new JPanel();

UIManager.LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels();
for (UIManager.LookAndFeelInfo info : infos)
makeButton(info.getName(), info.getClassName());

add(buttonPanel);
}

/**
* Makes a button to change the look and feel.
*/
void makeButton(String name, final String plafName)
{
// add button to panel

JButton button = new JButton(name);
buttonPanel.add(button);

// set button action

button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
// button action: switch to the new look and feel
try
{
UIManager.setLookAndFeel(plafName);
SwingUtilities.updateComponentTreeUI(LookNFeelFrame.this);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}

private JPanel buttonPanel;

public static final int DEFAULT_WIDTH = 300;
public static final int DEFAULT_HEIGHT = 200;
}


If you run this code, you may get a different number of buttons in your computer. I got 4 in mine and the output if I click on each is as follows:


Previous: Basics of Event Handling

Tuesday, May 31, 2011

Basics of Event Handling

In the previous chapters, we had seen how to create various Swing UI components. What good is a UI component that cannot handle user actions? Lets say you want to open a pop up when the user clicks a button or you want to save some data user entered in the screen when he clicks save, how would you do it?

Event Handling is your answer. Each of the two examples mentioned above are user stimulated events and using event handling, we can handle the events and take appropriate action.

The next thing your mind says is, what is event handling? Right??

Well, that is exactly what we are going to learn in this and the next few chapters.

So, lets get started!!!

What is Event Handling?

Any operating environment that supports GUIs constantly monitors events such as keystrokes or mouse clicks. The operating environment reports these events to the programs that are running. Each program then decides what, if anything, to do in response to these events. For example, if you use the start menu and then click on My Computer, the OS identifies the fact that you want to view the details of your computer and opens up the Explorer window. The click on the icon is an event and the opening of the explorer window is how the OS handles the event.

As one would expect in an object-oriented language like Java, the information about the event is encapsulated in an event object. In Java, all event objects ultimately derive from the class java.util.EventObject. Of course, there are subclasses for each event type, such as ActionEvent and WindowEvent.
Different event sources can produce different kinds of events. For example, a button can send ActionEvent objects, whereas a window can send WindowEvent objects.

Below is how Events are handled in AWT:
• A listener object is an instance of a class that implements a special interface called a listener interface.
• An event source is an object that can register listener objects and send them event objects.
• The event source sends out event objects to all registered listeners when that event occurs.
• The listener objects will then use the information in the event object to determine their reaction to the event.

Look at the image below to understand the relationship between event sources and listeners.


Below is how you will specify a listener to a component, say a Button.

ActionListener listener = . . .;
JButton button = new JButton("Ok");
button.addActionListener(listener);

Now the listener object is notified whenever an “action event” occurs in the button. For buttons, as you rightly guessed, an action event is a button click.

To implement the ActionListener interface, the listener class must have a method called actionPerformed that receives an ActionEvent object as a parameter.

class MyListener implements ActionListener
{
. . .
public void actionPerformed(ActionEvent event)
{
// code to handle button click goes here
. . .
}
}

Whenever the user clicks the button, the JButton object creates an ActionEvent object and calls listener.actionPerformed(event), passing that event object. An event source such as a button can have multiple listeners. In that case, the button calls the actionPerformed methods of all listeners whenever the user clicks the button.

You can understand the event notification system by looking at the image below:


A Working Example:

Let us wrap up this chapter by looking at a full fledged example.

Let us say we want to have 3 buttons in our screen and 3 different actions must happen when the user clicks on them. For simplicity lets have the screen filled with 3 different colors when the user clicks on each of them.

Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
* @version 1.1 31-May-2011
* @author Anand Vijayakumar
*/
public class TestButtonActions
{
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
MyTestFrame frame = new MyTestFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}

/**
* A frame with a button panel
*/
class MyTestFrame extends JFrame
{
public MyTestFrame()
{
setTitle("Button Action Test");
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);

// create buttons
JButton redButton = new JButton("Red");
JButton blueButton = new JButton("Blue");
JButton greenButton = new JButton("Green");

buttonPanel = new JPanel();

// add buttons to panel
buttonPanel.add(redButton);
buttonPanel.add(blueButton);
buttonPanel.add(greenButton);

// add panel to frame
add(buttonPanel);

// create button actions
HandleActions greenAction = new HandleActions(Color.GREEN);
HandleActions blueAction = new HandleActions(Color.BLUE);
HandleActions redAction = new HandleActions(Color.RED);

// associate actions with buttons
greenButton.addActionListener(greenAction);
blueButton.addActionListener(blueAction);
redButton.addActionListener(redAction);
}

/**
* An action listener that sets the panel's background color.
*/
private class HandleActions implements ActionListener
{
public HandleActions(Color c)
{
backgroundColor = c;
}

public void actionPerformed(ActionEvent event)
{
buttonPanel.setBackground(backgroundColor);
}

private Color backgroundColor;
}

private JPanel buttonPanel;

public static final int DEFAULT_WIDTH = 300;
public static final int DEFAULT_HEIGHT = 200;
}


If you compile and run this class your output will be like below:


On click of Red:


On click of Blue:


On click of Green:



Prev: Displaying Images

Next: Creating Listeners Containing a Single Method Call
© 2013 by www.inheritingjava.blogspot.com. All rights reserved. No part of this blog or its contents may be reproduced or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without prior written permission of the Author.

ShareThis

Google+ Followers

Followers