简体   繁体   中英

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!)

Firstly, all class names should begin with a capital letter as a convention, this does not affect compilation but is good practice.

Now, for your actual problem, the first thing that stands out to me is that your Button Class does not extend anything. This to me seems to be the reason why it does not appear on the screen. I would suggest making Button extend JButton :

public class Button extends JButton {
// Implementation Code
}

This is similar to how your MenuPanel extends JPanel . The JPanel cannot render a custom Button that you wrote. By extending JButton it will be able to render it as it knows how to interact with a JButton

I think you can better let your Button class extend JButton. In that way you can just add your own button class to the menupanel.

public class Button extends JButton
{


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



}

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

The difference is that you are no longer adding JButtons to the JPanel.

For this code to work, your "button" class must extend JPanel.

Another way to extract the shared code would be to create a "Button creator method" instead of a class, something like:

public class MenuPanel extends JPanel implements ActionListener
{
    int y = 95, width = 200, height = 50;
    private JButton playKnop, highScoreKnop, quitKnop, HTPKnop;

    public MenuPanel()
    {
        this.setLayout(null);

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

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

        validate();
    }

    private JButton createButton(String path, int x) {
        ImageIcon icon = new ImageIcon(MenuPanel.class.getResource(path));
        JButton button = new JButton(icon);
        button.setBounds(x, y, width, height);
        button.addActionListener(this);
        return button;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
    }
}

In the existing MenuPanel , when you do

this.add(playKnop);

you are adding a JButton to your JPanel

In the new MenuPanel you are adding a button to your JPanel .

You need to add a JButton to a JPanel .

Also choose Button rather than button for class names.

The solution is to rewrite this code so that you are adding JButton s rather than button s to your panel. There may be other issues with the code too.

There is a difference in what you are adding . In the new code you are adding instances of your button class to the JPanel. In the old code you added JButtons . buttons can't be displayed as they're not swing classes, the old JButtons could.

Extending button from JButton should do the trick:

public class button extends JButton {

// public JButton button; // this line is depreceted now

public ImageIcon buttonImage;

...

Also, learn about code formatting and style in Java . This will help you write clearer code and prevent confusions as above. Eg you have a class named button with a field named button and a method named button . Use different names as Button (classes are always upper case!), button and createButton .

Try adding a getButton in the class button to return the button for adding

public JButton getJButton(){
 retun this.button
}

then add use this on adding on the menu panel

this.add(playKnop.getJButton());

There is nothing wrong with your code. The only problem that I can see is that your Class button extend Object instead of JButton . So just do the following change and I feel it should work:

Instead of :

public class button 

write

public class button extends JButton

Perhaps you want to make your button class inherit JButton instead of keeping a button field. That way, you could add the button to the panel.

I am not very familiar with the JButton class. You need to set the buttonImage as background. Maybe there is some function like:

this.setBackground(buttonImage);

If there is no function liek this, you can set the background in the Constructor. Similar to your examples above. You always created a new Button with:

JButton b = new JButton(buttonImage);

You can give the same parameters to the super()-methode in your own Constructor. The result will look liek this:

public class Button extends JButton
{
   String backgroundPath;
   int y;

   public Button(String backgroundPath, int y, MenuPanel menuPanel)
   {
       super(new ImageIcon(PlayPanel.class.getResource(backgroundPath)));
       this.backgroundPath = backgroundPath;
       this.y = y;

       this.setBounds(x, y, width, height);
       this.addActionListener(menuPanel); 
   }
}

This code is not tested.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM