如何在另一个 class 中使用代码? (Java)

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

我正在制作一款坦克游戏,为了避免冗余,我正在制作 classes 进行扩展。 我的 MenuPanel 看起来像这个 atm (我只写了对问题重要的代码) (knop = 按钮的荷兰语)

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

因为制作按钮的代码完全相同(除了 backgroundPath 和 y 坐标)我制作了一个 class 按钮:

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



}

那样的话,我的菜单面板可能看起来像这样:

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

    }


}

我不知道为什么,但是当我这样做时,按钮不会出现,尽管按钮 class 中的代码是正确的(公元前,当我在 menuPanel 本身中使用代码时,它可以工作)

我不知道如何解决这个问题,我的整个 JavaProject 中有多个这样的问题,但如果有人能向我解释如何解决这个问题,我就可以摆脱项目中的所有冗余。

提前致谢, 萝拉

非常感谢大家!你的答案组合帮助我让按钮出现,但由于某种原因,图像没有加载它们。我的代码现在看起来像:

public class MenuPanel 扩展 JPanel 实现 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); 
    }
}

}

(所有按钮都有效!)

你能观察到线之间的区别吗:

playKnop.addActionListener(this);

和后面代码中的那个:

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

我相信您想添加 MenuPanel 作为动作侦听器,但您没有在以后的代码中传递对它的引用。你应该有: playKnop = new button("/buttons/PLAY.png", 350, this);

然后在您的 Button class 中设置此引用,例如:

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

在现有的MenuPanel中,当你做

this.add(playKnop);

您正在向 JPanel

添加 JButton

在新的 MenuPanel 中,您将 button 添加到 JPanel

您需要将 JButton 添加到 JPanel

同时为 class 个名称选择 Button 而不是 button

解决方案是重写此代码,以便您向面板添加 JButton 而不是 button。代码也可能存在其他问题。

首先,所有 class 名称都应以大写字母开头作为约定,这不影响编译,但是是一种很好的做法。

现在,对于您的实际问题,对我来说突出的第一件事是您的 Button Class 没有扩展任何内容。这对我来说似乎是它没有出现在屏幕上的原因。 我建议让 Button 扩展 JButton:

public class Button extends JButton {
// Implementation Code
}

这类似于您的 MenuPanel 扩展 JPanel 的方式。 JPanel 无法呈现您编写的自定义 Button。通过扩展 JButton 它将能够呈现它,因为它知道如何与 JButton

交互

您添加的内容存在差异。在新代码中,您将 button class 的实例添加到 JPanel。在旧代码中,您添加了 JButtonsbuttons 无法显示,因为它们不是摇摆 classes,旧的 JButton 可以。

从 JButton 扩展按钮应该可以解决问题:

public class button extends JButton {

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

public ImageIcon buttonImage;

...

此外,在 Java 中了解代码格式和样式。这将帮助您编写更清晰的代码并防止上述混淆。例如。您有一个名为 button 的 class,其中包含一个名为 button 的字段和一个名为 button 的方法。使用不同的名称,如 Button(class 总是大写!)、buttoncreateButton.

尝试在 class 按钮中添加一个 getButton 到 return 添加按钮

public JButton getJButton(){
 retun this.button
}

然后在菜单面板上添加使用这个

this.add(playKnop.getJButton());

您的代码没有任何问题。我能看到的唯一问题是您的 Class button 扩展了 Object 而不是 JButton。所以只需进行以下更改,我觉得它应该有效:

而不是:

public class button 

public class button extends JButton

也许您想使按钮 class 继承 JButton 而不是保留按钮字段。这样,您就可以将按钮添加到面板中了。

区别在于您不再将 JButton 添加到 JPanel。

要使此代码正常工作,您的 "button" class 必须扩展 JPanel。

提取共享代码的另一种方法是创建 "Button creator method" 而不是 class,类似于:

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

我认为您最好让 Button class 扩展 JButton。这样,您只需将自己的按钮 class 添加到菜单面板即可。

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



}

我对 JButton 不是很熟悉class。您需要将 buttonImage 设置为背景。也许有一些功能,如:

this.setBackground(buttonImage);

如果没有这个功能,可以在Constructor中设置背景。类似于您上面的示例。您总是创建一个新的按钮:

JButton b = new JButton(buttonImage);

您可以在自己的构造函数中为 super() 方法提供相同的参数。结果看起来像这样:

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

此代码未经测试。