Question

Alright, so my first class creates the Frame and also places a red rectangle in it which I can move. Now what i'm doing is, creating another class for a blue rectangle. Now in my attempt i have created the second class and also extended the first class unto it; which doesn't seem to do the job.

Summery: What do I need to do so they share the same frame? Is there a method for this?

SOLVED VERSION My Code(First Class): EDITED

        import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;



public class MyGame extends JPanel implements ActionListener, KeyListener {
    Timer t = new Timer(5, this);
    int x = 0, y = 0, velx =0, vely =0, g = 0;
    private Color color;

    public MyGame() {
        t.start();
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(400, 400);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(color);
        g.fillRect(x, y, 50, 30);
    }


    @Override
    public void actionPerformed(ActionEvent e) {
        if (x < 0) //stops us from going backwards past x = 0
        {
            velx = 0;
            x = 0;
        }

        if (y < 0) //stops us from going to the sky
        {
            vely = 0;
            y = 0;
        }

        if (y > 330) // stops us from going through the ground
        {
            vely = 0;
            y = 330;
        }

        x += velx;
        y += vely;
        repaint();
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int code = e.getKeyCode();

        {
            if (code == KeyEvent.VK_DOWN) {
                vely = 1; // removing velx = 0 allows us to go vertically and horizontlly at the same time

            }
            if (code == KeyEvent.VK_UP) {
                vely = -1; // same goes for here

            }
            if (code == KeyEvent.VK_LEFT) {

                velx = -1;
            }

            {
                if (code == KeyEvent.VK_RIGHT) {

                    velx = 1;

                }
            }
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
        velx = 0;
        vely = 0;
    }




    public static void main (String arge[]){

        JFrame frame = new JFrame("Testing");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        frame.add(new Incoming());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

    }
}

(Second Class): EDITED

            import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;



public class Incoming extends MyGame {

private Color color;

int x = 0, y = 0, velx = 0, vely = 0;

public Incoming() {
    color = Color.BLUE;
}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(color);
    g.fillRect(x, y, 50, 30);
}

@Override
public void actionPerformed(ActionEvent e) {
    super.actionPerformed(e);
    if (x < 0) //stops us from going backwards past x = 0
    {
        velx = 0;
        x = 0;
    }

    if (y < 0) //stops us from going to the sky
    {
        vely = 0;
        y = 0;
    }

    if (y > 330) // stops us from going through the ground
    {
        vely = 0;
        y = 330;
    }

    x += velx;
    y += vely;
    repaint();
}

@Override
public void keyPressed(KeyEvent e) {
    super.keyPressed(e);
    int code = e.getKeyCode();

    {
        if (code == KeyEvent.VK_S) {
            vely = 1; // removing velx = 0 allows us to go vertically and horizontlly at the same time

        }
        if (code == KeyEvent.VK_NUMPAD8) {
            vely = -1; // same goes for here

        }
        if (code == KeyEvent.VK_NUMPAD4) {
            vely = 0;
            velx = -1;
        }

        {
            if (code == KeyEvent.VK_NUMPAD6) {
                vely = 0;
                velx = 1;

            }
        }
    }
}

@Override
public void keyReleased(KeyEvent e) {
    super.keyReleased(e);
    velx = 0;
    vely = 0;
}
}

Thank you

Was it helpful?

Solution

You could either take advantage of the color property support of the component or supply your own color property which could set and retrieved through the use of setters and getters

The following example simply uses the components existing foreground property...

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
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 GameExample {

    public static void main(String[] args) {
        new GameExample();
    }

    public GameExample() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                MyGame game = new MyGame();

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(game);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class MyGame extends JPanel implements ActionListener {

        Timer t = new Timer(5, this);
        int x = 0, y = 0, velx = 0, vely = 0, g = 0;

        public MyGame() {
            t.start();
            setFocusTraversalKeysEnabled(false);
            setForeground(Color.RED);

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "up-pressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "down-pressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, false), "left-pressed");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, false), "right-pressed");

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), "up-released");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "down-released");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), "left-released");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), "right-released");

            ActionMap am = getActionMap();
            am.put("up-pressed", new YDelatAction(-1));
            am.put("down-pressed", new YDelatAction(1));
            am.put("left-pressed", new XDelatAction(-1));
            am.put("right-pressed", new XDelatAction(1));

            am.put("up-released", new YDelatAction(0));
            am.put("down-released", new YDelatAction(0));
            am.put("left-released", new XDelatAction(0));
            am.put("right-released", new XDelatAction(0));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(getForeground());
            g.fillRect(x, y, 50, 30);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if (x < 0) //stops us from going backwards past x = 0
            {
                velx = 0;
                x = 0;
            }

            if (y < 0) //stops us from going to the sky
            {
                vely = 0;
                y = 0;
            }

            if (y > 330) // stops us from going through the ground
            {
                vely = 0;
                y = 330;
            }

            x += velx;
            y += vely;
            repaint();
        }

        public class XDelatAction extends AbstractAction {

            private int value;

            public XDelatAction(int value) {
                this.value = value;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                vely = 0;
                velx = value;
            }

        }

        public class YDelatAction extends AbstractAction {

            private int value;

            public YDelatAction(int value) {
                this.value = value;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                vely = value;
            }

        }

    }

}

