简体   繁体   English

AWT KeyListener滞后于输入

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM