Coding tips - Java

Soldato
Joined
1 Mar 2003
Posts
5,508
Location
Cotham, Bristol
Afternoon folks, just after a bit of advise really, as there MUST be a better way of doing this. I have a GUI with a numpad type interface, now for each button 0-9 I have an action listener like so:

Code:
   private class Keypad0ActionListener implements ActionListener {
      public void actionPerformed(ActionEvent e) {
      	if(vmachine.giveChange()>0) {
      	   if(messageString=="MACHINE READY") 
      	      productCode = "0";
           else 
              productCode += "0";
	   balanceAmount = Double.toString(vMachine.giveChange);
      	   messageString = balance + balanceAmount +"\t" + product + productCode;              
           message.setText(messageString);	   
	} else {
	   message.setText("INSERT MONEY");
	   Thread.sleep(3000);
	   message.setText("MACHINE READY");
	}
      }
   }

Then later on I'll add the action Listener to the button like so

Code:
kpad0.addActionListener(new Keypad0ActionListener());

But seeing as each button basically has the same behaviour there must a better way of coding this, as If I decide I need to change the behaviour I have to change 10 actionPerformed() methods which is a bit of a maintenance nightmare

So over to you :)
 
give me about 10 mins and I'll see if one of the java guys here can help :D

Ok, but how do I then differentiate between which button has been pressed as in the example I've given productCode will be different depending upon which button has been pressed.

Edit: Woah sneaky ninja edit there, I even managed to quote your edit without noticing :p
 
Ok, but how do I then differentiate between which button has been pressed as in the example I've given productCode will be different depending upon which button has been pressed.

Edit: Woah sneaky ninja edit there, I even managed to quote your edit without noticing :p

You could use an anonymous (inner) class for each button - I seem to remember eons ago when doing Java at uni that's how a lot of tutorials handled GUI stuff.
 
You could use an anonymous (inner) class for each button - I seem to remember eons ago when doing Java at uni that's how a lot of tutorials handled GUI stuff.

Hmmm yeah but that would effectively be the same thing though wouldn't i.e. something like this

Plus anonymous and inner classes are two separate things, the example above is an inner class, the following is an anonymous class.

Code:
kpad0.addActionListener(new Keypad0ActionListener() implements ActionListener {
   public void actionPerformed(ActionEvent e) {
      if(vmachine.giveChange()>0) {
      	  if(messageString=="MACHINE READY") 
      	     productCode = "0";
          else 
             productCode += "0";
	  balanceAmount = Double.toString(vMachine.giveChange);
      	  messageString = balance + balanceAmount +"\t" + product + productCode;              
          message.setText(messageString);	   
      } else {
         message.setText("INSERT MONEY");
	 Thread.sleep(3000);
	 message.setText("MACHINE READY");
      }
   }
});

So I'd still have to do that for each button, again a maintenance issue
 
Last edited:
Have one listener for all values, then base your logic on the value of the button pressed?

It's a bit vague, but that's because there is no short sharp way of doing this.. this is what polymorphism is about. One listener to handle the actions of 10(+?) buttons, and within the action method for it, it uses the value for logic.

If it were a 500 button keypad.. would you code 500 actions?
 
Have one listener for all values, then base your logic on the value of the button pressed?

It's a bit vague, but that's because there is no short sharp way of doing this.. this is what polymorphism is about. One listener to handle the actions of 10(+?) buttons, and within the action method for it, it uses the value for logic.

If it were a 500 button keypad.. would you code 500 actions?

Ok so how about

Code:
private class KeypadActionListener implements ActionListener {
   private int keyValue;
   public KeypadActionListener(int keyValue) {
      this.keyValue = keyValue;
   }
   public void actionPerformed(ActionEvent e) {
      if(vmachine.giveChange()>0) {
         switch(keyValue) {
            case 0:
               if(messageString.equals("MACHINE READY")) 
      	         productCode = "0";
              else 
                 productCode += "0";
              break;
           //etc. etc. 
           //etc. etc.
         }
      }else {
         message.setText("INSERT MONEY");
	 Thread.sleep(3000);
	 message.setText("MACHINE READY");
      }
   }
}

