Haris Rabbani
Haris Rabbani

Reputation: 25

How can I add a key listener if I already implement an action listener in the class?

I would like to add a key listener events to 3 of my TextFields:

angleText, initialVelocityText, and accelerationText

I would like to reject characters except for decimal dots and also keep backspaces, and also accept numbers.

Thank you in advance - This has been fixed - Thanks especially to @AliGul for his response and thanks to the others too

This is the code from the class I am talking about:

package projectV1;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.*;






public class Simulation extends JPanel {
//Initialise all the variables
private int BOX_WIDTH = 1920;
private int BOX_HEIGHT = 1080;

public String angle, distance, height , acceleration, initialVelocity, velocity, time; // Keep all as string until calc
public int x, y ,vx, vy;
private boolean isRunning; 
public JFrame simFrame;
public JPanel  inputPanel;
public Animate animatePanel;
public JButton start, apply;
public boolean validation = false;
    public static TextField accelerationText;
    public static TextField angleText;
    public static TextField initialVelocityText;
    public static TextField velocityText;
    public static TextField distanceText;
    public static TextField timeText;
    public static TextField heightText;


//FOR THE APPLY BUTTON JUST HAVE ONE OF THOSE BUT HAVE MULTIPLE BOXES WHICH YOU CAN CHANGE THE VALUE OF


// This will have my JPanel for the animatePanel, the animate panel will have the next class acting on it for the
// animation of the program.
// SO now we have the 2 panels that we need, in the bottom panel we will have the buttons and text fields, 
// will be variable holders and can be changed, we need to figure out the logic of how that will come to working.

public Simulation() {


    simFrame = new JFrame("Simulation");
     Main.setJFrame(simFrame);
     inputPanel = new JPanel(new GridLayout(2,7));
     animatePanel = new Animate();
     inputPanel.setBackground(Color.WHITE);
     animatePanel.setBackground(Color.LIGHT_GRAY);
     simFrame.add(inputPanel, BorderLayout.NORTH);
     simFrame.add(animatePanel, BorderLayout.CENTER);
     gui();

    }
  public void gui(){
    JLabel a,b,c,d,e,f,g; // These are just initialising the JLabels for the text fields

    // WHAT i attempted to do here is to make it so that adding these variables gets the things

    time = "0";
     acceleration = "9.81";
     initialVelocity = "10";
     distance = "0";
     height = "0";
     velocity = "0";
     angle = "45";
     // Place all the swing elements, I use a grid layout

     a = new JLabel("Current Velocity: ",JLabel.CENTER);
     a.setToolTipText("The velocity that the ball is currently moving at");
     inputPanel.add(a);
     velocityText = new TextField(velocity);
     inputPanel.add(velocityText);

     b = new JLabel("Current Distance:  ",JLabel.CENTER);
     b.setToolTipText("What the distance horizontally that the ball is travelling at");
     inputPanel.add(b);
     distanceText = new TextField(distance);
     inputPanel.add(distanceText);

     c = new JLabel("Current Height: ",JLabel.CENTER);
     c.setToolTipText("The current vertical height of the ball");
     inputPanel.add(c);
     heightText = new TextField(height);
     inputPanel.add(heightText);

     d = new JLabel("Current Time Elapsed: ",JLabel.CENTER);
     d.setToolTipText("The time elapsed, this relates to the motion of the ball");
     inputPanel.add(d);
     timeText = new TextField(time);
     inputPanel.add(timeText);

     e = new JLabel("Input Initial Velocity ",JLabel.CENTER);
     e.setToolTipText("How fast should the ball start as?");
     inputPanel.add(e);
     initialVelocityText = new TextField(initialVelocity);


     inputPanel.add(initialVelocityText);

     f = new JLabel("Input Acceleration",JLabel.CENTER);
     f.setToolTipText("Whats the acceleration); 9.81 is due to gravity on earth, try 1.6, its the moon's");
     inputPanel.add(f);
     accelerationText = new TextField(acceleration);
     inputPanel.add(accelerationText);

     g = new JLabel("Input angle (degrees): ",JLabel.CENTER);
     g.setToolTipText("Angle of attack? Please enter a value between 1 and 90");
     inputPanel.add(g);
     angleText = new TextField(angle);

     inputPanel.add(angleText);

     apply = new JButton("Apply Changes"); // This will apply changes put in text fields.
     inputPanel.add(apply);

     start = new JButton("Start Simulation"); // This will apply and start the timer and send all the variables.
     inputPanel.add(start);

     apply.addActionListener(new ActionListener(){
         public void actionPerformed(ActionEvent e){
             apply();
         }
     });
     start.addActionListener(new ActionListener(){
         public void actionPerformed(ActionEvent e){
             apply();
             simulate(acceleration, angle, initialVelocity);
              }
     });
      }

