Search code examples
javaswingpaintkey-bindings

Problems with controlling the movement of a shape in Java swing window


I'm trying to make a program where you move a circle around in a java swing window using the arrow keys. keybindings is working fine, but there is always a problem with displaying the circle. Here's the code:

public class ShapesMove extends JFrame{

    public static int x = 40;
    public static int y = 40;

    public static void main(String[] args){

        final JFrame frame = new JFrame("Movement of 2d Shapes");
        frame.setSize(400,400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel content = (JPanel) frame.getContentPane();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        Action actionRight = new AbstractAction(){
            public void actionPerformed(ActionEvent actionRightEvent){
                x++;
            }
        };

        Action actionLeft = new AbstractAction(){
            public void actionPerformed(ActionEvent actionLeftEvent){
                x--;
            }
        };

        Action actionUp = new AbstractAction(){
            public void actionPerformed(ActionEvent actionUpEvent){
                y++;
            }
        };

        Action actionDown = new AbstractAction(){
            public void actionPerformed(ActionEvent actionDownEvent){
                y--;
            }
        };

        KeyStroke right = KeyStroke.getKeyStroke("RIGHT");
        KeyStroke left = KeyStroke.getKeyStroke("LEFT");
        KeyStroke up = KeyStroke.getKeyStroke("UP");
        KeyStroke down = KeyStroke.getKeyStroke("DOWN");

        InputMap inputMap = content.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        inputMap.put(right, "RIGHT");
        inputMap.put(left, "LEFT");
        inputMap.put(up, "UP");
        inputMap.put(down, "DOWN");
        content.getActionMap().put("RIGHT", actionRight);
        content.getActionMap().put("LEFT", actionLeft);
        content.getActionMap().put("UP", actionUp);
        content.getActionMap().put("DOWN", actionDown);

    }
    public void draw(Graphics g){
        g.drawOval(x, y, 60, 60);
    }
}

I did not include the import lines because I know I have all the right modules. Compiling always goes just fine, but the circle doesn't display when I run it. I tried the same code for the display in it's own separate fie and the circle showed up when I ran that, so what am I doing wrong here?


Solution

  • Changed your code, it works fine. Override paintComponent method and call your draw method inside it. And change JFrame to JPanel.

        public class ShapesMove extends JPanel{
    
        public static int x = 40;
        public static int y = 40;
    
        public static void main(String[] args){
    
            final JFrame frame = new JFrame("Movement of 2d Shapes");
            frame.setSize(400,400);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            final ShapesMove m = new ShapesMove();
            frame.getContentPane().add(m);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
    
            Action actionRight = new AbstractAction(){
                public void actionPerformed(ActionEvent actionRightEvent){
                    x++;
                    m.repaint();
                }
            };
    
            Action actionLeft = new AbstractAction(){
                public void actionPerformed(ActionEvent actionLeftEvent){
                    x--;
                    m.repaint();
                }
            };
    
            Action actionUp = new AbstractAction(){
                public void actionPerformed(ActionEvent actionUpEvent){
                    y++;
                    m.repaint();
                }
            };
    
            Action actionDown = new AbstractAction(){
                public void actionPerformed(ActionEvent actionDownEvent){
                    y--;
                    m.repaint();
                }
            };
    
            KeyStroke right = KeyStroke.getKeyStroke("RIGHT");
            KeyStroke left = KeyStroke.getKeyStroke("LEFT");
            KeyStroke up = KeyStroke.getKeyStroke("UP");
            KeyStroke down = KeyStroke.getKeyStroke("DOWN");
    
            InputMap inputMap = m.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
            inputMap.put(right, "RIGHT");
            inputMap.put(left, "LEFT");
            inputMap.put(up, "UP");
            inputMap.put(down, "DOWN");
            m.getActionMap().put("RIGHT", actionRight);
            m.getActionMap().put("LEFT", actionLeft);
            m.getActionMap().put("UP", actionUp);
            m.getActionMap().put("DOWN", actionDown);
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawOval(x, y, 60, 60);
        }
    
      }