Thursday, March 15, 2012

Inner Classes for Handling Listeners

It is a common practice in Java to use Inner classes to handle Listener events. An inner class is a private class contained in another class. As a private class it has access to all the fields and values of the containing class.

To me this is a violation of many OOP principles, such as encapsulation and the idea that classes should be as loosely coupled as possible. But, practically speaking, it is probably the best way to handle multiple events in a JPanel class.

Another practice is to use anonymous classes, which are inner classes that are not explicitly declared as such. I would discourage their use, even though they are also a common Java practice

Here is the code for a class that extends JPanel. It has two inner classes to handle the Listeners for two different buttons. This class, of course, would be called by a class extending JFrame.



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


public class PercentFormPanel extends JPanel{
 
 JPanel panel;
 JLabel lblAmount;
 JTextField txtAmount;
 JRadioButton tenPercent;
 JRadioButton fifteenPercent;
 JRadioButton twentyPercent;
 JLabel lblResult;
 JButton btnCalculate;
 JButton btnExit;
 
 public PercentFormPanel(){
 
  panel = new JPanel(new GridLayout(5,2,5,5));
  BuildPanel();
  this.add(panel);
  
 }
 private void BuildPanel(){
  lblAmount = new JLabel("Enter a Number and choose a percent");
  txtAmount= new JTextField(10);
  tenPercent=new JRadioButton("Ten Percent");
  fifteenPercent=new JRadioButton("Fifteen Percent");
  twentyPercent=new JRadioButton("Twenty Percent");
  
  ButtonGroup group = new ButtonGroup();
  group.add(tenPercent);
  group.add(fifteenPercent);
  group.add(twentyPercent);
  
  btnCalculate = new JButton("Calculate");
  //calls the internal class and its listener
  btnCalculate.addActionListener(new CalculateListener());
  
  lblResult = new JLabel();
  
  btnExit = new JButton("Exit");
  //calls internal class
  btnExit.addActionListener(new ExitListener());
  
  panel.add(lblAmount);
  panel.add(txtAmount);
  panel.add(tenPercent);
  panel.add(fifteenPercent);
  panel.add(twentyPercent);
  
  panel.add(lblResult);
  panel.add(btnCalculate);
  panel.add(btnExit);
 }
 
 //begin first internal class
 class CalculateListener implements ActionListener{
  public void actionPerformed(ActionEvent e){
   double percent;
   String amt = txtAmount.getText();
   if (amt.isEmpty())
    return;
   double amount=Double.parseDouble(amt);
   if (tenPercent.isSelected())
    percent=amount * .1;
   else if (fifteenPercent.isSelected())
    percent=amount *.15;
   else if (twentyPercent.isSelected())
    percent=amount * .2;
   else
    percent=amount;
   
   lblResult.setText(Double.toString(percent));
  }
  
 }
 
 //second internal class
 class ExitListener implements ActionListener{
  public void actionPerformed(ActionEvent e){
  
   System.exit(0);
  }
 }
 
 

}



No comments:

Post a Comment