That should work
 
There are a couple of ways to do this, you can either look at the source of the event (e.getSource()) and compare it against any of the things you've added the listener to to find the culprit, or derive JButton adding in some functionality to get a value from it.

Code:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;

public class Buttons extends JFrame{
  private JButton[] mMyButtons;
  private ActionListener mMyButtonListener;
  
  public Buttons(){
    super("Buttons");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    mMyButtons = new JButton[10];
    
    mMyButtonListener = new ActionListener(){
      public void actionPerformed(ActionEvent e){
        for(int i = 0; i < mMyButtons.length; i++){
          if(e.getSource() == mMyButtons[i]){
            System.out.println("Button: " + i);
            break;
          }
        }
      }
    };
    
    GridBagConstraints GBConst = new GridBagConstraints();
    GBConst.gridx = 0;
    GBConst.gridy = 0;
    GBConst.gridwidth = 1;
    GBConst.gridheight = 1;
    GBConst.anchor = GridBagConstraints.CENTER;
    GBConst.fill = GridBagConstraints.NONE;
    GBConst.insets = new Insets(0,0,0,0);
    GBConst.weightx = 1;
    GBConst.weighty = 1;
    
    getContentPane().setLayout(new GridBagLayout());
    
    for(int i = 0; i < mMyButtons.length; i++){
      mMyButtons[i] = new JButton("" + i);
      mMyButtons[i].addActionListener(mMyButtonListener);
      getContentPane().add(mMyButtons[i], GBConst);
      GBConst.gridy++;
    }
    
    pack();
    setVisible(true);    
  }
  
  public static void main(String[] args){
    new Buttons();
  }
}

Code:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;

public class Buttons1 extends JFrame{
  private cValuedJButton[] mMyButtons;
  private ActionListener mMyButtonListener;
  
  public Buttons1(){
    super("Buttons");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    mMyButtons = new cValuedJButton[10];
    
    mMyButtonListener = new ActionListener(){
      public void actionPerformed(ActionEvent e){
        System.out.println("Button: " + ((cValuedJButton)e.getSource()).GetValue());
      }
    };
    
    GridBagConstraints GBConst = new GridBagConstraints();
    GBConst.gridx = 0;
    GBConst.gridy = 0;
    GBConst.gridwidth = 1;
    GBConst.gridheight = 1;
    GBConst.anchor = GridBagConstraints.CENTER;
    GBConst.fill = GridBagConstraints.NONE;
    GBConst.insets = new Insets(0,0,0,0);
    GBConst.weightx = 1;
    GBConst.weighty = 1;
    
    getContentPane().setLayout(new GridBagLayout());
    
    for(int i = 0; i < mMyButtons.length; i++){
      mMyButtons[i] = new cValuedJButton(i);
      mMyButtons[i].addActionListener(mMyButtonListener);
      getContentPane().add(mMyButtons[i], GBConst);
      GBConst.gridy++;
    }
    
    pack();
    setVisible(true);    
  }
  
  public static void main(String[] args){
    new Buttons1();
  }
  
  protected class cValuedJButton extends JButton {
    int mValue;
    
    public cValuedJButton(int Value){
      super("" + Value);
      mValue = Value;
    }
    
    public int GetValue(){
      return mValue;
    }
  }
}

Examples of both above.
 
Ok so how about

*snip*

That should work
unf.. instead of switching on keyValue, why not just:
Code:
private class KeypadActionListener implements ActionListener {
   private int keyValue;
   public KeypadActionListener(int keyValue) {
      this.keyValue = keyValue;
   }
   public void actionPerformed(ActionEvent e) {
      if (vmachine.giveChange()>0) {
         if (messageString.equals("MACHINE READY")) {
            productCode = keyValue.toString();
         } else {
            productCode += keyValue.toString();
         }
      } else {
        message.setText("INSERT MONEY");
	 Thread.sleep(3000);
	 message.setText("MACHINE READY");
      }
   }
}
 
^^^ haha yes yes that would be easier, I think I must have a girls brain I always try to make things more complicated than they need to be.
 
Back
Top Bottom