  private void apply(){ // ADD VALIDATION FOR THIS BEFORE THE CODE IS DONE
    int count = 0;

    angle = angleText.getText();
    if (validateAngle(angle)){
        count = count +1;
    }
    angle = convertToRadians(angle);
    acceleration = accelerationText.getText();
    if (validateAcceleration(acceleration)){
        count = count +1;
    }
    initialVelocity = initialVelocityText.getText();
    if (validateInitialVelocity(initialVelocity)){
        count = count +1;
        }
    if (count ==3){
        validation = true;
    }
    }

public void simulate(String acceleration, String angle, String initialVelocity){


    // apply();
    if (validation){

    animatePanel.start(acceleration, initialVelocity, angle);
    } else {
        JOptionPane.showMessageDialog(animatePanel, "Re-enter values");
    }
    }

public String convertToRadians(String angle){ // Does a conversion to get the angle in degrees to radians.
    double angleToRadians = 0;
    angleToRadians = Double.parseDouble(angle);
    angleToRadians = (Math.PI*angleToRadians)/180;
    angle = Double.toString(angleToRadians);
    return angle;
}

public boolean validateAcceleration(String acceleration){
    double tempAcc = Double.parseDouble(acceleration);
    if (isDouble(acceleration)){
        if (tempAcc>0){
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }

    }


public boolean validateAngle(String angle){
    double tempAngle = Double.parseDouble(angle);
    if (isDouble(angle)){
        if (tempAngle>=1 && tempAngle<= 90){
            return true;
        } else {
            return false;
        }
        } else {
        return false;
    }

}


public boolean validateInitialVelocity(String initialVelocity){
    double tempVel = Double.parseDouble(initialVelocity);
    if (isDouble(initialVelocity)){
        if (tempVel >1){
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }
}

public boolean isDouble(String str) {
    try {
        Double.parseDouble(str);
        return true;
    } catch (NumberFormatException e) {
        return false;
    }
}

}

Upvotes: 1

Views: 229

Answers (3)

MadProgrammer
MadProgrammer

Reputation: 347314

I would like to reject characters except for decimal dots and also keep backspaces, and also accept numbers.

KeyListener is not the appropriate mechanism to achieve this (in fact KeyListener is generally not the appropriate mechanism for a lot of things), instead you should be using a DocumentFilter

There are countless examples:

Upvotes: 1

Ali Gul
Ali Gul

Reputation: 115

Hope this helps.

angleText.addKeyListener(new KeyAdapter() { //disables everything except number and dots
        public void keyTyped(KeyEvent e) {
            char input = e.getKeyChar();
            if ((input < '0' || input > '9') && input != '\b' && input != '.') {
                e.consume(); 
            }
        }
    });

Then, just change the 'angleText' part to 'initialVelocityText' etc.

Upvotes: 0

Webster
Webster

Reputation: 164

Have you tried using a focusListener ?

In short you would check when the focus is lost on either text fields, and validate wether the input fits your requirements, using a special method and a RegExp for your constraints.

Or you could use a FormattedTextField

Upvotes: 0

Related Questions