Search code examples
javaredundancyextending

How to use code from one class in another? (Java)


I'm making a tank game and to avoid redundancy I'm making classes to extend. My MenuPanel looks like this atm (I've only written the code that matters for the question) (knop = dutch for button)

public class MenuPanel extends JPanel implements ActionListener
{

    private JButton playKnop, highScoreKnop, quitKnop, HTPKnop;
    private ImageIcon play, HS, quit, HTP;
    private Tanks mainVenster;

    public MenuPanel(Tanks mainVenster) 
    {
        this.mainVenster = mainVenster;
        this.setLayout(null); 

        int x = 95; 
        int width = 200; 
        int height = 50;    


        play = new ImageIcon(PlayPanel.class.getResource(/buttons/PLAY.png));
        playKnop = new JButton(play);
        playKnop.setBounds(x, y, width, height);
        playKnop.addActionListener(this);

        HS = new ImageIcon(PlayPanel.class.getResource(/buttons/HS.png));
        highScoreKnop = new JButton(HS);
        highScoreKnop.setBounds(x, 460, width, height);
        highScoreKnop.addActionListener(this);

        HTP = new ImageIcon(PlayPanel.class.getResource(/buttons/HTP.png));
        HTPKnop = new JButton(HTP);
        HTPKnop.setBounds(x, 515, width, height);
        HTPKnop.addActionListener(this);

        quit = new ImageIcon(PlayPanel.class.getResource(/buttons/QUIT.png));
        quitKnop = new JButton(quit);
        quitKnop.setBounds(x, 570, width, height);
        quitKnop.addActionListener(this);

        this.add(playKnop);
        this.add(quitKnop);
        this.add(HTPKnop);
        this.add(highScoreKnop);

        validate();
    }
}

because the code to make the buttons is exactly the same (except for the backgroundPath and the y-coordinate) I made a class button:

package menu;

import java.awt.Image;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;

public class button 
{


    public JButton button;
    public ImageIcon buttonImage;

    public int x = 95;
    public int width = 200;
    public int height = 50;

    public String backgroundPath;
    public int y;



    public button(String backgroundPath, int y)
    {
        this.backgroundPath = backgroundPath;
        this.y = y;

        buttonImage = new ImageIcon(PlayPanel.class.getResource(backgroundPath));
        button = new JButton();
        button.setBounds(x, y, width, height);;
        button.addActionListener(this); 
    }



}

that way, my menuPanel COULD look like this:

    package menu;

    @SuppressWarnings("serial")
    public class MenuPanel extends JPanel implements ActionListener
    {

    private button playKnop, highScoreKnop, quitKnop, HTPKnop;
    private JTextField naam;
    private Tanks mainVenster;



    public MenuPanel(Tanks mainVenster) 
    {
        this.mainVenster = mainVenster;
        this.setLayout(null);       

        playKnop = new button("/buttons/PLAY.png", 350);        
        highScoreKnop = new button("/buttons/HS.png", 460);
        quitKnop = new button("/buttons/QUIT.png", 515);
        HTPKnop = new button("/buttons/HTP.png", 570);


        this.add(playKnop);
        this.add(quitKnop);
        this.add(HTPKnop);
        this.add(highScoreKnop);


        validate();

    }


}

I don't know why, but when I do this the buttons won't appear, although the code from the button class is correct (bc when I use the code in the menuPanel itself it works)

I don't know how to fix this problem and I have multiple problems like this in my whole JavaProject, but if someone could explain me how to fix this I could get rid of all the redundancy in my project.

Thanks in advance, Lola

Thank you all so much! a combination of your answers helped me to let the buttons appear, but for some kind of reason the images don't load with them. my code now looks like:

public class MenuPanel extends JPanel implements ActionListener {

private Button playKnop, highScoreKnop, quitKnop, HTPKnop;

private Tanks mainVenster;

int x = 95, width = 200, height = 50;

public MenuPanel(Tanks mainVenster) 
{
    this.mainVenster = mainVenster;
    this.setLayout(null);

    playKnop = new Button("/buttons/PLAY.png", 350, this);      
    highScoreKnop = new Button("/buttons/HS.png", 460, this);
    quitKnop = new Button("/buttons/QUIT.png", 515, this);
    HTPKnop = new Button("/buttons/HTP.png", 570, this);

    this.add(playKnop);
    this.add(quitKnop);
    this.add(HTPKnop);
    this.add(highScoreKnop);

    validate();

}

public class Button extends JButton
{
    JButton button;
    ImageIcon buttonImage;

    String backgroundPath;
    int y;


    public Button(String backgroundPath, int y, MenuPanel menuPanel)
    {
        super();
        this.backgroundPath = backgroundPath;
        this.y = y;

        buttonImage = new ImageIcon(PlayPanel.class.getResource(backgroundPath));
        this.setBounds(x, y, width, height);;
        this.addActionListener(menuPanel); 
    }
}

}

(all the buttons do work!)


Solution

  • Can you observe the difference between the line:

    playKnop.addActionListener(this);
    

    and the one in later code:

    playKnop = new button("/buttons/PLAY.png", 350);  
    

    I believe you want to add MenuPanel as action listener but you are not passing the reference to it in later code. You should rather have: playKnop = new button("/buttons/PLAY.png", 350, this);

    And then set this reference in your Button class like:

    public button(String backgroundPath, int y, MenuPanel menuPanel)
        {
            this.backgroundPath = backgroundPath;
            this.y = y;
    
            buttonImage = new ImageIcon(PlayPanel.class.getResource(backgroundPath));
            button = new JButton();
            button.setBounds(x, y, width, height);;
            button.addActionListener(menuPanel); 
        }