Reputation: 25
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
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
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
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