Java 使用KeyListener更改颜色

Java 使用KeyListener更改颜色,java,swing,methods,colors,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() {

我有一个项目,一个圆圈带有随机的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

    }

}
公共c类{
私有整数x,y,r;
私人色彩公司;
私有整数Re,G,B;
私用随机数;
公共c(){
//TODO自动生成的构造函数存根
ran=新随机数();
x=100;
y=50;
r=ran.nextInt(200)+50;
Re=ran.nextInt(255);
G=ran.nextInt(255);
B=ran.nextInt(255);
co=新颜色(Re、G、B);
}
公共整数getRe(){
返回Re;
}
公共int getG(){
返回G;
}
公共int getB(){
返回B;
}
公共int getX(){
返回x;
}
公共int getY(){
返回y;
}
公共整数getR(){
返回r;
}
公共无效setCo(内部Re、内部G、内部B){
co=新颜色(Re、G、B);
}
公共颜色getCo(){
返回公司;
}
公共随机getRan(){
回程跑;
}
公共无效集合x(整数x){
这个.x=x;
}
公共空间设置(整数y){
这个。y=y;
}
}
公共类Circle扩展JFrame实现ActionListener、KeyListener{
私人定时器;
私有整数x,y,a=5,b=5;
私有随机兰德;
c circ=新的c();
公众圈(){
setLayout(新的BorderLayout());
x=circ.getX();
y=circ.getY();
定时器=新定时器(50,此);
timer.start();
addKeyListener(此);
设置大小(550550);
setVisible(真);
}
公共空间涂料(图g){
超级油漆(g);
g、 椭圆形(x,y,100100);
g、 setColor(circ.getCo());
}
公共静态void main(字符串[]args){
新圆圈();
}
@凌驾
已执行的公共无效操作(操作事件e){
moveWithTimer();
重新油漆();
}
公共void moveWithTimer(){
x=x+b;
y=y+a;
如果(x500){
b=-5;
}
如果(y500){
a=-5;
}
}
@凌驾
按下公共无效键(按键事件e){
//TODO自动生成的方法存根
if(e.getKeyCode()==e.VK_空间){
约setCo(兰特·耐克斯汀(255)、兰特·耐克斯汀(255)、兰特·耐克斯汀(255));
}
}
@凌驾
公共无效密钥已释放(密钥事件e){
//TODO自动生成的方法存根
}
@凌驾
public void keyTyped(KeyEvent e){
//TODO自动生成的方法存根
}
}

我建议您在绘制圆之前,应在paint(g)中设置图形对象的颜色

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

通常,不应重写JFrame的paint()方法。相反,创建一个JPanel,将其添加到框架中,并覆盖面板的paintComponent()方法。

我建议您在绘制圆之前,应在paint(g)中设置图形对象的颜色

public void paint(Graphics g) {
    super.paint(g);
    g.setColor(circ.getCo());
    g.fillOval(x,y,100,100);
}
通常,不应重写JFrame的paint()方法。相反,创建一个JPanel,将其添加到框架中,并覆盖面板的paintComponent()方法

但当我按下它时,它不起作用。它和它原来的颜色很相配。那么,我怎样才能使这段代码正确呢

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

    }

}
KeyListener
变化无常,最好使用,它克服了
KeyListener

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

相反,从一个
JPanel
开始,覆盖它的
paintComponent
方法。它通常更灵活。请查看以了解更多详细信息

你的移动代码是错误的。将circle类的
x
/
y
值分配给其他一些变量,这里的问题是,更改这些变量的值不会影响circle类中的变量,相反,您需要重新分配它们

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);

}
如果是我,我也会尝试添加一个
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.awt.Color;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.KeyEvent;
导入java.util.Random;
导入javax.swing.AbstractAction;
导入javax.swing.ActionMap;
导入javax.swing.InputMap;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.KeyStroke;
导入javax.swing.Timer;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
公开课考试{
公共静态void main(字符串[]args){
新测试();
}
公开考试(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
例如printStackTrace();
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(newtestpane());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类TestPane扩展了JPanel{
私人定时器;
私有整数a=5,b=5;
私有随机兰德;
私人圈圈=新圈();
公共测试窗格(){
定时器=新定时器(50,新动作列表