[英]AWT KeyListener Lagging on Input
I'm creating a simple Java circle calculator but am having issues getting my KeyListeners to respond quickly. 我正在创建一个简单的Java圆计算器,但是在使我的KeyListener快速响应时遇到了问题。 The x and y values in the Circle class are not stored immediately but rather when I delete the input. Circle类中的x和y值不会立即存储,而是在删除输入时存储。 For example if I input 3 for x and 5 for y the Circle class is returning values of 0 until I delete the values, then it will return the proper values. 例如,如果我为x输入3,为y输入5,Circle类将返回0的值,直到删除这些值为止,然后它将返回正确的值。 My goal is to immediately display data related to this coordinates when the user enters values. 我的目标是在用户输入值时立即显示与此坐标相关的数据。 I can't do this while the KeyListeners are lagging. KeyListeners滞后时,我无法执行此操作。 Thank you. 谢谢。
**Edit: Just realized that the values will also be correct if I hit another key afterwards (like ctrl for example) **编辑:刚意识到如果我之后再按另一个键(例如ctrl),这些值也将是正确的
**2nd Edit: Added Circle code at bottom **第二次编辑:在底部添加了圈子代码
**3rd Edit: Added Point code at bottom **第三次编辑:在底部添加了点代码
Here is my code: 这是我的代码:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.text.DecimalFormat;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class CircleGUI extends JFrame
{
Circle c;
JFrame frame;
DecimalFormat df;
private JPanel panel;
private JLabel radiusLabel, areaLabel, coordinateLabel, containsPointLabel;
private JButton calculateButton;
private JTextField radiusTextField, xTextField, yTextField;
final int WINDOW_WIDTH = 500;
final int WINDOW_HEIGHT = 300;
public static void main(String[] args)
{
Circle c = new Circle();
CircleGUI test = new CircleGUI(c);
}
public CircleGUI(Circle c)
{
this.c = c;
setTitle("Circle Calculator");
setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
buildPanel();
add(panel);
df = new DecimalFormat("#.##");
setVisible(true);
}
private JPanel buildPanel()
{
radiusLabel = new JLabel("Enter radius:");
areaLabel = new JLabel();
radiusTextField = new JTextField(15);
calculateButton = new JButton("Calculate Area");
calculateButton.addActionListener(new CalculateAreaButtonListener());
coordinateLabel = new JLabel("Origin of the Circle:");
containsPointLabel = new JLabel("");
xTextField = new JTextField(4);
xTextField.addKeyListener(new xCoordinateTextFieldListener());
yTextField = new JTextField(4);
yTextField.addKeyListener(new yCoordinateTextFieldListener());
panel = new JPanel();
//panel.setLayout(new FlowLayout());
panel.add(radiusLabel);
panel.add(radiusTextField);
panel.add(calculateButton);
panel.add(areaLabel);
panel.add(coordinateLabel);
panel.add(xTextField);
panel.add(yTextField);
panel.add(containsPointLabel);
return panel;
}
private class CalculateAreaButtonListener implements ActionListener
{
@Override
public void actionPerformed(ActionEvent e)
{
areaLabel.setText(String.valueOf(df.format(calculateArea())));
}
public double calculateArea()
{
double radius = Double.parseDouble(radiusTextField.getText());
c.setRadius(radius);
return c.getArea();
}
}
private class xCoordinateTextFieldListener implements KeyListener
{
@Override
public void keyPressed(KeyEvent e)
{
double x;
if (!xTextField.getText().equals(null) && !xTextField.getText().equals(""))
{
x = Double.parseDouble(xTextField.getText());
c.setX(x);
}
}
@Override
public void keyReleased(KeyEvent e)
{
System.out.println("x: " + c.getX());
}
@Override
public void keyTyped(KeyEvent arg0)
{
}
}
private class yCoordinateTextFieldListener implements KeyListener
{
@Override
public void keyPressed(KeyEvent e)
{
double y;
if (!yTextField.getText().equals(null) && !yTextField.getText().equals(""))
{
y = Double.parseDouble(yTextField.getText());
c.setY(y);
}
;
}
@Override
public void keyReleased(KeyEvent e)
{
System.out.println("y: " + c.getY());
}
@Override
public void keyTyped(KeyEvent arg0)
{
}
}
}
Circle code: 圈子代码:
public class Circle
{
//Instantiate and declare instance fields
Point origin = new Point();
double radius;
Circle(double radius)
{
this.radius = radius;
origin.setX(0);
origin.setY(0);
}
//Two arg-constructor
Circle(Point origin, double radius)
{
this.origin = origin;
this.radius = radius;
}
//Three-arg constructor
Circle(double xValue, double yValue, double radius)
{
origin.setX(xValue);
origin.setY(yValue);
this.radius = radius;
}
//Default constructor
Circle()
{
setX(0);
setY(0);
radius = 0;
}
//Copy constructor
Circle(Circle c)
{
setX(c.getX());
setY(c.getY());
radius = c.getRadius();
}
//Get origin of the circle
Point getOrigin()
{
return origin;
}
//Set origin of the circle
void setOrigin(Point point)
{
this.origin = point;
}
//Set x value
void setX(double x)
{
origin.setX(x);
}
//Get x value
double getX()
{
return origin.getX();
}
//Set y value
void setY(double y)
{
this.origin.setY(y);
}
//Get y value
double getY()
{
return origin.getY();
}
//Set radius field
void setRadius(double radius)
{
this.radius = radius;
}
//Get radius field
double getRadius()
{
return radius;
}
//Get area of the circle
double getArea()
{
//Use constant provided in the static method Math.PI
return Math.PI * (radius * radius);
}
//Translate instance fields to a human readable String
public String toString()
{
return "x: " + this.getX() + ", y: " + this.getY() + ", radius: " + this.radius;
}
//Compare whether two circles instance fields are equal
boolean equals(Circle c)
{
if (getX() == c.getX() && getY() == c.getY() && getRadius() == c.getRadius())
return true;
else
return false;
}
double getDistance(double xValue, double yValue)
{
double x = xValue - this.getX();
double y = yValue - this.getY();
return Math.sqrt((x * x) + (y * y));
}
double getDistance(Circle c)
{
//Initialize variables to x^2-x^1 and y^2-y^1
double x = c.getX() - this.getX();
double y = c.getY() - this.getY();
//Calculate distance to center of the circle
return Math.sqrt((x * x) + (y * y));
}
boolean containsPoint(double xValue, double yValue)
{
if (getDistance(xValue, yValue) <= radius)
return true;
else
return false;
}
//Test if two circle overlap
boolean doesOverlap(Circle c)
{
//Initialize sumOfRadii to the sum of both circles radius
double sumOfRadii = c.getRadius() + radius;
//If the distance to the center of the circle is less than or equal to the sum of the two circles radius then return true, otherwise return false.
if (getDistance(c) <= sumOfRadii)
return true;
else
return false;
}
}
Point Code: 点代码:
public class Point
{
private double x;
private double y;
public Point(double xValue, double yValue)
{
x = xValue;
y = yValue;
}
public Point(Point p) {
this(p.x, p.y);
}
public Point() {
this(0, 0);
}
public void setX(double xValue)
{
this.x = xValue;
}
public double getX()
{
return x;
}
public void setY(double yValue)
{
this.y = yValue;
}
public double getY()
{
return y;
}
public boolean equals(Point otherPoint)
{
return (this.x == otherPoint.x) && (this.y == otherPoint.y);
}
public String toString() {
return "(" + x + ", " + y + ")";
}
}
Keylistener
is not the right choice for responding to changes in a text field. Keylistener
不是响应文本字段中更改的正确选择。 See How to Write a Document Listener for an alternate approach. 有关替代方法,请参见如何编写文档侦听器 。
Firstly, I wouldn't use a KeyListener
to monitor changes to a text field, a DocumentListener
would provide more useful information to the changes of the underlying field, but an ActionListener
would probably be more appropriate under these conditions. 首先,我不会使用KeyListener
来监视文本字段的更改, DocumentListener
会为基础字段的更改提供更多有用的信息,但是在这些情况下, ActionListener
可能更合适。
Take a look at How to write an Action Listener and How to use text fields for more details 看一看如何编写动作侦听器和如何使用文本字段以了解更多详细信息
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.