【问题标题】:Java moving a circle in a gui with arrow keysJava用箭头键在gui中移动一个圆圈
【发布时间】:2012-03-16 04:48:29
【问题描述】:

我正在尝试使用 keyEvent 向左移动一个圆圈。到目前为止,圆圈已在窗口上绘制,但并没有向左移动!我觉得问题在于我将 Window() 构造函数添加到容器的位置。控制台上没有输出告诉我它正在工作。所以我认为它甚至没有达到 KeyEvent 类。这是我的代码:

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

【问题讨论】:

    标签: java swing user-interface graphics2d keyevent


    【解决方案1】:

    实际上发生的事情是这样的,您将Window 添加到JFrame,但重点在于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);
                }
            });
        }
    }
    

    【讨论】:

    • 我修改它现在可以正常工作,圆圈现在左右移动。但是我正在尝试做类似 newX = circle.x + 5.0;这是什么都不做,让圆圈移动的唯一方法是 circle.x++;我不喜欢它的移动速度……?
    • 你试过用circle.x += 5;代替newX = circle.x + 5.0;吗?
    • 啊,是的,谢谢。我不知道它为什么不接受新的任务。好吧,你已经拯救了这一天,现在我将继续我的比赛。谢谢楼主!
    • 呵呵,欢迎您并保持微笑 :-),答案是当您编写 circle.x += 5; 时,您正在递增 circle 对象的变量 x,否则您必须编写 @ 987654337@ 让那个东西工作:-)
    • 好例子;另请参阅LinePanel,它使用键绑定来避免该问题。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      解决方案是将 KeyListener 添加到 JFrame。这样,当 JFrame 获得焦点时,所有的击键都会引发一个事件。

      【讨论】:

      • 你的意思是 frame.addKeyListeners(new MoveCircle());在 main 方法中?
      • 是的,这就是我的意思,但这可能行不通,因为 MoveCircle() 只能从 Window 调用。所以我的解决方案是:Window window = new Window(); container.add(window); frame.addKeyListener(window.new MoveCircle());
      • 并且是 System.out.prints(...);执行?还是在 JFrame 上按 Enter 时控制台为空?
      猜你喜欢
      • 1970-01-01
      • 2013-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-29
      • 2015-12-10
      相关资源
      最近更新 更多