This would allow you to create a new instance that use a different color by doing...

MyGame game = new MyGame();
game.setForeground(Color.BLUE);

Or you could create a new subclass using something like...

public class MyBlueGame extends MyGame {

    public MyBlueGame () {
        setForeground(Color.BLUE);
    }

}

Generally speaking, you should favour the key bindings API over KeyListener as it provides more control over the level of focus required to generate key events and generally produces more re-usable and configurable code (IMHO)

Updated

So, based on you example code...

Each class is going to need it's own color property, which independent of the other, otherwise the inheritance is going to get in the way (and the parent will want to use the value of the child)

You will also need to change the keyPressed and keyReleased methods for the child class so that the two rectangles can move independently of each other.

This is not my preferred solution. I would have a single game surface which was capable of rendering the state of the overall game (all the entities) and would provide a means by which the gaming elements could be added (and possibly removed) from the surface and some kind of controller that would be able to control the way in which those elements are updated...but that's just me...

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class GameTest {

    public static void main(String[] args) {
        new GameTest();
    }

    public GameTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new Incoming());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class MyGame extends JPanel implements ActionListener, KeyListener {

        Timer t = new Timer(5, this);
        int x = 0, y = 0, velx = 0, vely = 0, g = 0;

        private Color color;

        public MyGame() {
            color = Color.RED;
            t.start();
            addKeyListener(this);
            setFocusable(true);
            setFocusTraversalKeysEnabled(false);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(color);
            g.fillRect(x, y, 50, 30);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if (x < 0) //stops us from going backwards past x = 0
            {
                velx = 0;
                x = 0;
            }

            if (y < 0) //stops us from going to the sky
            {
                vely = 0;
                y = 0;
            }

            if (y > 330) // stops us from going through the ground
            {
                vely = 0;
                y = 330;
            }

            x += velx;
            y += vely;
            repaint();
        }

        @Override
        public void keyPressed(KeyEvent e) {
            int code = e.getKeyCode();

            {
                if (code == KeyEvent.VK_DOWN) {
                    vely = 1; // removing velx = 0 allows us to go vertically and horizontlly at the same time

                }
                if (code == KeyEvent.VK_UP) {
                    vely = -1; // same goes for here

                }
                if (code == KeyEvent.VK_LEFT) {

                    velx = -1;
                }

                {
                    if (code == KeyEvent.VK_RIGHT) {

                        velx = 1;

                    }
                }
            }
        }

        @Override
        public void keyTyped(KeyEvent e) {
        }

        @Override
        public void keyReleased(KeyEvent e) {
            velx = 0;
            vely = 0;
        }

    }

    public class Incoming extends MyGame {

        private Color color;

        int x = 0, y = 0, velx = 0, vely = 0;

        public Incoming() {
            color = Color.BLUE;
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(color);
            g.fillRect(x, y, 50, 30);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            super.actionPerformed(e);
            if (x < 0) //stops us from going backwards past x = 0
            {
                velx = 0;
                x = 0;
            }

            if (y < 0) //stops us from going to the sky
            {
                vely = 0;
                y = 0;
            }

            if (y > 330) // stops us from going through the ground
            {
                vely = 0;
                y = 330;
            }

            x += velx;
            y += vely;
            repaint();
        }

        @Override
        public void keyPressed(KeyEvent e) {
            super.keyPressed(e);
            int code = e.getKeyCode();

            {
                if (code == KeyEvent.VK_NUMPAD2) {
                    vely = 1; // removing velx = 0 allows us to go vertically and horizontlly at the same time

                }
                if (code == KeyEvent.VK_NUMPAD8) {
                    vely = -1; // same goes for here

                }
                if (code == KeyEvent.VK_NUMPAD4) {
                    vely = 0;
                    velx = -1;
                }

                {
                    if (code == KeyEvent.VK_NUMPAD6) {
                        vely = 0;
                        velx = 1;

                    }
                }
            }
        }

        @Override
        public void keyReleased(KeyEvent e) {
            super.keyReleased(e);
            velx = 0;
            vely = 0;
        }
    }

}

OTHER TIPS

i think all what you have to do is to set the colour as a parameter for your class MyGame , to add a field colour to your class.

private Color colour;

public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Colour);
        g.fillRect(x,y,70,40);
}


            JFrame f = new JFrame();
            MyGame s = new MyGame();
             s.setCoulor(Color.RED)   //  s.setCoulor(Color.BLUE)
            f.add(s);
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setSize(600,400);
            f.setVisible(true);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top