2017-11-09 5 views
0

私は円がランダムなxとyの値と選択された色で表示されるプロジェクトを持っていますが、ユーザーがスペースバーを押したときに円の色を変更する必要があります。私の円はx座標とy座標の両方を動かし、スペースボタンを押すと円の色を変えたいと思います。しかし、私はそれを押すと動作しません。元の色となります。どうすればこのコードを正しく作成できますか?私はあなたがグラフィックスの色を設定する必要が示唆KeyListenerで色を変更する

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 

    } 

} 

答えて

2

しかし、押しても機能しません。元の色となります。どうすればこのコードを正しく作成できますか?

KeyListenerは、親指の一般的なルールとしてKeyListener

の問題に関連する焦点を当て、主を克服Key Bindings APIを使用して、気まぐれ優れている、あなたは、JFrameのようなトップレベルのコンテナのpaintをオーバーライドするべきではありませんそれらは複合コンポーネントであり、単なる真面目なものです。

代わりに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); 

} 

「サークル」クラスでは、さらに2つの方法を使用できます。 1つは色をランダム化する(すでにRandomオブジェクトを持っていますが、それを使用することもできます)、もう1つはオブジェクトをペイントすることです。実行可能な例として)

...

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

    } 

} 
;

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メソッドを追加するために誘惑されると思いますが、それは私です

2

はが円を描く前に、塗料(G)内のオブジェクト。

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

一般的には、あなたがたJFrameのpaint()メソッドをオーバーライドするべきではありません。その代わりに、JPanelを作成してフレームに追加し、パネルのpaintComponent()メソッドをオーバーライドします。