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

No comments:

Post a Comment

© 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