java - 使用 KeyListener 更改颜色

标签 java swing methods colors keylistener

我有一个项目,一个圆圈带有随机的 x 和 y 值以及选定的颜色,但是当用户按下空格键时,圆圈的颜色必须改变。我的圆圈同时移动 x 和 y 坐标,并且我想在按下空格按钮时更改圆圈的颜色。但当我按下它时它不起作用。它与原来的颜色相配。那么我怎样才能使这段代码正确呢?

public class c {
    private int x,y,r;
    private Color co;
    private int Re,G,B;
    private Random ran;

    public c() {
        // TODO Auto-generated constructor stub
        ran= new Random();
        x=100;
        y=50;
        r= ran.nextInt(200)+50;
        Re=ran.nextInt(255);
        G=ran.nextInt(255);
        B=ran.nextInt(255);
        co= new Color(Re,G,B); 
    }

    public int getRe() {
        return Re;
    }

    public int getG() {
        return G;
    }

    public int getB() {
        return B;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getR() {
        return r;
    }
    public void setCo(int Re,int G,int B) {
        co= new Color(Re,G,B);
    }
    public Color getCo() {
        return co;
    }

    public Random getRan() {
        return ran;
    }
    public void setX(int x) {
        this.x=x;
    }
    public void setY(int y) {
    this.y=y;
    }

}



public class Circle extends JFrame implements ActionListener,KeyListener{

    private Timer timer;
    private int x,y,a=5,b=5;
    private Random rand;
    c circ = new c();
    public Circle() {
        setLayout(new BorderLayout());
        x=circ.getX();
        y=circ.getY();
        timer=new Timer(50,this);
        timer.start();
        addKeyListener(this);
        setSize(550,550);
        setVisible(true);

    }

    public void paint(Graphics g) {
        super.paint(g);
        g.fillOval(x,y,100,100);
        g.setColor(circ.getCo());
    }


    public static void main(String[]args) {
        new Circle();
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        moveWithTimer();
        repaint();      
    }

    public void moveWithTimer() {

        x=x+b;
        y=y+a;
    if(x<0) {
        b=5;
    }

    if(x+50>500) {
        b=-5;
    }

    if(y<0){
        a=5;
    }

    if(y+50>500) {
        a=-5;
    }



    }

    @Override
    public void keyPressed(KeyEvent e) {
        // TODO Auto-generated method stub
       if(e.getKeyCode()==e.VK_SPACE) {
           circ.setCo(rand.nextInt(255),rand.nextInt(255),rand.nextInt(255));


       }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub

    }

}

最佳答案

But it does not work when I pressed it. It goes with its original color. So how can I make this code right?

KeyListener善变,最好使用Key Bindings API它克服了 KeyListener 的主要与焦点相关的问题。

作为一般经验法则,您不应覆盖 paint顶级容器,如 JFrame ,它们是复合组件,真是一团糟。

相反,以 JPanel 开头并覆盖它的 paintComponent方法。一般情况下是比较灵活的。看看Performing Custom Painting了解更多详情。

您的移动代码错误。您分配 x/y循环类的值到其他一些变量,这里的问题是,改变这些变量的值不会影响你的循环类中的变量,相反,你需要将它们分配回来...

public void moveWithTimer() {
    int x = circ.getX();
    int y = circ.getY();

    x = x + b;
    y = y + a;
    if (x < 0) {
        b = 5;
    }

    if (x + 50 > 500) {
        b = -5;
    }

    if (y < 0) {
        a = 5;
    }

    if (y + 50 > 500) {
        a = -5;
    }

    circ.setX(x);
    circ.setY(y);

}

您的“circle”类还可以使用一些附加方法。一种用于随机化颜色(它已经有一个 Random 对象,不妨使用它),另一种用于绘制对象。

public class Circle {
    //...

    public void paint(Graphics2D g2d) {
        g2d.setColor(co);
        g2d.fillOval(x, y, r * 2, r * 2);
    }

    //...

    public void randomColor() {
        setCo(ran.nextInt(255), ran.nextInt(255), ran.nextInt(255));
    }

    //...

}

如果是我,我会很想添加 move方法也是如此,但这就是我;)

作为一个可运行的示例...

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Random;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private Timer timer;
        private int a = 5, b = 5;
        private Random rand;
        private Circle circ = new Circle();

        public TestPane() {
            timer = new Timer(50, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    moveWithTimer();
                    repaint();
                }
            });
            timer.start();

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "spaced");
            am.put("spaced", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    circ.randomColor();
                    repaint();
                }
            });
        }

        public void moveWithTimer() {
            int x = circ.getX();
            int y = circ.getY();

            x = x + b;
            y = y + a;
            if (x < 0) {
                b = 5;
            }

            if (x + 50 > 500) {
                b = -5;
            }

            if (y < 0) {
                a = 5;
            }

            if (y + 50 > 500) {
                a = -5;
            }

            circ.setX(x);
            circ.setY(y);

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(500, 500);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            circ.paint(g2d);
            g2d.dispose();
        }

    }

    public class Circle {

        private int x, y, r;
        private Color co;
        private int Re, G, B;
        private Random ran;

        public Circle() {
            // TODO Auto-generated constructor stub
            ran = new Random();
            x = 100;
            y = 50;
            r = ran.nextInt(50) + 50;
            Re = ran.nextInt(255);
            G = ran.nextInt(255);
            B = ran.nextInt(255);
            co = new Color(Re, G, B);
        }

        public void paint(Graphics2D g2d) {
            g2d.setColor(co);
            g2d.fillOval(x, y, r * 2, r * 2);
        }

        public int getRe() {
            return Re;
        }

        public int getG() {
            return G;
        }

        public int getB() {
            return B;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

        public int getR() {
            return r;
        }

        public void randomColor() {
            setCo(ran.nextInt(255), ran.nextInt(255), ran.nextInt(255));
        }

        public void setCo(int Re, int G, int B) {
            co = new Color(Re, G, B);
        }

        public Color getCo() {
            return co;
        }

        public Random getRan() {
            return ran;
        }

        public void setX(int x) {
            this.x = x;
        }

        public void setY(int y) {
            this.y = y;
        }

    }

}

关于java - 使用 KeyListener 更改颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47198752/

相关文章:

java - 如何使用velocity模板生成二维码

java - JComboBox 和 vetoableChange?

java - 界面 : setSize() method of second window does not work

java - 我在 Java 中的方法找不到变量的值并将其设置为 0。我做错了什么?

objective-c - 我应该将托管对象上下文作为方法的参数包含在内吗?

c++ - 想要分配 std::string 但编译器认为是 bool

java - jps 不工作

java - 如果单例 getInstance() 方法未同步,Junit 测试将失败

java - 使用 Mapstruct 将实体转换为不可变模型对象时单元测试失败

java - 是否可以阻止一次触发 Action 监听器?