2012-03-15 25 views
1

我正试图用keyEvent移动一个圆圈。到目前为止,圆形画在窗口上,但它不会左移!我觉得问题是我将Window()构造函数添加到容器的位置。控制台上没有输出来告诉我它正在工作。所以我不认为它甚至达到了KeyEvent类。这里是我的代码:Java在gui中用箭头键移动圆圈

import java.awt.*; 
import java.awt.event.*; 
import java.awt.geom.Ellipse2D; 
import javax.swing.*; 


public class Window extends JPanel { 

    private static Ellipse2D.Double circle; 

    public Window() { 
     super(); 
     int width = 400; 
     int height = 400; 
     circle = new Ellipse2D.Double(0.5 * width, 0.9 * height, 
       0.1 * width, 0.05 * height); 
     addKeyListener(new MoveCircle()); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponents(g); 
     Graphics2D brush = (Graphics2D) g; 
     int width = getWidth(); 
     int height = getHeight(); 
     g.clearRect(0, 0, width, height); 
     brush.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
       RenderingHints.VALUE_ANTIALIAS_ON); 
     brush.draw(circle); 
    } 

    public class MoveCircle implements KeyListener { 

     @Override 
     public void keyPressed(KeyEvent e) { 
      System.out.println("Working on top!"); 
      if (e.getKeyCode() == KeyEvent.VK_LEFT) { 
       System.out.println("Working on bottom!"); 
       circle.x++; 
       repaint(); 
      } 
     } 

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

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

    public static void main(String[] args) { 
     Window window = new Window(); 
     JFrame frame = new JFrame(); 
     Container container = frame.getContentPane(); 
     container.add(new Window()); 
     frame.addKeyEvent(window.new MoveCircle()); 
     frame.setSize(800, 700); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.setVisible(true); 
    } 
} 

回答

4

实际上正在发生的事情是这样,要添加WindowJFrame,但重点在于与JFrame,所以当你在你的Keyboard那东西键入转到JFrame不是KeyListener连接到Window类。所以为了克服它,你只需在Window类的对象上调用requestFocusInWindow()即可。试试这个代码,我已经做了一些关于EDT和东西的修改。

import java.awt.*; 
import java.awt.event.*; 
import java.awt.geom.Ellipse2D; 
import javax.swing.*; 


public class Window extends JPanel { 

    private static Ellipse2D.Double circle; 
    private JFrame frame; 

    public Window() { 
     super(); 
     int width = 400; 
     int height = 400; 
     circle = new Ellipse2D.Double(0.5 * width, 0.9 * height, 
       0.1 * width, 0.05 * height);   
    } 

    public Dimension getPreferredSize() 
    { 
     return (new Dimension(frame.getWidth(), frame.getHeight())); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponents(g); 
     Graphics2D brush = (Graphics2D) g; 
     int width = getWidth(); 
     int height = getHeight(); 
     g.clearRect(0, 0, width, height); 
     brush.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
       RenderingHints.VALUE_ANTIALIAS_ON); 
     brush.draw(circle); 
    } 

    public class MoveCircle implements KeyListener { 

     @Override 
     public void keyPressed(KeyEvent e) { 
      System.out.println("Working on top!"); 
      if (e.getKeyCode() == Event.ENTER) { 
       System.out.println("Working on bottom!"); 
       double newX = circle.x - 1; 
       circle.x = newX; 
       repaint(); 
      } 
     } 

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

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

    private void createAndDisplayGUI(Window window) 
    { 
     frame = new JFrame(); 
     Container container = frame.getContentPane();  
     container.add(window); 
     window.addKeyListener(new MoveCircle());   
     frame.setSize(800, 700); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.setVisible(true); 
     window.requestFocusInWindow(); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       Window window = new Window(); 
       window.createAndDisplayGUI(window); 
      } 
     }); 
    } 
} 
+0

我修改了它现在可以正常工作,现在圆圈左右移动。不过,我正在尝试像newX = circle.x + 5.0;这是无所事事,让圆移动的唯一方法是circle.x ++;我不喜欢它移动的速度有多慢......? – user1198199 2012-03-15 20:50:32

+0

你试过用'circle.x + = 5;'而不是'newX = circle.x + 5.0;'? – 2012-03-15 20:54:50

+0

啊,是的,谢谢你。我不知道为什么它不接受新的任务。那么你已经保存了一天,现在我将继续我的比赛。谢谢你,先生! – user1198199 2012-03-15 20:57:24

1

只有焦点组件会得到关键事件。你需要在某个时候调用requestFocus()。

1

解决方案是,将KeyListener添加到JFrame。通过这种方式,当JFrame拥有焦点时,所有关键笔画都将引发一个事件。

+0

you mean frame.addKeyListeners(new MoveCircle());在主要方法? – user1198199 2012-03-15 20:25:54

+0

是的,这就是我的意思,但这可能无法正常工作,因为MoveCircle()只能从Window调用。所以我的解决方案是:'窗口窗口=新窗口(); container.add(window); frame.addKeyListener(window.new MoveCircle());' – Boman 2012-03-15 20:29:49

+0

keyListener已添加,但现在圆不移动。嗯... – user1198199 2012-03-15 20:35:59